## Find the main color composition of an image based on Python

AI algorithm and image processing 2020-11-16 17:24:47
main color composition image based

If we can know what the most colors in an image are , It can help us solve many practical problems . For example, in the field of agriculture, you want to determine the maturity of fruits , We can check whether the color of the fruit falls within a certain range , To see if they're mature .

Next we will use Python And some common libraries （ for example Numpy,Matplotlib and OpenCV） To solve this problem .

01. preparation

We will load the basic package here . in addition , Because we are going to use Jupyter Programming , So don't forget to add %matplotlib inline command .

The second step ： Load and display the sample image

We're going to show two images side by side , So we need to do an auxiliary function . Next, we'll load some of the sample images we'll use in this tutorial , And use the above functions to display it .

02. Common methods

Method 1 ： Average

The first method is the simplest （ But it doesn't work ） Methods - Just find the average pixel value . Use numpy Of average function , We can easily get the average pixel values on rows and widths -axis=(0,1)

```img_temp = img.copy()
img_temp[:,:,0], img_temp[:,:,1], img_temp[:,:,2] = np.average(img, axis=(0,1))
img_temp_2 = img_2.copy()
img_temp_2[:,:,0], img_temp_2[:,:,1], img_temp_2[:,:,2] = np.average(img_2, axis=(0,1))
show_img_compar(img, img_temp)
show_img_compar(img_2, img_temp_2)```

From the above image, you can see , The average method can produce incorrect results , The most common color it gives may not be the color we want , This is because the average takes into account all pixel values . When we have high contrast images （ An image contains “ light colour ” and “ Dark ”） This problem will be serious at the time . In the second picture , This is more clear . It gives us a new color , The color is not visible in the image at all .

Method 2 ： Highest pixel frequency

The second method will be more accurate than the first . Our job is to calculate the number of times each pixel value appears .numpy It provides us with a function to complete this task . But first of all , We have to adjust the shape of the image data structure , To provide only 3 List of values （ Every R,G and B Channel strength one ）.

We can use numpy Of reshape Function to get a list of pixel values .

Now we have the right structure of data , You can start calculating the frequency of pixel values , Use numpy Medium unique Function .

```img_temp = img.copy()
unique, counts = np.unique(img_temp.reshape(-1, 3), axis=0, return_counts=True)
img_temp[:,:,0], img_temp[:,:,1], img_temp[:,:,2] = unique[np.argmax(counts)]
img_temp_2 = img_2.copy()
unique, counts = np.unique(img_temp_2.reshape(-1, 3), axis=0, return_counts=True)
img_temp_2[:,:,0], img_temp_2[:,:,1], img_temp_2[:,:,2] = unique[np.argmax(counts)]
show_img_compar(img, img_temp)
show_img_compar(img_2, img_temp_2)```

Is it more meaningful than the first one ？ The most common color is the black area . But if we don't just use one of the most common colors , What do you do with more colors ？ Use the same concept , We can use N The most common color . let me put it another way , What do we do with the most common color clusters .

Method 3 ： Use K Mean clustering

We can use famous K Mean clustering clusters color groups together .

```def palette(clusters):
width=300
palette = np.zeros((50, width, 3), np.uint8)
steps = width/clusters.cluster_centers_.shape[0]
for idx, centers in enumerate(clusters.cluster_centers_):
palette[:, int(idx*steps):(int((idx+1)*steps)), :] = centers
return palette
clt_1 = clt.fit(img.reshape(-1, 3))
show_img_compar(img, palette(clt_1))
clt_2 = clt.fit(img_2.reshape(-1, 3))
show_img_compar(img_2, palette(clt_2))```

Easy ！ Now? , What we need is a function that displays the color clusters above and displays them immediately . We just need to create a height of 50, Width is 300 Pixel images to display color groups / palette . For each color cluster , We assign it to our palette .

Isn't it beautiful ？ In terms of the most common colors in an image ,K The mean clustering gives excellent results . In the second image , We can see too many shades of brown in the palette . It's probably because we've chosen too many clusters . Let's see if we can choose the smaller k Value to fix it .

```def palette(clusters):
width=300
palette = np.zeros((50, width, 3), np.uint8)
steps = width/clusters.cluster_centers_.shape[0]
for idx, centers in enumerate(clusters.cluster_centers_):
palette[:, int(idx*steps):(int((idx+1)*steps)), :] = centers
return palette
clt_3 = KMeans(n_clusters=3)
clt_3.fit(img_2.reshape(-1, 3))
show_img_compar(img_2, palette(clt_3))```

Because we use K Mean clustering , So we still have to determine the appropriate number of clusters ourselves . Three clusters seem to be a good choice . But we can still improve these results , And still can solve the cluster problem . How do we also show the percentage of clusters in the whole image ？

Method four ：K mean value + The scale shows

What we need to do is modify our palette function . Instead of using fixed steps , We change the width of each cluster to be proportional to the number of pixels in that cluster .

```from collections import Counter
def palette_perc(k_cluster):
width = 300
palette = np.zeros((50, width, 3), np.uint8)
n_pixels = len(k_cluster.labels_)
counter = Counter(k_cluster.labels_) # count how many pixels per cluster
perc = {}
for i in counter:
perc[i] = np.round(counter[i]/n_pixels, 2)
perc = dict(sorted(perc.items()))
#for logging purposes
print(perc)
print(k_cluster.cluster_centers_)
step = 0
for idx, centers in enumerate(k_cluster.cluster_centers_):
palette[:, step:int(step + perc[idx]*width+1), :] = centers
step += int(perc[idx]*width+1)
return palette
clt_1 = clt.fit(img.reshape(-1, 3))
show_img_compar(img, palette_perc(clt_1))
clt_2 = clt.fit(img_2.reshape(-1, 3))
show_img_compar(img_2, palette_perc(clt_2))```

It not only provides us with the most common colors in images . It also gives us the proportion of each pixel that appears .

03. Conclusion

We introduced several uses Python And the best-known library to capture the most common colors in images . in addition , We also see the advantages and disadvantages of these technologies . up to now , Use k> 1 Of K Mean finding the most common colors is one of the best solutions to finding the most frequent colors in an image .