Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create cv::Mat header for const data

Tags:

Typically if my data is non-const, I can initialize a cv::Mat header on top of it for algebraic manipulation.

float awesome_data[24] = {0}; cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, awesome_data); 

But, if my data is const

const float awesome_data[24] = {0}; cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, awesome_data); 

will have an error: unable to convert from const void * to void *. I know that I won't be changing awesome_mat, what is the best way to do this?

Currently, I have to do a const cast

const float awesome_data[24] = {0}; cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, const_cast<float *>(awesome_data)); 
like image 209
Dat Chu Avatar asked Apr 13 '11 19:04

Dat Chu


2 Answers

The data in cv::Mat can always be modified. To be more safe you should copy the data:

const float awesome_data[24] = {0}; cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F, const_cast<float *>(awesome_data)).clone(); 

With const cv::Mat only the matrix header is readonly but not the data (Differences of using "const cv::Mat &", "cv::Mat &", "cv::Mat" or "const cv::Mat" as function parameters?):

const cv::Mat mat = cv::Mat::zeros(6, 4, CV_32F); mat += 1; // compiles and runs fine! 
like image 79
R1tschY Avatar answered Oct 06 '22 03:10

R1tschY


The only way to do this completely safely is to make a copy of awesome_data (one way or another). The solution by @R1tschY makes a copy of the data using an OpenCV method, which itself requires a const_cast. To avoid the const_cast altogether, the memory should be copied outside of OpenCV (since OpenCV does not respect const data). This would be one way:

const float awesome_data[24] = {0}; cv::Mat awesome_mat = cv::Mat(6, 4, CV_32F); //Allocates its own memory memcpy(awesome_mat.data, awesome_data, 24*sizeof(float)); //Copy into the allocated memory. 
like image 33
ianinini Avatar answered Oct 06 '22 03:10

ianinini