Color Spaces
How do we see colors?
Our eyes see color in three components: red, green, and blue. The pixels on your screen are actually a combination of red, green, and blue lights, but because these lights are so close to each other compared to how far away your eyes are, they appear as one color. If you have a giant TV and you stand really close, you may actually be able to see each color of pixel.
Armed with this knowledge, we can break a color down into 3 channels, on for red, one for green, and one for blue. Here's a picture of me flying an airplane.
But let's break that down into the three red, green, and blue channels.
- Red
- Green
- Blue
Each channel represents how red, green or blue something is, where black means no color.
Looking through another lens
But let's look at what happens if I change the image to a different color schemes. Try and guess what happens in each of the three channels.
- Channel 1
- Channel 2
- Channel 3
That image uses a color scheme called YCrCb, where there are three channels, Y is luminance, Cr is red, and Cb is blue. This color scheme is based off how our brains interpret colors. We recognize objects based on the contrast in brightness. In the first channel, Y, you can clearly see the contrast between the dashboard and the sky as well as my body and the rest of the cockpit. If we look at the second channel, Cr, my skin stands out from my sweatshirt because the sweatshirt is blue and my skin is not. If we look at the third channel, Cb, you can see that my blue sweatshirt stands out from everything else.
Now why is this useful? The YCrCb color scheme is great because brightness and color are not intertwined. This means that we can interpret the colors, regardless of what the brightness of our surroundings are, as opposed to RGB where a change in brightness affects all three channels.
Converting between colors
Converting between color spaces is really easy, but you have to keep track of when you switch, because there is no way to get OpenCV to tell you what color space you are using.
First, we have to know what our source color space is. By default, the input
parameter is in RGB.
Second, we need to know what our intended color space is. Supported color spaces are RGB, GRAY, HSV, LAB, XYZ, YCrCb (and more).
Then we can simply use the following function:
ImgProc.cvtColor(source, destination , color_space);
Source and destination are both any Mat
, though ideally the destination should be blank.
For the color space parameter, there are constants in the ImgProc class. Some examples are:
- ImgProc.COLOR_RGB2HSV
- ImgProc.COLOR_HSV2RGB
You can use the autocomplete menu to list what conversions are supported. Just type in ImgProc.COLOR_
and let the IDE
list all the options.
You may have to convert from one color to another first.
As an example, we can put the grayscale version of RGB in a new Mat
like so:
Mat inputGray = new Mat();
ImgProc.cvtColor(input, inputGray, ImgProc.COLOR_RGB2GRAY);
Whenever we are done, we should make sure input
is still in RGB. If it isn't, OpenCV will assume it is and the display
in the dashboard will have incorrect colors.
Whenever we convert to grayscale, we lose all color information. Whenever we convert back to RGB, it will still not have color. This is because all color spaces except grayscale have 3 channels, whereas grayscale only has 1, so it is impossible to get those channels back.