Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access the RGB values in Opencv?

Tags:

c++

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 ;
    }
}
like image 945
Barshan Das Avatar asked Nov 26 '12 14:11

Barshan Das


2 Answers

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

like image 191
azwald Avatar answered Oct 08 '22 07:10

azwald


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)])
like image 42
Daniel Martín Avatar answered Oct 08 '22 06:10

Daniel Martín