Updated date:

Color spaces (RGB vs HSV) - Which one you should use?

Tarek is a software engineer who has some experience working on image processing projects. He would like to share his learnings.

RGB Color Space


When working on Image processing or computer vision tasks, you will observe that RGB (Red, Green and Blue) color space is usually the default space where your frames (or images) are loaded in. It is the most commonly understood color space, a three dimensional model, consist of three primary colors, and based on the combination of these colors you are able to generate any other possible color.

HSV Color Space


Another popular color space is HSV, it is composed three components, Hue, Saturation and Value. In simple terms, Hue represents the actual pure color perceived by our eyes, Saturation is the colorfulness of that pure color (i.e decreasing Saturation reduces the colorfulness from the color itself), Value is the intensity of the color, correlates with the its darkness.

The distribution of colors in Hue component aligns well with color of the visible light spectrogram.

  • Red ranges between 0 and 60 degrees.
  • Yellow ranges between 61 and 120 degrees.
  • Green ranges between 121-180 degrees.
  • Cyan ranges between 181-240 degrees.
  • Blue ranges between 241-300 degrees.
  • Magenta ranges between 301-360 degrees.

Why HSV is usually preferred in image processing tasks?

In most image processing and computer vision applications, people tend to use HSV model more than RGB model.

One way to see the difference is by looking at the objective by which each model was built. For RGB model, it was technically built/optimized for the display screen, however, for HSV model, it is built to mimic how humans interpret colors, quite close to Munsell color system which is based on rigorous measurements of human subjects' visual responses to color.

Since HSV is capable of separating pure colors from their lightness, this allows people to perform different operations on either the color itself (Hue) or its intensity (Value). For example, in computer vision applications, people are more interested in the color of the image but less interested in its lightness, in fact, in most applications lightness is considered a noise, because it could affect the image uniqueness without having a real change in it (except for the lightness), this explains why usually HSV makes the algorithm more robust and less sensitive to image lightness.

Next we are going to see two cases where doing image processing in HSV space is more useful than RGB space.

Hue is a robust shadow invariant channel in HSV.

As explained above, in this section, I am going to provide a practical example asserting the robustness of Hue channel when it comes to handling the shadow.

The following code compares the normal RGB image to its own pure Hue image, no Saturation, no Value. Example steps:

  1. Load the image.
  2. Convert it from RGB to HSV.
  3. Copy HSV, and set its Saturation and Value to a constant number 255 (highest number, to ensure that the colors are visible and clear).
hsv_frame = cv2.cvtColor(rgb_frame, cv2.COLOR_RGB2HSV)

hsv_only = hsv_frame.copy()
hsv_only[:, :, 1] = 255 
hsv_only[:, :, 2] = 255

fig, ax = plt.subplots(1, 2)
ax[0].set_title('RGB image')
ax[1].set_title('Hue only image')
ax[1].imshow(cv2.cvtColor(hsv_only, cv2.COLOR_HSV2RGB))

As you can see, Hue channel was able to clearly stress the boundaries of the lemon, additionally, it was able to remove the lighting effects on the lemon itself.

Another observation is that there is some redness around the lemon, to understand the reason, we need to clarify that Hue channel has only colors, no white/gray/black colors, which means that if the image has any portion that is colorless (white, gray, black), then its representation in Hue will be almost random, because the saturation and value are going to destroy the color resulting in the grayish color we see.

Lighting Control in HSV (Histogram equalizer)

Histogram equalizer is a method that converts the distribution of colors in the image into a unified distribution, it targets rebalancing the total count of each bin in the histogram.

In our example, we are going to use it to equalize the Value channel in HSV. Steps:

  1. Extract Value channel.
  2. Equalize its histogram.
  3. Insert the equalized values back to Value channel in the original image.
def equalize(img_hsv):
    pixelsValueChannel = img_hsv[:,:,2]
    plt.imshow(cv2.cvtColor(img_hsv, cv2.COLOR_HSV2RGB))
    new_valuechannel = cv2.equalizeHist(pixelsValueChannel)
    img_hsv_new = img_hsv.copy()
    # adding the new value channel to the image
    img_hsv_new[:,:,2] = new_valuechannel
    plt.imshow(cv2.cvtColor(img_hsv_new, cv2.COLOR_HSV2RGB))


As you can see, the histogram of Value is now close to being uniformly distributed, which resulted in an increase of the brightness of some of the elements in the image. For example, you can see that the lower portion of the lemon is now slightly brighter.

This kind of operation is particularly helpful if you know that the image suffers from strong lighting conditions (too dark or too bright), the equalization will result in an increase in contrast, which generally looks more pleasant.