Barshan Das
Barshan Das

Reputation: 3767

How to access the RGB values in Opencv?

I am confused about the use of number of channels. Which one is correct of the following?

// roi is the image matrix

for(int i = 0; i < roi.rows; i++)
{
    for(int j = 0; j < roi.cols; j+=roi.channels())
    {
        int b = roi.at<cv::Vec3b>(i,j)[0];
        int g = roi.at<cv::Vec3b>(i,j)[1];
        int r = roi.at<cv::Vec3b>(i,j)[2];
        cout << r << " " << g << " " << b << endl ;
    }
}

Or,

for(int i = 0; i < roi.rows; i++)
{
    for(int j = 0; j < roi.cols; j++)
    {
        int b = roi.at<cv::Vec3b>(i,j)[0];
        int g = roi.at<cv::Vec3b>(i,j)[1];
        int r = roi.at<cv::Vec3b>(i,j)[2];
        cout << r << " " << g << " " << b << endl ;
    }
}

Upvotes: 7

Views: 14986

Answers (3)

azwald
azwald

Reputation: 31

the second one is correct, the rows and cols inside the Mat represents the number of pixels, while the channel has nothing to do with the rows and cols number. and CV use BGR by default, so assuming the Mat is not converted to RGB then the code is correct

reference, personal experience, OpenCV docs

Upvotes: 2

Daniel Mart&#237;n
Daniel Mart&#237;n

Reputation: 7845

A quicker way to get color components from an image is to have the image represented as an IplImage structure and then make use of the pixel size and number of channels to iterate through it using pointer arithmetic.

For example, if you know that your image is a 3-channel image with 1 byte per pixel and its format is BGR (the default in OpenCV), the following code will get access to its components:

(In the following code, img is of type IplImage.)

for (int y = 0; y < img->height; y++) {
    for(int x = 0; x < img->width; x++) {
        uchar *blue = ((uchar*)(img->imageData + img->widthStep*y))[x*3];
        uchar *green = ((uchar*)(img->imageData + img->widthStep*y))[x*3+1];
        uchar *red = ((uchar*)(img->imageData + img->widthStep*y))[x*3+2];
    }
}

For a more flexible approach, you can use the CV_IMAGE_ELEM macro defined in types_c.h:

/* get reference to pixel at (col,row),
   for multi-channel images (col) should be multiplied by number of channels */
#define CV_IMAGE_ELEM( image, elemtype, row, col )       \
    (((elemtype*)((image)->imageData + (image)->widthStep*(row)))[(col)])

Upvotes: 1

Julien Greard
Julien Greard

Reputation: 1049

I guess the 2nd one is correct, nevertheless it is very time consuming to get the data like that.

A quicker method would be to use the IplImage* data structure and increment the address pointed with the size of the data contained in roi...

Upvotes: 0

Related Questions