OpenCV C ++: how CV_32F access pixel value via uchar data pointer

In short, I would like to know if it is possible to directly access the pixel value from CV_32F Mat, through the Mat member "uchar * data".

I can do it without problems if Mat is CV_8U, for example:

// a matrix 5 columns and 6 rows, values in [0,255], all elements initialised at 12 cv:Mat A; A.create(5,6, CV_8UC1); A = cv::Scalar(12); //here I successfully access to pixel [4,5] uchar *p = A.data; int value = (uchar) p[4*A.step + 5]; 

The problem is that I am trying to perform the same operation with the following matrix,

 // a matrix 5 columns, 6 rows, values in [0.0, 1.0], all elements initialised at 1.2 cv::Mat B; B.create(5,6, CV_32FC1); B = cv::Scalar(1.2); //this clearly does not work, no syntax error but erroneous value reported! uchar *p = B.data; float value = (float) p[4*B.step + 5]; //this works, but it is not what I want to do! float value = B.at<float>(4,5); 

Thanks a lot Valerio

+7
opencv
source share
2 answers

You can use the ptr method, which returns a pointer to a matrix row:

 for (int y = 0; y < mat.rows; ++y) { float* row_ptr = mat.ptr<float>(y); for (int x = 0; x < mat.cols; ++x) { float val = row_ptr[x]; } } 

You can also use the data pointer for float and use elem_step instead of step if the matrix is ​​continuous:

 float* ptr = (float*) mat.data; size_t elem_step = mat.step / sizeof(float); float val = ptr[i * elem_step + j]; 
+15
source share

Note that CV_32F means that the elements are float instead of uchar . "F" here means "swim." And the “U” in CV_8U means unsigned integer . Perhaps that is why your code does not give the correct value. Declaring p as uchar* , p[4*B.step+5] causes p to move to the fifth line and advance sizeof(uchar)*5 , which are usually wrong. You can try

 float value = (float) p[4*B.step + 5*B.elemSize()] 

but I'm not sure if this will work. Here are some ways to pass [i, j] data to a value:

  • value = B.at<float>(i, j)
  • value = B.ptr<float>(i)[j]
  • value = ((float*)B.data)[i*B.step+j]

The third method is not recommended, as it easily overflows. Also, a 6x5 matrix should be created by B.create(6, 5, CV_32FC1) , I think?

+5
source share

All Articles