OpenCV get pixel channel value from Mat image

2019-01-03 02:18发布

Maybe I'm not looking hard enough, but everything seems to want me to use an array. Thus, how do I get the channel value for a particular pixel for foo if foo is something like Mat foo = imread("bar.png")?

3条回答
小情绪 Triste *
2楼-- · 2019-01-03 02:44

The below code works for me, for both accessing and changing a pixel value.

For accessing pixel's channel value :

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]; 
        }   
    }
}

For changing a pixel value of a channel :

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;
        }
     }
}

`

Source : Accessing pixel value

查看更多
Luminary・发光体
3楼-- · 2019-01-03 02:45

The pixels array is stored in the "data" attribute of cv::Mat. Let's suppose that we have a Mat matrix where each pixel has 3 bytes (CV_8UC3).

For this example, let's draw a RED pixel at position 100x50.

Mat foo;
int x=100, y=50;

Solution 1:

Create a macro function that obtains the pixel from the array.

#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

Solution 2:

Get's the pixel using the method ptr.

unsigned char * p = foo.ptr(y, x); // Y first, X after
p[0] = 0;   // B
p[1] = 0;   // G
p[2] = 255; // R
查看更多
兄弟一词,经得起流年.
4楼-- · 2019-01-03 02:50

Assuming the type is CV_8UC3 you would do this:

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 is the documentation for Vec3b. Hope that helps! Also, don't forget OpenCV stores things internally as BGR not RGB.

EDIT :
For performance reasons, you may want to use direct access to the data buffer in order to process the pixel values:

Here is how you might go about this:

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...
    }
}

Or alternatively:

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...
    }
}
查看更多
登录 后发表回答