Reputation: 24151
I am using OpenCV 3.0 to load an image from file, and then store that data in an array.
If I use:
cv::Mat image = cv::imread("myimage.png");
uchar pixel = image.at<uchar>(50, 100);
It will give me the pixel value at the (x = 100, y = 50) image coordinate.
However, if I now copy the image memory to an array:
uchar data[image.rows * image.cols];
memcpy(data, image.data, image.rows * image.cols);
And then read the pixel value from this array:
uchar pixel = data[100 * image.cols + 50];
Then it does not give me the same value as before.
I'm wondering why this is? Is it because OpenCV does not store its memory as a single array in this way? If so, how could I copy the memory to an array and then access pixel values directly from this array?
Thanks :)
Upvotes: 2
Views: 1451
Reputation: 3200
That is because OpenCV uses padding.
Each line may contain extra bytes to ensure better alignment.
Copy your data this way if you want it without padding.:
for ( int i=0; i<image.rows; ++i )
memcpy( &data[i*100], image.data + image.step*i, 50);
Also, data is arranged by horizontal lines (rows). So you should access it this way :
image.at<uchar>(Y,X).
uchar pixel = data[Y*image.cols + X];
Or you could copy if with padding included :
memcpy( data, image.data, image.step*image.rows);
And then you would have to access it using lines of size image.step (which may be equal or larger than image.cols).
uchar pixel = data[Y*image.step + X];
Upvotes: 3