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.
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;
}