【发布时间】:2015-06-29 13:45:23
【问题描述】:
我已阅读Mat 格式的图像。
Mat image = imread("image.png", 1);
我使用
声明指向其数据的指针unsigned char *ptr_source = image.data
现在,我想访问for loop 中每个像素的 R、G 和 B 值。 我已经知道用img.at<Veb3b>(i,j) 或类似的东西来做这件事的方法,但现在,我必须用unsigned char 类型的指针来做。
uchar R_value = ptr_source[ i*?? + ??? ];
uchar G_value = ptr_source[ i*?? + ??? ];
uchar B_value = ptr_source[ i*?? + ??? ];
重要提示:有些人here 提到使用以下内容:
unsigned char *input = (unsigned char*)(img.data);
for(int j = 0;j < img.rows;j++){
for(int i = 0;i < img.cols;i++){
unsigned char b = input[img.step * j + i ] ;
unsigned char g = input[img.step * j + i + 1];
unsigned char r = input[img.step * j + i + 2];
}
}
根据openCV docs,这对我来说很有意义,但不幸的是它不适用于我的情况。另一个method posted at SO 说要使用以下内容:
uchar b = frame.data[frame.channels()*(frame.cols*y + x) + 0];
uchar g = frame.data[frame.channels()*(frame.cols*y + x) + 1];
uchar r = frame.data[frame.channels()*(frame.cols*y + x) + 2];
基本问题:虽然,它似乎工作,但我不明白它的逻辑。 为什么我们需要将(frame.cols*y + x) 与frame.channels() 相乘??
【问题讨论】:
-
你真的必须使用
data吗?无论如何.. 我认为 OpenCV 以 BGR 顺序存储像素,并且大小可能会根据加载的图像类型而变化。在这个solution(第二个答案)......他使用image.channels()来了解步长。我希望他的回答能对你有所帮助。 -
@wendelbsilva:是的,我正在寻找类似的东西,但我不确定这是否适合我。另外,B频道的
frame.channels()*(frame.cols*y + x) + 0我也看不懂。 -
数据按顺序存储。所以
frame.channels()*(frame.cols*y + x) + 0表示他正在尝试访问像素(x, y)。由于数据是连续的,因此数组中的位置将是y乘以矩阵的宽度 (frame.cols) 加上x。他在最后添加了0,只是为了帮助阅读算法。 -
@wendelbsilva:我能够理解那部分。我的困惑是,为什么我们需要乘以
frame.channels()以及它如何帮助我们获得 R、G 和 B 像素值? -
您可能有灰度图像。在这种情况下,字节数和它们的存储方式将与您拥有 RGB 或 RGBA 图像时不同。如果你知道你的图像是 RGB,你可以继续使用你想要的大小。但是如果你不知道它使用了多少字节,或者你想使用函数让算法更容易阅读,你可以使用
.channels()