Ask Your Question
2

Interfaces std::Vector to cv::Mat

asked 2014-10-30 02:56:15 -0500

MRDaniel gravatar image

updated 2014-10-30 03:49:49 -0500

Hello,

I am working with OpenCV and love the cv::Mat. Shared pointers for the win!

With a std::vector<cv::point>() we can simply convert to a cv::Mat.

std::vector<cv::Point> points = std::vector<cv::Point>();

cv::Mat pointsMat = cv::Mat(points);

cv::Point point = pointsMat.at<cv::Point>(0,0);

We can then access the points. Sweet.

There are other datatypes such as histograms, descriptors matrices that all use the cv::Mat, making it ideal for interfaces.

What about these types?

2Df/2Dd/3Df/3Dd Points

std::vector<cv::Point3d> points = std::vector<cv::Point3d>();

This is the same as above for cv::Point.

Keypoints

std::vector<cv::keypoint>(); Has other attributes as well as a Point2f, such as octave, size etc which are of mixed types.

Contours std::vector<std::vector<cv::point>>(); Possibly, std::vector<cv::mat> if treated like a single vector of cv::Point. However we still have a std::vector.

Descriptor Matches

std::vector<cv::dmatch>() This contains int, bool, float types.

With contours, it could be done using a std::vector<cv::mat> where a std::vector<cv::mat>(1) is used for single images and matrices. The std::vector is NOT thread safe, so i don't want to be passing too many of them around.

1) Can we convert these types to a cv::Mat? Even if a deconversion step back to their original type is required.

2) What is the overhead for converting std::vector to cv::Mat?

3) Are there any known interfaces for OpenCV primitives?

4) How would the conversion back from a cv::Mat to a std::vector work in each case? Thank you.

EDIT

I found this on a similar post on this forum.

Mat a = Mat::ones(10,1,CV_32FC3);
vector<Point3f> b;

a.copyTo(b);

Therefore... with Point2f....

Mat a = Mat::ones(10,1,CV_32FC2);

etc.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2014-10-30 05:08:35 -0500

updated 2014-10-30 05:21:42 -0500

Hi!

  1. It is possible to convert a vector to a cv::Mat, but only if vector inside-type is supported by OpenCV. That is, there is a structure called "DataType" which define how data can be used by Mat constructor (look in modules\core\include\opencv2\core\traits.hpp for examples). So this is defined for classic types (float, int...) and some more complex types, like cv::Complex<>, std::complex<>, cv::Vec<> etc. If you want to add your specific type, you just have to specialize this class. But be careful: inside-type can't be a structure of different types like cv::Keypoint is (there is float and int)! Indeed, a Mat with such data doesn't make sense as a Mat is defined with a single data type (CV_32F for instance), so the values would be incoherent.

  2. The constructor of Mat allow you to specify if you want to copy the data or not. If you don't want to copy data, the overhead is null!

  3. I don't understand this question ;-)

  4. Assuming your Mat is contiguous, the solution you post is the best you can do!

So here is a snippet of how to do this with classical types:

std::vector<cv::Point3d> test;
test.push_back(cv::Point3d(0, 1, 2)); test.push_back(cv::Point3d(3, 4, 5));
cv::Mat cvt(test, false);//second param for data copy (here, data are not duplicated!)
edit flag offensive delete link more
Login/Signup to Answer

Question Tools

Stats

Asked: 2014-10-30 02:56:15 -0500

Seen: 20,871 times

Last updated: Oct 30 '14