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
First step : Add package
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 .
Code link :https://github.com/mrakelinggar/data-stuffs/tree/master/frequent_color
This article is from WeChat official account. - AI Algorithm and image processing (AI_study) , author : Nuby
The source and reprint of the original text are detailed in the text , If there is any infringement , Please contact the [email protected] Delete .
Original publication time : 2020-11-09
Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .