Q:

OpenCV color identification

Hi I'm trying to built simple color identifying program. I have taken a image (yellow & pink) with  and convert it in HSV color space. Then used threshold to identify yellow color region. I getting the output (black image). I want yellow region to be filled with while color and rest with black.

 

IplImage *imgRead= cvLoadImage("yellow.jpeg",CV_LOAD_IMAGE_COLOR);
if(!imgRead) {
fprintf(stderr, "Error in reading image\n");
exit(1);
}
IplImage *imgHsv = cvCreateImage(cvGetSize(imgRead),8, 3);
cvCvtColor(imgRead, imgHsv,CV_BGR2HSV);

IplImage *imgThreshold = cvCreateImage(cvGetSize(imgRead),8, 1);
cvInRangeS(imgHsv, cvScalar(25, 80, 80,80), cvScalar(34, 255, 255,255), imgThreshold);
cvShowImage("image",imgThreshold);
cvWaitKey(0);

In above code I had calculated HSV value for yellow as 30. (In gimp hsv value for yellow color is 60). In cvInRangeS, except for hue value I'm not sure how to specify other values for cvScalar.
What values I need to put? Am I missing anything?

A:

I think the problem you are having is due to the scaling of the HSV data to fit in 8-bits. Normally, as I'm sure you noticed from using GIMP that HSV scales are as follows:

H -> [0, 360]
S -> [0, 100]
V -> [0, 100]

But, OpenCV remaps these values as follows:

(H / 2) -> [0, 180] (so that the H values can be stored in 8-bits)
S       -> [0, 255]
V       -> [0, 255]

This is why your calculated Hue value is 30 instead of 60. So, to filter out all colors except for yellow your cvInRangeS call would look something like this:
cvInRangeS(imgHsv, cvScalar(25, 245, 245, 0), cvScalar(35, 255, 255, 255), imgThreshold);

The fourth channel is unused for HSV. This call would give you 10-counts of noise in your color detector threshold for each dimension.
As mentioned by, SSteve your threshold should work, but you may need to expand your threshold boundaries to capture the yellow-ish color in your image.
Hope that helps!

A:

I ran your code and it worked fine. Perhaps the yellow in your image isn't as yellow as you think.

Edit: The other potential difference is that I'm using OpenCV 2.3. Which version are you using?
Ok, one more edit: Have you tried looking at your yellow values? That would give you a definitive answer as to what values you should use in cvInRangeS. Add these two lines after the call to cvCvtColor:
uchar* ptr = (uchar*)(imgHsv->imageData);
printf("H: %d, S:%d, V:%d\n", ptr[0], ptr[1], ptr[2]);

For my image, I got:
H: 30, S:109, V:255

That's why your code worked for me.

