Finding the dominant colours in an image could be useful for a number of creative applications, however, more importantly it’s a fun learning exercise. Adobe Capture (iOS, Google Play)’s ‘colors’ feature is a good example the output of this guide:
Also please make sure to follow the supermodel who’s image I’m using to demonstrate these concepts: @neonandlynx
There are various methods of extracting an image’s dominant colours, I will focus on using the k-Means algorithm for this guide. I will also discuss processing steps to speed up the execution time and use a webcam feed to extract dominant colours in real time. Let’s have a look at the processing.
The most straightforward method of doing this would be to use each pixel of the image as input to a k-Means model. For a 2 megapixel image, this would result in 5,760,000 inputs to the algorithm (i.e. 1600w x 1200h x 3c). In order to increase the processing speed the number of data points need to be reduced.
The method proposed will take advantage of the fact that an image is stored as a width x height (h) x channel (c) matrix and NumPy’s vectorized functions.
- Firstly, the image will be broken on the w and h axis in (roughly) even squares. This will result in n number of w x h x c matrices.
Note: The number of these squares will have the most influence on performance, more squares = more accurate, more processing, less FPS.
- Each individual square will then have its w and h axis averaged. This will result in n number of 1 x 1 x 3 matrices.
Note: By averaging the image data there is a loss of accuracy in the final output as the averaged colour may not even be present in the original image. However this method is much faster than using the full set of pixel values and provides a ‘good enough’ output.
- As a 1 x 1 x 3 matrix only has 3 values, 1 dimension from the matrix will be removed. this results in n number of 1 x 3 matrices, or the colour value for n number of pixels.
Following the proposed method, the image presented in Figure 2, results in 105 datapoints (35 pixels, 0.001% of original size).
The resulting pixels will then be fed to a k-means model and fit to k clusters. K-means will identify the average colour data for each cluster (cluster centroids), this will be the output of the process.
Most of the code will only use numpy and pandas functions to take advantage of broadcasting and vectorized functions, OpenCV is only used to get the webcam feed.
The code is available here: https://github.com/thezaza101/Python-Code-Snippets/blob/master/other/p/Snipppets/ExtractDominantColours.py