2015-08-19 201 views
2

我使用OpenCV 3.0从文件加载图像,然后将数据存储在数组中。OpenCV:矩阵元素访问

如果我使用:

cv::Mat image = cv::imread("myimage.png"); 
uchar pixel = image.at<uchar>(50, 100); 

它会给我在的像素值(X = 100,Y = 50)的图像坐标。

但是,如果我现在图像存储器复制到一个数组:

uchar pixel = data[100 * image.cols + 50]; 

然后,它不给我相同的值:

uchar data[image.rows * image.cols]; 
memcpy(data, image.data, image.rows * image.cols); 

,然后从该阵列读取像素值像之前一样。

我想知道这是为什么?是否因为OpenCV不以这种方式将其内存作为单个阵列存储?如果是这样,我怎么能将内存复制到一个数组,然后直接从这个数组访问像素值?

谢谢:)

+0

这是因为数据对齐正在存储第一行,然后是secpnd行。 .at(50,100)表示col = 100,row = 50,因此您必须访问数据[50 * image.cols + 100]。如果矩阵不连续,请参阅jose antonios的答案。啊...他也提到了x/y排序:D – Micka

回答

3

这是因为OpenCV使用填充。
每行可能包含额外的字节以确保更好的对齐。

如果你想让它不填充:

for (int i=0; i<image.rows; ++i) 
    memcpy(&data[i*100], image.data + image.step*i, 50); 

此外,数据由水平线(行)安排复制数据这种方式。所以,你应该访问这样说:

image.at<uchar>(Y,X). 
uchar pixel = data[Y*image.cols + X]; 

或者你也可以复制,如果用填充包括:

memcpy(data, image.data, image.step*image.rows); 

然后,你将不得不使用尺寸image.step线它(这可能是访问等于或大于image.cols)。

uchar pixel = data[Y*image.step + X]; 
+0

是的,如果以后你使用image.step来访问它。不,如果你想要数据没有填充和访问image.cols,我假设这是什么需要在这里。 –