Hey folks!! If you are a Harry Potter fan like me, you would know what an Invisibility Cloak is. Yes! It’s the cloak which Harry Potter uses to become invisible. Of course, we all know that an invisibility cloak is not real — it’s all graphics trickery. It is nothing more than color identification and removing the foreground.

So recently I was working on a project using OpenCV which deals with COLOR DETECTION. When I was googling the stuff for the project, I was unable to find an appropriate color identification algorithm. I came across several blogs and pages where cv2.inRange function was used detect colors by creating a mask using pre-determined lower and upper boundaries in the RGB color space.

When I tried to use the masking algorithm, I wondered if there’s another better approach which can help me in the project. You must be wondering why I wondered for another approach?

The limitations which I found in the above approach are:

  1. Accuracy: Accuracy is the most important aspect of a Machine Learning model. Suppose the range of green is lower = [36, 25, 25] and upper = [70, 255,255]. Now if I want to detect light green, then using above approach, I’ll get green as output which is a bit different shade than light green.
  2. Complexity: An efficient algorithm is the one that has least complexity. Using the above approach, I need to cross-check every pair of boundaries for detecting a specific color. This increases the run time of algorithm if the data to be traversed is large.
  3. Also, we need to have the exact range of boundaries for a color, which is very difficult to find.

So, I came across an approach which uses KMeans algorithm to extract color from images. This approach is more accurate, less complex and no data set is required.

In this article, I’ll explain how to use KMeans algorithm to extract colors from images.

Import necessary packages

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
import cv2
from collections import Counter
import os
import argparse

We’ll start by importing the necessary packages which includes cv2, numpy, Counter from collections, argparse, matplotlib and KMeans from sklearn’s sub-package cluster.

Color Detection

class DetectColor:
    def RGB_to_HEX(self,color):
        return "#{:02x}{:02x}{:02x}".format(int(color[0]), int(color[1]), int(color[2]))

    def get_image(self,image_path):
        image = cv2.imread(image_path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        return image

    def get_colors(self,image, number_of_colors, show_chart):
        image = image.reshape(image.shape[0]*image.shape[1], 3)
        
        clf = KMeans(n_clusters = number_of_colors)
        
        labels = clf.fit_predict(image)
        counts = Counter(labels)
        
        # sort to ensure correct color percentage
        counts = dict(sorted(counts.items()))
        center_colors = clf.cluster_centers_
        # We get rgb colors by iterating through the keys
        rgb_colors = [center_colors[i] for i in counts.keys()]
        hex_colors = [self.RGB_to_HEX(rgb_colors[i]) for i in counts.keys()]
        
        if (show_chart):
            plt.figure(figsize = (6, 6))
            plt.pie(counts.values(), labels = hex_colors, colors = hex_colors,wedgeprops={"edgecolor":"0",'linewidth': 1})
        return rgb_colors

After importing packages, we’ll create a class DetectColor that will include all the functions necessary for detecting the color.

  1. RGB_to_HEX(): This function is used to convert RGB to HEX so that you can use hex colors according to your requirements.
  2. get_image(): This method helps in reading an image from the specified path and then changing its color space from BGR to RGB as OpenCV represents images as NumPy arrays in reverse order.
  3. get_colors(): This method helps in extracting the colors from the specified image. It takes three arguments:
    • image: the input image
    • number_of_colors: total colors we want to extract
    • show_chart: Boolean variable that decides to show the pie chart or not

Next, we reshape the image data as KMeans expect a 2-D input.

KMeans algorithm creates clusters based on the supplied count of clusters. Here, it will form clusters of colors. We then fit and predict on the same image to extract the prediction into the variable labels.

Counter is used to get count of all labels. To find the colors, we use clf.cluster_centers_. The rgb_colors iterates over the keys present in count, and then divides each value by 255. We could have directly divided each value by 255 but that would have disrupted the order.

Next, we get the hex colors. As we divided each color by 255 before, we now multiply it by 255 again while finding the colors.

If show_chart is True, we plot a pie chart with each pie chart portion defined using count.values() and labels as hex_colors.

We finally return the rgb_colors which can be used at a later stage.

Testing the code

I’ll use the following image as input to test the code.

if __name__ == "__main__":
    img = 'img.png'
    obj = DetectColor()
    color = obj.get_colors(obj.get_image(img), 8, True)

Now, I’ll create an object of the DetectColor class and I’ll provide an image as input and plot the pie chart for it.

Voila !! You’re done !

Conclusion

In this article, we discussed the methodology to extract colors from an image using KMeans algorithm.

Hope you liked my work. Please feel free to share your thoughts and suggestions.

– Pratiksha Goyal


12 Comments

Tootle · June 5, 2020 at 6:18 am

Thanks so much for the post.Really thank you! Great.

Vinny · June 11, 2020 at 6:48 pm

Thanks! And thanks for sharing your great posts every week!

Dimas · June 15, 2020 at 8:34 am

Thanks so much for the post.Really thank you! Great.

Only best offers cialis buying · June 18, 2020 at 12:16 pm

Thank you for this post. Its very inspiring.https://cialisdiscountsm.com/

Chia · June 25, 2020 at 7:28 am

Thanks! And thanks for sharing your great posts every week!

Buy generic cialis · June 29, 2020 at 6:56 am

Thanks! And thanks for sharing your great posts every week!http://cilapharm.com/

Ankit · July 5, 2020 at 3:39 am

Thank you for this post. Its very inspiring.

Vanshika · July 5, 2020 at 4:05 am

Thank you ever so for you post.Much thanks again.

Viabhav · July 5, 2020 at 4:20 am

Thank you ever so for you post.Much thanks again.

Akshit · July 5, 2020 at 4:29 am

Thanks! And thanks for sharing your great posts every week!

Ben · July 5, 2020 at 4:32 am

Thank you for your blog post.Really thank you! Awesome.

Jenny · July 5, 2020 at 4:36 am

Thank you for this post. Its very inspiring.

Leave a Reply

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

Insert math as
Block
Inline
Additional settings
Formula color
Text color
#333333
Type math using LaTeX
Preview
\({}\)
Nothing to preview
Insert