How to initialize a cv::Mat using a vector of floats?
Asked Answered
C

2

7

Is there a way of initializing a opencv cv::Mat using a vector<float> object? Or do I need to loop over every entry of the vector and write it into the cv::Mat object?

Counterfoil answered 19/4, 2016 at 14:54 Comment(4)
What does your vector of float hold? Color of every pixel or scale of your desired Mat?Sacerdotal
Mat1f mat(1, vec.size(), vec.data()Outhouse
cv::Mat mat( vec ); ^^ do same.Systematist
@sturkmen: It works. If you write your proposal as an answer I will accept it. Also the vector will be represented as a column. Is there also a way to use it to initialize a row? (If not I can simply transpose the Mat)Counterfoil
S
6

I wrote the following test code ( including @Miki 's comment ) to myself to understand in detail.

you will understand well when you test it.

#include <opencv2/highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
vector<float> vec{0.1,0.9,0.2,0.8,0.3,0.7,0.4,0.6,0.5,1};

Mat m1( vec ); 
imshow("m1",m1);
waitKey();

Mat m2( 1,vec.size(), CV_32FC1,vec.data());
imshow("m2",m2);
waitKey();

Mat1f m3( vec.size(), 1, vec.data());
imshow("m3",m3);
waitKey();

Mat1f m4( 1, vec.size(), vec.data());
imshow("m4",m4);
waitKey();

cout << "as seen below all Mat and vector use same data" << endl;
cout << vec[0] << endl;
m1 *= 2;
cout << vec[0] << endl;
m2 *= 2;
cout << vec[0] << endl;
m3 *= 2;
cout << vec[0] << endl;
m4 *= 2;
cout << vec[0] << endl;

return 0;
}
Systematist answered 19/4, 2016 at 22:23 Comment(1)
It's worth nothing that with your approach you can also deep copy the data directly (with true in the constructor) while with mine you would need to clone the matrix for deep copy. Also, to get a matrix with given rows and cols, with your approach you'll need to reshape, while with mine you can specify rows and cols in the constructor. So both methods have pros and cons, depending on your task.Outhouse
D
0

OpenCv supports std::vector -> cv::Mat mapping with or without copy. It's in the docs!

template<typename _Tp > 
cv::Mat::Mat(const std::vector< _Tp > &  vec, bool copyData = false);

Example:

vector<float> image(100); // vector with 100 floats (could be any supported types)
cv::Mat cv_image{image, false};

Next, you can reshape the resulting image given the number of rows and the number of channels:

int desired_rows = 10;
int desired_channels = 1;
cv_image = cv_image.reshape(desired_channels, desired_rows);
Doloroso answered 17/12, 2023 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.