I am trying to convert RGB image into HSV but I get very strange results. So as a test I made an image with one solid colour:
red (64) green (46) blue (120)
According to gimp, the hsv values should be 255 62 47
Here is some code…
// coloured image
tempColorImage = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 3);
cvSet(tempColorImage, cvScalar(64, 46, 120));
// hsv image
hsvImage = cvCreateImage(cvSize(width,height), IPL_DEPTH_8U, 3);
cvCvtColor( tempColorImage, hsvImage , CV_RGB2HSV);
// print rgb values of first pixel
int r = (int)tempColorImage->imageData;
int g = (int)tempColorImage->imageData;
int b = (int)tempColorImage->imageData;
printf("r %i g %i b %i\n", r,g,b);
// print hsv values of first pixel
int h = (int)hsvImage->imageData;
int s = (int)hsvImage->imageData;
int v = (int)hsvImage->imageData;
printf("h %i s %i v %i\n", h, s, v);
The rgb values are shown fine.
When using CV_RGB2HSV the hsv are 127 -99 120
When using CV_BGR2HSV the hsv show as -83 -99 120
I must be doing something wrong here.
the calls look right, but the negative numbers suggest that maybe you are doing something wrong with how you are printing out the values. it’s a char * pointer, not an unsigned char pointer, so printing it as an int will not get you the right values (they go betw. -127 & 127). for example, this:
is not this,
where the first convert img->imageData into a pointer and grabs the i
th value stepping i amount in floats, the second takes the ith char
(-127 to 127) and converts it to a float.
I think you are not getting values you would expect because you either
have to (a) & 0xff
(http://darksleep.com/player/JavaAndUnsignedTypes.html) or (b) cast
imageData pointer to a unsigned char array before you get the pixels
int r = (int) ((unsigned char *)tempColorImage->imageData);
hope that helps!!
Many thanks Zach, you are spot on. printf wasnt displaying right.
The other thing that I’ve just worked out…
rgb of 64 46 120
in gimp the hsv shows as 254 62 47
in opencv the hsv shows as 127 157 120
gimp ranges are:
h 0 - 360
s 0 - 100
v 0 - 100
opencv ranges seem to be
h 0 - 180
s 0 - 255
v 0 - 255
so working out
127/180 * 360 = 254
157/255 * 100 = 62
120/255 * 100 = 47
So the values were right all along, I was just displaying them wrong and working within gimps ranges not opencv.
I am doing something similar to you here. Could you tell me how you would change the code if you were to read hsv value for a pixel (400, 600)?