A step-by-step tutorial using K-means to extract image color themes | by Viola Mao | Towards Data Science

Many people are struggling when choosing Powerpoint theme colors. We are not color experts and the default color palette has been used in many presentations.
More importantly, we want something that is natural, and comfortable. There are articles about fashion designers using Nature’s color for their inspiration. We could, as well, use the natural color for our data visualizations. Overall, nature’s color scheme always provides the most beautiful color match.
In this article, I will use K-means for the RGB values clustering to find the color themes through nature images.
The process is simple:
1. Detect the image’s RGB
2. Use K-means to find the dominant colors
from matplotlib import image as imgimage = img.imread('./image.jpg')image.shape=>(1466, 2200, 3)
There are multiple ways to detect RGB values in Python. Here we use imread within library matplotlib.
In imread’s view, images are consisted by 3 layers of R, G, B values and imread will return an M*N*3 array with M*N as the image’s size (pixels) and 3 is for the R, G, B three layers.
There are other ways to show the R, G, B channels of this image:
import numpy as npfig, ax = plt.subplots(nrows = 1, ncols=3, figsize=(15,5))for c, ax in zip(range(3), ax):        # initiate a zero matrix with dtype as unit8 as the R,G,B values are between 0 to 255    channel = np.zeros(image.shape, dtype="uint8")        # only allow one color at each time    channel[:, :, c] = image[:, :, c]        # display each channel    ax.imshow(channel)
Below is the output:
Before we apply K-means to find the dominant colors, we need:
Convert the M*N*3 array to 3 one-dimensional lists and put them into a dataframe for further processing.
from scipy.cluster.vq import whitenimport pandas as pd#construct to a dataframe for future data processdf = pd.DataFrame()df['r']=pd.Series(image[:,:,0].flatten())df['g']=pd.Series(image[:,:,1].flatten())df['b']=pd.Series(image[:,:,2].flatten())df.head()
Next, similar to how we process data in the other machine learning projects, the data elements need to be standardized or whiten.
df['r_whiten'] = whiten(df['r'])df['g_whiten'] = whiten(df['g'])df['b_whiten'] = whiten(df['b'])df.head()
We will use kmeans from scipy for the data cluster. Here, we aim to find 5 main colors from that image.
kmeans returns two values cluster_centers and distortions. For our purpose, only cluster_centers value is used.
from scipy.cluster.vq import kmeanscluster_centers, distortion = kmeans(df[['r_whiten', 'g_whiten', 'b_whiten']], 5)cluster_centers=>array([[4.10601113, 4.99663622, 6.11418557],       [1.81266348, 1.5258174 , 1.05002704],       [0.91465102, 1.04919171, 1.13272675],       [2.6160078 , 2.29307316, 1.17989749],       [3.41610131, 3.36236196, 1.84276022]])
The cluster_centers consist of standardized values that will need to restore to the real R, G, B to retrieve the colors.
imshow could show image either within 0 to 1 float or 0 to 255 int. So we use int() to return the integer values for each cluster center.
r_std, g_std, b_std = df[['r', 'g', 'b']].std()colors=[]for color in cluster_centers:    sr, sg, sb = color    colors.append((int(sr*r_std), int(sg*g_std), int(sb*b_std)))plt.imshow([colors])plt.show()colors
In this tutorial, we use matplotlib and scipy to extract theme colors with K-means. Whenever you are bored with the default Powerpoint color palette, try to use this method to find other themes to inspire you :).
Here is the full code.
from scipy.cluster.vq import kmeansimport pandas as pdfrom scipy.cluster.vq import whitenfrom matplotlib import pyplot as pltfrom matplotlib import image as imgimage = img.imread('./image8.jpg')#construct to a dataframe for future data processdf = pd.DataFrame()df['r']=pd.Series(image[:,:,0].flatten())df['g']=pd.Series(image[:,:,1].flatten())df['b']=pd.Series(image[:,:,2].flatten())df['r_whiten'] = whiten(df['r'])df['g_whiten'] = whiten(df['g'])df['b_whiten'] = whiten(df['b'])cluster_centers, distortion = kmeans(df[['r_whiten', 'g_whiten', 'b_whiten']], 5)r_std, g_std, b_std = df[['r', 'g', 'b']].std()colors=[]for color in cluster_centers:    sr, sg, sb = color    colors.append((int(sr*r_std), int(sg*g_std), int(sb*b_std)))plt.imshow([colors])plt.show()
Some other examples for your references:
Seaside
Sunset
I like Machine Learning as I believe it can truly help our daily life. Please connect with me through LinkedIn: