Reputation: 123
I need to find the most present color in an image with OpenCV. I referred https://docs.opencv.org/2.4/modules/imgproc/doc/histograms.html?highlight=calchist and when I run that code I get for the H-S histogram is as below image. How do I tell the most present color from that histogram? Can someone please tell me how I get the most present color in an image using the histogram for HSV? (I am using C++)
Upvotes: 5
Views: 3046
Reputation: 18321
Maybe you need a colormap like this:
(The image is taken from my another answer : Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV))
Notice that the Hue
domains the color
so I scale it 4X. The x
axis is H
, the y
axis is S
, while keep V=255
.
Then according the maxval position (H-S), lookup the colormap to get the color.
Another example is that:
For this image:
Calculate the H-S hist, log it, threshold to get the domain colors' mask, like this:
Upvotes: 2
Reputation: 556
As far as I can see (a very ambigous description on opencv site) here we have Hue on first axis, Saturation on second axis and color intensity as point brightness. Hue varies from 0 (red) to 180 (from violet to red). Saturaion varies from 0 to 255 (black-gray-white). Hue is quantized from 180 to 30. Saturation is quantized from 255 to 32 (in accordance with your link to opencv site). The brighter square area on histogram, the brighter some combination of hue and saturation on your image. I reproduced OpenCV sample on my PC. I added my source image and HS histogram. On HS histogram we can see one bright rectangle corresponding to blue color of medium saturation I also added source modified for OpenCV 3.4.0
#include <Windows.h>
#include <Vfw.h>
#include "opencv2\core\core.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\imgcodecs\imgcodecs.hpp"
#include "opencv2\highgui\highgui.hpp"
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
Mat src, hsv;
src=imread("blue_circle.jpg");
cvtColor(src, hsv, CV_BGR2HSV);
// Quantize the hue to 30 levels
// and the saturation to 32 levels
int hbins = 30, sbins = 32;
int histSize[] = {hbins, sbins};
// hue varies from 0 to 179, see cvtColor
float hranges[] = { 0, 180 };
// saturation varies from 0 (black-gray-white) to
// 255 (pure spectrum color)
float sranges[] = { 0, 256 };
const float* ranges[] = { hranges, sranges };
MatND hist;
// we compute the histogram from the 0-th and 1-st channels
int channels[] = {0, 1};
calcHist( &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);
int scale = 10;
Mat histImg = Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
for( int h = 0; h < hbins; h++ )
for( int s = 0; s < sbins; s++ )
{
float binVal = hist.at<float>(h, s);
int intensity = cvRound(binVal*255/maxVal);
rectangle( histImg, Point(h*scale, s*scale),
Point( (h+1)*scale - 1, (s+1)*scale - 1),
Scalar::all(intensity),
CV_FILLED );
}
namedWindow( "Source", CV_WINDOW_FREERATIO );
imshow( "Source", src );
namedWindow( "H-S Histogram", CV_WINDOW_FREERATIO );
imshow( "H-S Histogram", histImg );
waitKey(0);
return 0;
}
Upvotes: 4
Reputation: 26345
Judging from the image you've posted, and a very brief read of the description at the link, it looks like the rows represent hues and columns represent saturations. So it looks like the above image is saying that a hue of 0 and a saturation of about 3/4ths of the max is the color with the most occurrences. Usually a hue of 0 is red, so it's probably a fairly bright, fairly pure red in this case.
Upvotes: 3