c++opencvgetpixel

OpenCV get pixel channel value from Mat image


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")?


Solution

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