Ask Your Question

Extracting the Percentage of color (Red,blue,green,yellow,orange) in an image in Opencv?

asked 2014-01-30 10:51:45 -0500

user1234 gravatar image

updated 2014-01-30 10:54:53 -0500

I have to differentiate between 5 types of images which could have mostly either red,green, blue, orange or yellow color with some white or black color. I have to find which color is prominent in the image.

The source of images is Webcam, so the actual color also depends upon the illumination and distance of the image from webcam.

I am trying to calculate the percentage based upon "Hue" values. I am specifying some range for each color. My ranges are:

Red: 0-10
Green: 50-65

Yellow: 18-21

Blue: 100-115

PROBLEM: Even though the image displayed is not Red still i am getting high % for red color.

My code is following:

int findRect::checkByHSV(int svmResult, Mat detectedSquare)

    Mat hsv_img;

    Vec3b pixel;
    float totalPixel=0; // to count the total number of pixels in an image---to get the Percentage later
    float totalClass[6];// because we want to test for 5 classes + a garbage class.{{ Class-0 -> Garbage, Class-1->Orange, Class-2->Green, Class-3->Red, 
                        //  Class-4->Blue, Class-5->Yellow }} 

    for(int i=0; i<hsv_img.rows; i++)
        for (int j=0; j<hsv_img.cols; j++)


            if(  pixel[0]>0 &&  pixel[0]<1  )           totalClass[1]++;    // Class-1->Orange
            else if (  pixel[0]>50 &&  pixel[0]<65  )   totalClass[2]++;    // To check Green class-2 //svmResult==2 && 
            else if (  pixel[0]>0 &&  pixel[0]<10  )        totalClass[3]++;    // Class-3->Red
            else if (  pixel[0]>100 &&  pixel[0]<115  )     totalClass[4]++;    // Class-4->Blue
            else if (  pixel[0]>18 &&  pixel[0]<21  )       totalClass[5]++;    // Class-5->Yellow


    float percentage[5];
    totalClass[0]=0; //Putting zero to the Garbage class

    for (int i=0; i<=5; i++)
        percentage[i] = (totalClass[i] / totalPixel )*100;

    cout<<"\n Organge: "<<percentage[1]<<"  Green: "<<percentage[2]<<"  Red: "<<percentage[3]<<"  Blue: "<<percentage[4]<<"  Yellow: "<<percentage[5]<<"\n \n";

    return svmResult;
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2014-01-30 12:09:24 -0500

icedecker gravatar image

You can use the function countNonZero and divide by the total number of pixels of image. A example of use:

vector<Mat> channels;

Mat red, blue, green;
inRange(channels[0], Scalar(0), Scalar(10), red); // red
// ... do the same for blue, green, etc only changing the Scalar values and the Mat

double image_size = hsv_img.cols*hsv_img.rows;
double red_percent = ((double) cv::countNonZero(red))/image_size;

But it could be not optimal depending of the application (for example, if you need to scan lots of image). Anyway, you can use it to compare the values.

edit flag offensive delete link more

Question Tools


Asked: 2014-01-30 10:51:45 -0500

Seen: 5,414 times

Last updated: Jan 30 '14