Skip to main content

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.

Me flying an airplane

But let's break that down into the three red, green, and blue channels.

Me flying an airplane

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.

Me flying an airplane

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
tip

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.

caution

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.