I'm using OpenCV 3.2.
Let's suppose I have a 3 x 1 Mat:
cv::Mat foo = (cv::Mat_<float>(3,1) << 0, 1, 2);
Now I want to concatenate a single value to foo, and then having a resulting 4 x 1 Mat.
A simple solution would be:
cv::Mat bar = (cv::Mat_<float>(4,1) << foo.at<float>(0,0),
foo.at<float>(1,0),
foo.at<float>(2,0),
3);
But this solution overfits to the problem dimensions. Of course, I can generalize it by looping all the values of an n x 1 Mat, resulting in an n+1 x 1.
What I'm looking for is a smarter solution that takes advantage of OpenCV syntax, and directly returns the concatenation of a single-column Mat and a single value.
You're in luck. cv::Mat provides member function push_back which
adds elements to the bottom of the matrix
Furthermore,
The methods add one or more elements to the bottom of the matrix. They emulate the corresponding method of the STL vector class. ...
Since your Mat has a single column, you can just simply add scalar values, you just have to make sure the type matches the data type of the Mat. In you case you can add floats directly, but anything else you need to cast to float explicitly before adding.
If you had a Mat with a single row, and wanted to add a column, it would be a little more complicated. You're need to use reshape before and after the push_back. However, to quote the documentation
No data is copied. That is, this is an O(1) operation.
If you need to do this often, then it's trivial to wrap it in an inline function.
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
// Adding rows
cv::Mat foo = (cv::Mat_<float>(3, 1) << 0, 1, 2);
std::cout << foo << "\n";
foo.push_back(3.0f);
std::cout << foo << "\n";
foo.push_back(static_cast<float>(4)); // Need to make sure the type matches!
std::cout << foo << "\n";
// -----
// Adding columns
cv::Mat bar = (cv::Mat_<float>(1, 3) << 0, 1, 2);
std::cout << bar << "\n";
// push_back needs to add a full row so reshapes are needed (but cheap)
bar = bar.reshape(1, bar.cols);
bar.push_back(3.0f);
bar = bar.reshape(bar.rows);
std::cout << bar << "\n";
return 0;
}
[0;
1;
2]
[0;
1;
2;
3]
[0;
1;
2;
3;
4]
[0, 1, 2]
[0, 1, 2, 3]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With