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++)
OpenCV has some built-in functions to perform Color detection and Segmentation operations. So what are Color Detection and Segmentation Techniques in Image Processing? Color detection is a technique of detecting any color in a given range of HSV (hue saturation value) color space.
HSV color space: It stores color information in a cylindrical representation of RGB color points. It attempts to depict the colors as perceived by the human eye. Hue value varies from 0-179, Saturation value varies from 0-255 and Value value varies from 0-255. It is mostly used for color segmentation purpose.
The reason we use HSV colorspace for color detection/thresholding over RGB/BGR is that HSV is more robust towards external lighting changes. This means that in cases of minor changes in external lighting (such as pale shadows,etc. ) Hue values vary relatively lesser than RGB values.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With