I've seen a lot of OpenCV code which accesses the data member of a cv::Mat
directly. cv::Mat
stores the pointer to the data in a unsigned char* data
member. Access to the data member looks like:
cv::Mat matUC(3,3,CV_8U)
int rowIdx = 1;
int colIdx = 1;
unsigned char val = matUC.data[ rowIdx * matUC.cols + colIdx]
I'm wondering if this works for a cv::Mat
with pixel type other than unsigned char
.
cv::Mat matF(3,3,CV_32F)
int rowIdx = 1;
int colIdx = 1;
float val = matF.data[ rowIdx * matF.cols + colIdx];
My understanding would be that a typecast is needed to access the elements correctly. Something like:
float val = ((float*)matF.data)[ rowIdx * matF.cols + colIdx];
I've seen a lot of code which doesn't use a typecast. So my question is: Is the typecast mandatory to access the correct element?
Mat
data is an uchar*
. If you have a, say, float matrix CV_32FC1
, you need to access data as float
.
You can do in different ways, not necessarily using casting:
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
cv::Mat matF(3, 3, CV_32F);
randu(matF, Scalar(0), Scalar(10));
int rowIdx = 1;
int colIdx = 1;
// 1
float f1 = matF.at<float>(rowIdx, colIdx);
// 2
float* fData2 = (float*)matF.data;
float f2 = fData2[rowIdx*matF.step1() + colIdx];
// 3
float* fData3 = matF.ptr<float>(0);
float f3 = fData3[rowIdx*matF.step1() + colIdx];
// 4
float* fData4 = matF.ptr<float>(rowIdx);
float f4 = fData4[colIdx];
// 5
Mat1f mm(matF); // Or directly create like: Mat1f mm(3, 3);
float f5 = mm(rowIdx, colIdx);
// f1 == f2 == f3 == f4 == f5
return 0;
}
Notes
step1()
instead of cols
when accessing directly data
through pointers, since the image may not be continuous. Check here for more details.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With