Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert C++ array to opencv Mat

Tags:

c++

opencv

What is the fastest way to convert a C++ array into an 2D opencv Mat object? Brute force method would be to loop over all entries of the 2D mat and fill them with values of the array.
Is there a better / faster way to do that? Could I somehow just give pointer of the array to the 2D matrix?
(I'm using opencv 2.4.8)

like image 304
mcExchange Avatar asked Jun 09 '17 08:06

mcExchange


People also ask

What is a CV mat?

The Mat class of OpenCV library is used to store the values of an image. It represents an n-dimensional array and is used to store image data of grayscale or color images, voxel volumes, vector fields, point clouds, tensors, histograms, etc.

What is CV_64F?

That is, image of type CV_64FC1 is simple grayscale image and has only 1 channel: image[i, j] = 0.5. while image of type CV_64FC3 is colored image with 3 channels: image[i, j] = (0.5, 0.3, 0.7) (in C++ you can check individual pixels as image.at<double>(i, j) ) CV_64F is the same as CV_64FC1 .

What is CV_8UC3?

CV_8UC3 - 3 channel array with 8 bit unsigned integers. CV_8UC4 - 4 channel array with 8 bit unsigned integers. CV_8UC(n) - n channel array with 8 bit unsigned integers (n can be from 1 to 512) )

What is scalar OpenCV?

ScalarRepresents a 4-element vector. The type Scalar is widely used in OpenCV for passing pixel values. In this tutorial, we will use it extensively to represent BGR color values (3 parameters). It is not necessary to define the last argument if it is not going to be used.


1 Answers

Yes there is, in the documentation of cv::Mat you can see how it can be achieved.

Specifically in this line

C++: Mat::Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP)

This means that you can do something like

double x[100][100];

cv::Mat A(100, 100, CV_64F, x);

This will not copy the data to it. You have to also remember that OpenCV data is row major, which means that it has all the columns of one rows and then the next row and so on. So your array has to match this style for it to work.

About how fast it is, the documentation also talks about it:

data – Pointer to the user data. Matrix constructors that take data and step parameters do not allocate matrix data. Instead, they just initialize the matrix header that points to the specified data, which means that no data is copied. This operation is very efficient and can be used to process external data using OpenCV functions. The external data is not automatically deallocated, so you should take care of it.

It will work quite fast, but it is the same array, if you modified it outside of the cv::Mat, it will be modified in the cv::Mat, and if it is destroyed at any point, the data member of cv::Mat will point to a non-existant place.

UPDATE:

I forgot to also say, that you can create the cv::Mat and do std::memcpy. This way it will copy the data, which may be slower, but the data will be owned by the cv::Mat object and destroyed upon with the cv::Mat destroyer.

double x[100][100];
cv::Mat A(100,100,CV_64F);
std::memcpy(A.data, x, 100*100*sizeof(double));
like image 105
api55 Avatar answered Sep 20 '22 17:09

api55