cvtColor HSV Bug (Bug #328)


Added by Thomas A almost 15 years ago. Updated almost 13 years ago.


Status:Done Start date:
Priority:Blocker Due date:
Assignee:Gary Bradski % Done:

0%

Category:imgproc, video
Target version:-
Affected version: Operating System:
Difficulty: HW Platform:
Pull request:

Description

convert a RGB Mat in a HSV results in different colors

Scalar darkBlueRGB = (0,0,139);
Mat testMat(Size(300,200),CV_8UC3);
Mat testMatHSV;
floodFill(testMat,Point(0,0),darkBlueRGB);
imshow("RGBTest",testMat);
cvtColor(testMat,testMatHSV,CV_RGB2HSV);
imshow("HSVTest",testMatHSV);
testMat is blue but testMatHSV is green

Associated revisions

Revision 11dfceb2
Added by Marina Kolpakova about 12 years ago

Merge pull request #328 from jet47:new-gpu-fixes

History

Updated by Gary Bradski almost 15 years ago

Unless I am missing something, you are viewing an HSV image as a RGB image. The color will look strange but this is no bug. Convert the HSV back to RGB and then view it.

Updated by anonymous - almost 15 years ago

ok my fault but the real problem is this

Scalar darkBlueHSV = (225,255,255);
Mat testMat(Size(300,200),CV_8UC3);
Mat testMatHSV;
cvtColor(testMat,testMatHSV,CV_RGB2HSV);
floodFill(testMatHSV,Point(0,0),darkBlueHSV);
cvtColor(testMatHSV,testMat,CV_HSV2RGB);
imshow("RGBTest",testMat);

This Ends in a black window but HSV: (225,255,255) should be blue.

Updated by Chris Nichols over 14 years ago

1. There is a problem with your assignment of darkBlueHSV. As you have it written, when I check the value of darkBlueHSV in memory it is (255,0,0,0). To correctly assign:

Scalar darkBlueHSV = Scalar(225,255,255);

2. As far as I can tell from the wiki entry on cvtColor and from using the following test code, it seems like the Hue value is limited to (0,180) which actually is 1/2 of the Hue value if you are using the normal 360 degrees/100%/100% range. So the H values of (180,255) map to (0,75). In your example, 225 -> 45 -> 90 degrees gets you the correct BGR color when you use other converters on the web.

    int h = 225;
    Scalar hsv = Scalar(h,255,255);
    Mat testMatHSV1(Size(300,200), CV_8UC3, hsv);
    Mat testMatBGR1, testMatHSV2, testMatBGR2;

    cvtColor(testMatHSV1, testMatBGR1, CV_HSV2BGR);
    cvtColor(testMatBGR1, testMatHSV2, CV_BGR2HSV);
    cvtColor(testMatHSV2, testMatBGR2, CV_HSV2BGR);

In that example, testMatBGR1 and testMatBGR2 will be the same. However, if you use an h value on the range (180,255) then testMatHSV1 and testMatHSV2 will be different.

Updated by Chris Nichols over 14 years ago

If this is working as intended then it would be nice to make it more clear on the cvtColor wiki page. The closest mention that it makes is that

H <- H/2 (to fit to 0 to 255)

which isn't exactly clear. My first instinct would be to scale the full 360 degrees to the 8 bits which caused a good deal of confusion.

Updated by anonymous - over 14 years ago

in r3421 the new conversion codes added: CV_BGR2HSV_FULL and CV_HSV2BGR_FULL. They use the whole 0..255 hue range. Thus, the problem will be solved by using the new codes.

  • (deleted custom field) set to fixed

Updated by Andrey Kamaev almost 13 years ago

  • Category set to imgproc, video

Also available in: Atom PDF