Reputation: 129
I am using OpenCV 3.1 with VS2012 C++/CLI.
I have stored the result of a finContours call into:
std::vector<std::vector<Point>> Contours;
Thus, Contours[0] is a vector of the contour points of the first contour. Contours[1] is a vector of the contour points of the second vector, etc.
Now, I want to load one of the contours into a Mat Based on Convert Mat to vector <float> and Vector<float> to mat in opencv I thought something like this would work.
Mat testMat=Mat(Images->Contours[0].size(),2,CV_32FC1);
memcpy(testMat.data,Images->Contours[0].data(),Images->Contours[0].size()*CV_32FC1);
I specified two columns because I each underlying pint must be composed of both an X point and a Y point and each of those should be a float. However, when I access the Mat elements, I can see that the first element is not the underlying data but the total number of contour points.
Any help on the right way to accomplish this appreaciated.
Upvotes: 1
Views: 2759
Reputation: 41765
You can do that with:
Mat testMat = Mat(Images->Contours[0]).reshape(1);
Now testMat
is of type CV_32SC1
, aka of int
. If you need float
you can:
testMat.convertTo(testMat, CV_32F);
Some more details and variants...
You can simply use the Mat
constructor that accepts a std::vector
:
vector<Point> v = { {0,1}, {2,3}, {4,5} };
Mat m(v);
With this, you get a 2 channel matrix with the underlying data in v
. This means that if you change the value in v
, also the values in m
change.
v[0].x = 7; // also 'm' changes
If you want a deep copy of the values, so that changes in v
are not reflected in m
, you can use clone
:
Mat m2 = Mat(v).clone();
Your matrices are of type CV_32SC2
, i.e. 2 channels matrices of int
(because Point
uses int
. Use Point2f
for float
). If you want a 2 columns single channel matrix you can use reshape
:
Mat m3 = m2.reshape(1);
If you want to convert to float
type, you need to use convertTo
:
Mat m4;
m2.convertTo(m4, CV_32F);
Here some working code as a proof of concept:
#include <opencv2\opencv.hpp>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
vector<Point> v = { {0,1}, {2,3}, {4,5} };
// changes in v affects m
Mat m(v);
// changes in v doesn't affect m2
Mat m2 = Mat(v).clone();
// m is changed
v[0].x = 7;
// m3 is a 2 columns single channel matrix
Mat m3 = m2.reshape(1);
// m4 is a matrix of floats
Mat m4;
m2.convertTo(m4, CV_32F);
return 0;
}
Upvotes: 2