We already have RGB so why we need HSV ?

In image processing we often use HSV model over the RGB model, but what actually lag behind by RGB so that we need the HSV model. for these let’s understand the models and then we code some program to view it practically.

RGB model is basically a blend of three colors, Red Green & Blue, every color in this model is the combination of these three colors, we all are familier with it

While HSV is the blend of Hue, Saturation & Value (Brightness).

  • Hue is the Absolute color
  • Saturation is like mixing of white color and
  • Value is the illumination or brightness,

let’s see and example.

Here we have a Rubik’s cube we can clearly see there are two shades of yellow. Right and left, right one is in little dark while left one is in light.

From the human perspective, we know both are yellow and the difference is of illumination or brightness but for the RGB model, it’s a different color or a different blend of Red Green and Blue with no relation to each other.

While the HSV model is closed to human perspective and can sense the color is same and the difference is in light. which helps us in color recognition in an image much easier, there are many instance where color changes due to shadow, but is actually a same color.

So lets see how both model looks

RGB Model

RGB Model

As we can see there are only three main colors which hasa absolute value. 

  • Red (255,0,0)
  • Green (0,255,0)
  • Blue (0,0,255)

ny color can made up using the mixing of these three colors.

This is the widely used model in color selecting because even change in a single value can change the entire color,

So it gives us leverage to select from n number of colors. but this boon becomes a bane when we need to recognize the color. because it coded every pixel and if it senses any slight change in the color it changes the color code which makes it difficult to recognize the color of an object as whole

HSV Model

HSV Model

This model is versatile in nature, it contains the absolute value for each prime color just like three color in RGB, here I meant with prime is the brightest shade of that color which we call a Hue

As you can see in the model the hue is the top most disc of color, the numbering start from the red and moving anticlockwise and complete the 360 deg circle to the red itself. 

The saturation is like the mixing of white into it, the more the value the less white mixed in the shade, and when the saturation becomes zero in any color, it becomes white. 

Similarly, the ‘Value’ in HSV denote how bright light the color is. The more the value, the bright is the shade and in the same ways if its zero then color become black

Now lets talk about the range of values

As in the RGB model the value lies between (0-255)

In HSV model

  • Hue ranges from (0-360)
  • Saturation ranges from (0-100) and
  • Value(Brightness) ranges from (0-100)

But for python the values become different.

ince in python we use numpy array and uint8 datatype to define these color coding and it has a range of (0-255), So we try to maintain the color coding values in the range of 0-255, thus values changes by

  • Hue ranges from (0-179), approximately the half 
  • Saturation ranges from (0-255) and
  • Value ranges from (0-255)
Hue Range

In python, we use OpenCV to recognize color in an image, to do so we need to define the lowest value and the highest value in which the color can vary. Then the OpenCV will separate the colors which lie in that range from any other color and provides a mask.

Theory part ends here, let’s make some program to understand it better.

Our approach will be to take out the yellow color from the Rubik’s cube image.

The main logic behind the program is to give a range from lower value to the upper value in which color should lie. and if the program detects any color in the given range the that color would be seperated out from the rest

So lets make the program

import cv2
import numpy as np

img= cv2.imread('rubix.png') #BGR


#converting the image formats
img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
img_hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)


#Defining the windows
cv2.namedWindow('mask RGB',cv2.WINDOW_NORMAL)
cv2.namedWindow('mask HSV',cv2.WINDOW_NORMAL)


#resizing the windows
cv2.resizeWindow('mask RGB',(500,500))
cv2.resizeWindow('mask HSV',(500,500))

#Lower& Higher Values of RGB
lower_rgb=np.array([ ]) #Value to add later
upper_rgb=np.array([ ]) #Value to add later

#Lower& Higher Values of HSV
lower_hsv=np.array([ ]) #Value to add later
upper_hsv=np.array([ ]) #Value to add later

#making Mask
mask_rgb=cv2.inRange(img_rgb,lower_rgb,upper_rgb)
mask_hsv=cv2.inRange(img_hsv,lower_hsv,upper_hsv)

#using Bitwise And operation on image and mask
res_rgb=cv2.bitwise_and(img,img,mask=mask_rgb)
res_hsv=cv2.bitwise_and(img,img,mask=mask_hsv)

#showing the mask
cv2.imshow('mask RGB',mask_rgb)
cv2.imshow('mask HSV',mask_hsv)


#saving images
cv2.imwrite('mask_rgb.png',mask_rgb)
cv2.imwrite('mask_hsv.png',mask_hsv)
cv2.imwrite('res_rgb.png',res_rgb)
cv2.imwrite('res_hsv.png',res_hsv)

cv2.waitKey(0)
cv2.destroyAllWindows()

Here we are ready to rumble, we just have to put the values of lower and upper, 

Since RGB model is not meant for the image processing so we dont have any fair idea about how to select the lower and upper values. Lets take the dark side value as the lower one and bright side value as the upper one

As we can see the darker value is R:137, G:119, B:0 and the brighter one is R:233, G:214, B:0

Lets put these value in RGB range

  • lower_rgb=np.array([137,119,0])
  • upper_rgb=np.array([233,214,0])

For HSV the value classification is much easier. we know the range of colors from above chart. So the range of hue for yellow color lies between somewhere 20-40

Hue Value for Yellow

so lower value for hue become 20 and upper value for hue become 40

Lets saturation lower value take as 140 and upper as 255

Now the Value or brightness value is important and it is changing the color significantly. so lets take the range from 100-255

Lets put these value in RGB range

  • lower_hsv=np.array([20,140,100])
  • upper_hsv=np.array([40,255,255])

After putting these values in the program we get the following output

As we can see we are not getting any result from the RGB model.

We toggle some more value for RGB but we didn’t get anything. On the other hand, we get a beautiful response from HSV model in the very first attempt.

With HSV, the value selection is understandable. We know which factor is responsible for which purpose and we can change the range accordingly.

Lets take another example and this time we try to take out blue color from the image

For RGB we are again taking the darker and brighter shade of Blue for lower and upper value respectivelly

so for RGB model we get the values i.e

  • lower_rgb=np.array([20,20,54])
  • upper_rgb=np.array([33,33,135])

For HSV model

The range of blue color lies somewhere between 95 to 135. so we get our lower and higher value for hue. lets take the saturation between 120 to 255.

This time we need to push brightness value much more because the darker side of blue is nearly to black. so we will take between 30-255

For RGB model we get the values i.e

  • lower_hsv=np.array([95,120,30])
  • upper_hsv=np.array([135,255,255])

Lets put these values in the program and see what happens

Unlike the yellow color we got some blue color by the RGB model but still, nothing compared to HSV model.

So to conclude this we can say that RGB model is best for color picking but worst for color recognizing in an image. 

In the real world scenario there are many instances where the color is changed due to some exposure of light or shadow, and to detect that we need a model which can relate to human perception thus HSV model is required.

Thanks for reading

Leave a Reply

Your email address will not be published. Required fields are marked *