dominant images

Dominant Colors in an Image using Python

Dominant Colors in an Image using KMeans Clustering

An Image is a multi-dimensional array consisting of three channels i.e., RGB. This array ranges from 0-255, where 0 represents black and 255- white. In the article we shall implement KMeans Clustering Algorithm to find out the dominant colors in an Image.

Sample Image:

best relaxing anime march_comes_in_like_lion

KMeans Clustering

Machine Learning is mainly classified into three types: Supervised Learning, Unsupervised Learning, and Reinforcement Learning. KMeans Clustering is one of the Unsupervised Learning Algorithm. The K in KMeans is a Hyperparameter that represents the number of clusters we’re trying to identify. A cluster refers to a collection of data points which shows similar relation. In KMeans Clustering algorithm, we define K value, and then the algorithm identify k number of centroids, and then allocates a data point to its nearest cluster.

We shall look into KMeans in detail in the ongoing #100DayofML Blog series, and all source code are available on GitHub.

Approach 1: Simple KMeans Clustering Implementation

Using KMeans Clustering Algoritm we shall find the similar color and cluster it. The maximum dominated color can easily be identified by observing the centorid centers.

We shall begin by importing the required modules.

import cv2
from sklearn.cluster import KMeans

To implement KMeans Clustering we need to assign a k value i.e., cluster value. You can give any k value, say 5. When k is 5, the algorithm will detect the top 5 dominating colors in the image. If k is 3, three dominating colors, and so on.

#In this example we will detect the top 3 dominating colors in image

k = 3

Read the input image using cv2.imread

img = cv2.imread('Pictures/march_comes_in_like_lion.webp')
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.axis("off")

Using the plt.imshow display the image.

We can’t fit a 3D image to our KMeans, if you fit a 3D image, you will end up with a ValueError.

ValueError: Found array with dim 3. KMeans expected <= 2.

So let’s flatten the image into 2D with 3 channels.

img = img.reshape((img.shape[0] * img.shape[1], 3))

Create an instance of KMeans clustering using the Sklearn library and assign a k parameter.

kmeans = KMeans(n_clusters = k)
kmeans.fit(img)
COLORS = kmeans.cluster_centers_
COLORS = COLORS.astype(int)

Now we have array size of k color that are dominated colors in the color.

plt.figure(figsize=(10,20))
for domColor in range(k):
    plt.subplot(1,k,domColor+1)
    plt.imshow([[COLORS[domColor]]])
    plt.axis("off")

Putting All Together: Dominant Colors in Image Using KMeans Clustering

import cv2
from sklearn.cluster import KMeans

img_path = "<add_your_image_path>"
img = cv2.imread(img_path)
k = 3

img = img.reshape((img.shape[0] * img.shape[1], 3))


kmeans = KMeans(n_clusters = k)
kmeans.fit(img)

COLORS = kmeans.cluster_centers_
COLORS = COLORS.astype(int)

plt.figure(figsize=(10,20))
for domColor in range(k):
    plt.subplot(1,k,domColor+1)
    plt.imshow([[COLORS[domColor]]])
    plt.axis("off")

Output:

dominant colors in image

Yes, we did it. This is it for approach one. Lets look at another approach:

Kickstart with 100 Days Of Machine Learning Challenge

Approach 2: Using cv2 to detect proportations of dominant colors in an Image

In this approach we shall look how spread out are the dominant colors in an image. We shall use the same code from above.

First let use check the proportion of the colors.

distributionImage = (np.unique(kmeans.labels_,return_counts=True)[1])
distributionImage = distributionImage/img.shape[0]
distributionImage

Now zip the distributed data with its associated color.

pixelColors = zip(distributionImage,COLORS)
pixelColors = sorted(pixelColors)[::-1]

Output:

[(0.40172815755579827, array([232, 226, 212])),
 (0.3446207020232486, array([70, 63, 63])),
 (0.2536511404209531, array([152, 147, 142]))]

As you can observe the first index is the proportion of the color and the second index is the array representing a color.

fill = np.zeros((175,450,3),dtype="int")
start = 0
i = 1
for pixels,color in pixelColors:
    end = start+int(pixels*fill.shape[1])
    if i==k: #if there is only one dominant color
        fill[:,start:] = color[::-1]
    else:
        fill[:,start:end] = color[::-1]
    start = end
    i+=1

plt.title("Dominant Color In An Image")
plt.imshow(fill)
plt.axis("off")

Putting All together

import numpy as np


import cv2
from sklearn.cluster import KMeans

img_path = "<add_your_image_path>"
img = cv2.imread(img_path)
k = 3

img = img.reshape((img.shape[0] * img.shape[1], 3))


kmeans = KMeans(n_clusters = k)
kmeans.fit(img)

COLORS = kmeans.cluster_centers_
COLORS = COLORS.astype(int)

distributionImage = (np.unique(kmeans.labels_,return_counts=True)[1])
distributionImage = distributionImage/img.shape[0]
distributionImage

pixelColors = zip(distributionImage,COLORS)
pixelColors = sorted(pixelColors)[::-1]

fill = np.zeros((175,450,3),dtype="int")
start = 0
i = 1
for pixels,color in pixelColors:
    end = start+int(pixels*fill.shape[1])
    if i==k: #if there is only one dominant color
        fill[:,start:] = color[::-1]
    else:
        fill[:,start:end] = color[::-1]
    start = end
    i+=1

plt.title("Dominant Color In An Image")
plt.imshow(fill)
plt.axis("off")
Reference: https://machinelearningprojects.net/most-dominant-colors-in-an-image/

Self-Promotion

Join our Discord Server and become a part of the Anime Vyuh Community. We share content on 100DaysOfCodeAnime ReviewOne Piece Theory, and Character Analysis articles.

Subscribe to our Newsletter to never miss out on the content: https://animevyuh.org/newsletter. Join our Newsletter now for fantastic Anime recommendationsPython, and Machine Learning Content.

Support Us: https://www.buymeacoffee.com/trjtarunhttps://ko-fi.com/tarunrjain751.
GitHub: https://github.com/lucifertrj.
Twitter: https://twitter.com/TRJ_0751.

Want to learn Machine Learning with Proper Roadmap and resources? Then check this Repository: https://github.com/lucifertrj/100DaysOfML