Colour Filtering and Colour Pop Effects using OpenCV Python

Maximinusjoshus
featurepreneur
Published in
6 min readApr 27, 2021

Have you ever thought of separating a single hue of colour from an image? This article walks you through the process of filtering specific colours from a regular RGB image using OpenCV python. So let’s get started.

Photo by Robert Katzki on Unsplash

Hue:

Before starting to filter colours, it is good to have a basic understanding of what hue is. This is one of the definitions of hue from wikipedia

In color theory, hue is one of the main properties (called color appearance parameters) of a color, defined technically in the CIECAM02 model as “The degree to which a stimulus can be described as similar to or different from stimuli that are described as red, orange, yellow, green, blue, purple,” which in certain theories of color vision are called unique hues.

Yeah, I know this might sound agonizing to understand but let me break this down for you. The word “stimulus” in this context means the light that reaches our eye when we see an object. Now let me rephrase the definition. All the colours that we see, can be interpreted as a variant of the colours: red, orange, yellow, green, blue, purple, which are known as unique hues in certain theories of colour vision. To summarize, hue is the purest form of the primary as well as the secondary colours. Generally, hue is measured in 360 degrees of a colour circle, but in OpenCV the hue scale is only 180 degrees.

HSV (Hue, Saturation, Value):

Just like the most common colour spaces we use to represent an image like RGB and BGR, HSV too is a colour space in which H denotes hue, S denotes Saturation and V denotes value. As we already know what hue is let us see about saturation and value

Saturation:

Saturation gives the purity of a colour. A pure colour has no gray mixed in it. Greater the amount of gray mixed in a colour, lesser the saturation. The saturation value is usually measured from 0 to 100% but in OpenCV the scale for saturation is from 0 to 255.

Value:

This is a measure of the brightness of a colour. When the brightness value is maximum, the colour turns white and when the brightness value is minimum, the colour turns black. This is usually measured from 0 to 100% but in OpenCV the scale for value is from 0 to 255.

Now let us get out hands dirty with some real action.

Filtering colours:

To filter a colour using OpenCV, we have to specify the hue range of the colour, we need to filter, and create a mask for the colour. And then perform bitwise AND operation between the original image arrays (which is discussed in detail in this article) using the mask to get the filtered colour as the result.

Let us try to filter green colour from the image below:

Photo by Sharon Pittaway on Unsplash

The code to filter green colour from the above image is:

The results of the above code snippet are:

HSV image
mask(left) and final image with only green colour(right)

Creating Colour Pop Effects using the concept of Colour Filtering:

So now as we know how to create colour filters, let us see how to create colour pop effects using OpenCV. Let us use the image below to demonstrate this.

The process flow to create a red colour pop filter is as follows:

  1. Read the image and convert it to the HSV format.
  2. Set the lower and upper bounds for the HSV of the red colour you are going to filter. One way to find the HSV colour space values of a colour is to run the following code snippet.
img = np.uint8([[[0,0,255]]])
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
print(hsv)

OpenCV reads images in BGR format, and that’s why red colour is [0, 0, 255]. The above code snippet prints:

[[[  0 255 255]]]

which is the HSV value of red colour(hue- 0, saturation- 255(100%), value- 255(100%). You can also do the same for a specific pixel in an image, to find the HSV value of that pixel.

pixel = img[3124, 2342]
hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV)
print(hsv)

As we know the HSV value of the colour we are trying to filter now, we can set the upper and lower bounds by adjusting the hue, saturation and value values separately according to our needs.

3. Create a mask for red hue using inRange function of OpenCV.

4. Create an inverse of the mask using the bitwise_not operation on the mask.

5. Filter only the red coloured portion of the original image using the mask(foreground).

6. Obtain the grayscale format of the original image using cv.cvtColor function.

7. Now use the inverse of the mask to filter only the regions containing colours other than red in the original image, from the grayscale image(background).

8. Before adding the background to the foreground, you have to convert the grayscale background image which has only one channel to a three channel grayscale image using numpy.stack() function. This step should be done because OpenCV’s add function works only if both the images to be added are of the same shape.

9. Add the foreground and the background to get the final image with only the red color popping out from a grayscale background.

The code to create the red colour pop filter is:

Now let us look at the results:

grayscale image(left) and HSV image(right)
mask(left) and mask inverse(right)
background(left) and foreground(right)

Now, it’s time for the most awaited final result! Presenting you the added final image.

As you can see we have got some stunningly astonishing results. We have successfully separated the red colour from the image and turned the remaining image to grayscale which has brought us this master piece of defined aestheticism. And that’s it, congratulations, you have created your own color pop filter using OpenCV! Now you can make yourself comfortable, and try filtering colours other than red on your own.

I have made a simple kivy user interface for the code and it is here. Clone the repo and try it for yourself!

Thank you.

--

--