Frage

I'm trying to compute the most common color in an image. Using calcHist function, I understand I can get an histogram whose bins in a single channel are the pixel value, and the value of each bin is how many times is that value present in the image.

Also, it is easy to get the max value of the histogram (that is a double) and its position using minMaxLoc function.

But what I want is the whole color (the Vec3b object with the value of each channel).

Here's what I have so far:

 split(image, lab_channels); 

 histSize = 256;
 range[0] = 0;
 range[1] = 256;
 const float *lRange = {range};
 calcHist( &lab_channels[0], 1, 0, Mat(), 
     l_hist, 1, &histSize, &lRange, 
     true, false );

 histSize = 256;
 range[0] = 0;
 range[1] = 256;
 const float *aRange = {range};
 calcHist( &lab_channels[1], 1, 0, Mat(), 
     a_hist, 1, &histSize, &aRange, 
     true, 
     false );

 histSize = 256;
 range[0] = 0;
 range[1] = 256;

 const float *bRange = {range};
 calcHist( &lab_channels[2], 1, 0, Mat(), 
      b_hist, 1, &histSize, &bRange, t
      rue, false );

 minMaxLoc(l_hist, 0, 0, 0, &maxPos);
 result[0] = maxPos.y; 
 minMaxLoc(a_hist, 0, 0, 0, &maxPos);
 result[1] = maxPos.y; 
 minMaxLoc(b_hist, 0, 0, 0, &maxPos);
 result[2] = maxPos.y; 

where result is my Vec3b vector with the most common color.

This code works fine (it does retrieve a color), but the problem is that it gets the most common color separately from each channel and finally it's not necessarely the most common color in the combined channels.

So, if I do this procedure, but for the 3 channels (like it's shown in opencv documentation), how can I get this Vec3b vector from the resulting histogram? or at least another data type I could cast or transform to it.

War es hilfreich?

Lösung

Here is something you can do:

1st) Calculate the joint histogram. use calcHist with the 3-channel image, instead of calculating one independent histogram for each channel.

2nd) look for the maximum in the joint histogram, just as you did with the channel histograms, using minMaxLoc.

Now, it would be wonderful if we knew what color is assigned to each bin in the joint histogram, but this is not straightforward. You can either look at the OpenCV implementation, or ask someone about it ..or try the following:

3rd) Set all the joint histogram values to 0, except the value corresponding to the maximum you just found. Set the value of this bin to the maximum value (i.e 1.0 if this is a normalized histogram). Then do a backprojection of the histogram to the original image (use calcBackProject for that). The pixels with the most-frequent color (the one you are looking for) should be highlighted in the backprojection image.

Hope that it helps!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top