:::: MENU ::::

OpenCV: Color-spaces and splitting channels

Posted in November 6, 2014

There are more than 150 color-space conversion methods available in OpenCV. It is very easy to convert from one to another. We’re going to see how to do that and how to see what these color-spaces and its channels looks like. Watch the video to see how to change color-spaces and split channels using OpenCV.

Pre-requirements:
-- OpenCV installed: How to install OpenCV 3 on Ubuntu

Introduction

We can say that a color-space is a combination of a color model and a mapping function (this definition is well-known). For color model, we can understand any mathematical model that can be used to represent colors as numbers (e.g. RGB(255, 0, 0) represents the red color). For mapping function, we can understand any function that can map a color model to an absolute color space, in order to connect this color system to the real world, making it usable.

Conversion between color-spaces

Our goal here is to visualize each of the three channels of these color-spaces: RGB, HSV, YCrCb and L*a*b. In general, none of them are absolute color-spaces and the last three (HSV, YCrCb and L*a*b) are ways of encoding RGB information. Our images will be read in BGR (Blue-Green-Red), because of OpenCV defaults. For each of these color-spaces there is a mapping function and they can be found at OpenCV cvtColor documentation.
One important point is: OpenCV imshow() function will always assume that the Mat shown is in BGR color-space. Which means, we will always need to convert back to see what we want. Let’s start.

OpenCV Program: Split Channels (2506 downloads)

HSV

While in BGR, an image is treated as an additive result of three base colors (blue, green and red), HSV stands for Hue, Saturation and Value (Brightness). We can say that HSV is a rearrangement of RGB in a cylindrical shape. The HSV ranges are:

  • 0 > H > 360 ⇒ OpenCV range = H/2 (0 > H > 180)
  • 0 > S > 1 ⇒ OpenCV range = 255*S (0 > S > 255)
  • 0 > V > 1 ⇒ OpenCV range = 255*V (0 > V > 255)

YCrCb or YCbCr

It is used widely in video and image compression schemes. The YCrCb stands for Luminance (sometimes you can see Y’ as luma), Red-difference and Blue-difference chroma components. The YCrCb ranges are:

  • 0 > Y > 255
  • 0 > Cr > 255
  • 0 > Cb > 255

L*a*b

In this color-opponent space, L stands for the Luminance dimension, while a and b are the color-opponent dimensions. The L*a*b ranges are:

  • 0 > L > 100 ⇒ OpenCV range = L*255/100 (1 > L > 255)
  • -127 > a > 127 ⇒ OpenCV range = a + 128 (1 > a > 255)
  • -127 > b > 127 ⇒ OpenCV range = b + 128 (1 > b > 255)

Splitting channels

All the color-spaces mentioned above were constructed using three channels (dimensions). It is a good exercise to visualize each of these channels and realize what they really store, because when I say that the third channel of HSV stores the brightness, what do you expect to see? Remember: a colored image is made of three-channels (in our cases) and when we see each of them separately, what do you think the output will be? If you said a grayscale image, you are correct! However, you might have seen these channels as colored images out there. So, how? For that, we need to choose a fixed value for the other two channels. Let’s do this!
To visualize each channel with color, I used the same values used on the Slides 53 to 65 from CS143, Lecture 03 from Brown University.

RGB or BGR

Original image (a) and its channels with color: blue (b), green (c) and red (d). On the second row, each channel in grayscale (single channel image), respectively.

Original image (a) and its channels with color: blue (b), green (c) and red (d). On the second row, each channel in grayscale (single channel image), respectively.

HSV

Original image (a) and its channels with color: hue (b), saturation (c) and value or brightness (d). On the second row, each channel in grayscale (single channel image), respectively.

Original image (a) and its channels with color: hue (b), saturation (c) and value or brightness (d). On the second row, each channel in grayscale (single channel image), respectively.

YCrCb or YCbCr

Original image (a) and its channels with color: luminance (b), red-difference (c) and blue difference (d). On the second row, each channel in grayscale (single channel image), respectively.

Original image (a) and its channels with color: luminance (b), red-difference (c) and blue difference (d). On the second row, each channel in grayscale (single channel image), respectively.

L*a*b or CIE Lab

Original image (a) and its channels with color: luminance (b), a-dimension (c) and b-dimension (d). On the second row, each channel in grayscale (single channel image), respectively.

Original image (a) and its channels with color: luminance (b), a-dimension (c) and b-dimension (d). On the second row, each channel in grayscale (single channel image), respectively.


  • #!/42

    Thanks for the detailed post. Really helped me out. 🙂

  • disqus_7IVJR5GG7n

    Olá rodrigo, você sabe como eu poderia fazer a setagem do espaço de cores de forma sem ser usando o opencv ou qualquer outra biblioteca? Estou aprendendo a programação com imagens e preciso fazer essa alteração em baixo nivel porem não achei muita informação util na internet.
    Obrigada

    • As transformações entre espaços de cores são funções simples. Basta aplicar as conversões nas estruturas de dados que você estiver usando para suas imagens.

  • Paweł Lula

    can you help me understood why we have this values double std_values[3][3] = {{1, 127.5, 127.5}, {191.25, 1, 127.5}, {191.25, 127.5, 1}}; in all spaces, why we need them?

    • Yes, but to help you, I need the context. How did you get them?

      • Paweł Lula

        i down load you source code and in main.cpp in all methods show*() we have this variable “double std_values …” and i don’t know we need them, i what about values for another spaces like Luv or XYZ?

      • Oh sorry. These are the standard values used to see the colored versions of each channel. Single-channel images are grayscale, but often you’ll see them as colored images. To do this, you need to set a fixed value to the other 2 channels. This is explained in the post and you can see this on the slide I shared, from Brown University.

      • Paweł Lula

        thank you for your response. But what about standard values for spaces like LUV or XYZ, becouse i can’t find information on the internet about splitting these channels

      • I think you didn’t understand. These values are just for visualization. You can choose any value and you’ll get a colored image of a specific channel. There is no such thing as right/wrong values: play with them.

  • Paweł Lula

    thank, it will be very helpful

  • ade

    hai rodrigo.. how if continue capture from webcam?

    • You just need to feed the frames of the stream, in your case a stream from a webcam…