Getting dominant colour value from HSV Histogram

2019-02-21 05:28发布

问题:

I am creating a hsv histogram from an image like below.

- (void)processImageWithHsv:(Mat&)image;
{
    Mat image_hsv;

    cvtColor(image, image_hsv, CV_BGR2HSV);

    int hbins = 50, sbins = 60;
    int histSize[] = {hbins, sbins};

    float hranges[] = { 0, 360 };
    float sranges[] = { 0, 256 };

    const float* ranges[] = { hranges, sranges };
    MatND hist;

    int channels[] = {0, 1};

    calcHist( &image_hsv, 1, channels, Mat(), // do not use mask
             hist, 2, histSize, ranges,
             true, // the histogram is uniform
             false );

    double maxVal = 0;
    minMaxLoc(hist, 0, &maxVal, 0, 0);

    // ???: HOW Convert this information to colour value

}

But I have no idea to get most dominant color value from that hist? Should I use maxVal?

回答1:

You made some mistakes:

  1. You are looking for dominant color value but you tell calcHist to work with hue and saturation. You should change channels.
  2. Your hranges is wrong: it should be 180.
  3. dims should be 1 (not 2), because you only need the value histogram.

After those correction maxVal should contain the most recurring value value.



回答2:

- (void)processImageWithHsv:(Mat&)image;
{
    Mat image_hsv;

    cvtColor(image, image_hsv, CV_BGR2HSV);

    // Quanta Ratio
    int scale = 10;

    int hbins = 36, sbins = 25, vbins = 25;
    int histSize[] = {hbins, sbins, vbins};

    float hranges[] = { 0, 180 };
    float sranges[] = { 0, 256 };
    float vranges[] = { 0, 256 };

    const float* ranges[] = { hranges, sranges, vranges };
    MatND hist;

    int channels[] = {0, 1, 2};

    calcHist( &image_hsv, 1, channels, Mat(), // do not use mask
             hist, 3, histSize, ranges,
             true, // the histogram is uniform
             false );

    int maxVal = 0;

    int hue = 0; 
    int saturation = 0; 
    int value = 0; 

    for( int h = 0; h < hbins; h++ )
        for( int s = 0; s < sbins; s++ )
             for( int v = 0; v < vbins; v++ )
                {
                      int binVal = hist.at<int>(h, s, v);
                      if(binVal > maxVal)
                      {
                          maxVal = binVal;

                          hue = h;
                          saturation = s;
                          value = v;
                      }
                }

    hue = hue * scale; // angle 0 - 360
    saturation = saturation * scale; // 0 - 255
    value = value * scale; // 0 - 255
}