I recently spent a few hours struggling over how to convert RGB to HSV ranges in openCV. Most of the google results I got from my searches assumed I already knew something about colorspaces.
I did know some things. But there were “unknown unknowns”.
If you can get your openCV color range to work right, here’s all the stuff I wish I’d known.
Red Green Blue. Usually represented as (r,g,b) where the values are 0 to 255 depending on how much of each color you have. There is a hexidecimal equivalent as well (##FF0000 = (255,0,0), for example.
The 255 limit is due to 8 bit processing. If you have a higher powered computer you can have even more range.
Whoa! What is this? WHY is this? It is what it looks like: RGB, reversed. That’s probably all you need to know. The explanation of why has to do with how things are stored in memory but for beginners like me, understanding the low level stuff isn’t important.
I knew HSV was Hue, Saturation and Value. It also is sometimes called HSB, which is Hue Saturation, Brightness. It is NOT the same as HSL which is Hue Saturation Lightness.
Look at this cylinder and image the top outermost ring that I’ve lined in white. Those are the full color of spectrum.
Now if you move from any point on the edget, toward the circle you are adding white and the shade gets lighter:
Similarly, if you go down, you are adding black and the color becomes darker:
So what kinds of values can you put into (H, S, V)?
Typically it is (0-360, 0-100%, 0-100%) but don’t stop reading here because asterisk!
The first value is the value on the color wheel (the circle I drew) Zero is red, then it loops around 360 degrees (like a circle). So the red primary is at 0, the green primary is at 120, and the blue primary is at 240.
The second and third values are percentages of how much white and black you have… well sorta. That’s often how they’re described but maybe it’s best to think of it as values from 0-100. Because…
A big thing that hung me up was not realizing that depending on what application you are using, it might have a different scale for each value in HSV. This is often because it can’t fit that much into an 8 bit integer (0-255). OpenCV, for example, halves H to 179 but scales S and V up to the full 255. Which means for openCV:
For H: Your red primary is still at 0, but green is at 60 now and blue is at 120.
For S: Your value is 255 for the full primary red color’s saturation.
For V: Your value is 255 for the full primary red color’s value
Ok! So now I hope you have an understanding of (how I understand) HSV, RGB, and BGR in openCV.
Suppose you have a RGB and you want to convert it to HSV for openCV?
You can now use something like this to do it. But remember most of these tools are going to assume a 360 HSV and you’ll have to scale it to whatever you are using.
What if you want to convert it in python/openCV?
- Remember it uses BGR
- Remember in openCV that HSV ranges are (0-179, 0-255, 0-255)
- Use something like recommended here.
- In case you don’t follow the link above, let me elaborate on it:
1:green = np.uint8([[[0,255,0 ]]])
2: hsv_green = cv2.cvtColor(green,cv2.COLOR_BGR2HSV)
3: print hsv_green
> [[[ 60 255 255]]]
So the first line is saying “take this 8-bit BGR color and store that into green.
The second line says call the function “cvtColor” (ie, convert color).
“green” is the source (this could also be a file)
“cv2.COLOR_BGR2HSV is the conversion code (there are over 150 color-space conversion methods in openCV. This is just one of the codes)
What is printed to the screen is the HSV value.
Side note (thanks Alan Watts): With the halving, you lose lots of color information, so if you need more definition, you can use cv2.RGB2HSV_FULL during color conversion and it’ll fit the range into 0-255 instead.