也许我看起来不够努力,但似乎所有东西都要我使用数组。因此,如果foo类似于Mat foo = imread("bar.png")
,如何获取foo的特定像素的通道值?
答案 0 :(得分:89)
假设类型为CV_8UC3,您可以这样做:
for(int i = 0; i < foo.rows; i++)
{
for(int j = 0; j < foo.cols; j++)
{
Vec3b bgrPixel = foo.at<Vec3b>(i, j);
// do something with BGR values...
}
}
Here是Vec3b的文档。希望有所帮助!另外,不要忘记OpenCV内部存储的内容为 BGR 而不是RGB。
编辑:
出于性能原因,您可能希望使用直接访问数据缓冲区来处理像素值:
您可以采用以下方式:
uint8_t* pixelPtr = (uint8_t*)foo.data;
int cn = foo.channels();
Scalar_<uint8_t> bgrPixel;
for(int i = 0; i < foo.rows; i++)
{
for(int j = 0; j < foo.cols; j++)
{
bgrPixel.val[0] = pixelPtr[i*foo.cols*cn + j*cn + 0]; // B
bgrPixel.val[1] = pixelPtr[i*foo.cols*cn + j*cn + 1]; // G
bgrPixel.val[2] = pixelPtr[i*foo.cols*cn + j*cn + 2]; // R
// do something with BGR values...
}
}
或者:
int cn = foo.channels();
Scalar_<uint8_t> bgrPixel;
for(int i = 0; i < foo.rows; i++)
{
uint8_t* rowPtr = foo.row(i);
for(int j = 0; j < foo.cols; j++)
{
bgrPixel.val[0] = rowPtr[j*cn + 0]; // B
bgrPixel.val[1] = rowPtr[j*cn + 1]; // G
bgrPixel.val[2] = rowPtr[j*cn + 2]; // R
// do something with BGR values...
}
}
答案 1 :(得分:14)
以下代码适用于访问和更改像素值。
用于访问像素的频道值:
for (int i = 0; i < image.cols; i++) {
for (int j = 0; j < image.rows; j++) {
Vec3b intensity = image.at<Vec3b>(j, i);
for(int k = 0; k < image.channels(); k++) {
uchar col = intensity.val[k];
}
}
}
用于更改频道的像素值:
uchar pixValue;
for (int i = 0; i < image.cols; i++) {
for (int j = 0; j < image.rows; j++) {
Vec3b &intensity = image.at<Vec3b>(j, i);
for(int k = 0; k < image.channels(); k++) {
// calculate pixValue
intensity.val[k] = pixValue;
}
}
}
`
答案 2 :(得分:1)
像素数组存储在cv :: Mat的“data”属性中。假设我们有一个Mat矩阵,其中每个像素有3个字节(CV_8UC3)。
对于此示例,让我们在位置100x50处绘制一个RED像素。
Mat foo;
int x=100, y=50;
解决方案1:
创建一个从数组中获取像素的宏函数。
#define PIXEL(frame, W, x, y) (frame+(y)*3*(W)+(x)*3)
//...
unsigned char * p = PIXEL(foo.data, foo.rols, x, y);
p[0] = 0; // B
p[1] = 0; // G
p[2] = 255; // R
解决方案2:
使用ptr。
方法获取像素unsigned char * p = foo.ptr(y, x); // Y first, X after
p[0] = 0; // B
p[1] = 0; // G
p[2] = 255; // R