Colors From Image

Colors From Image finds the dominant color palette from an image. Often times when I see beautiful flowers I wonder what color palette they have. On a recent walk with my dog I saw a pink and orange plumeria in full bloom. I got the idea to make a Python program that would analyze the colors from an image and return the palette and hex codes.

synth style color palette

The Process:

First, I had to figure out how to process an image and get the dominant colors from it. I knew I wanted to use Python and both of these articles used something called K-Means Clustering, an unsupervised machine learning algorithm, to find the dominant colors from an image.

  1. OpenCV and Python K-Means Color Clustering
  2. Color palette extraction with K-means clustering | Machine Learning from Scratch (Part IV)

Venelin Valkov in the second article explains how the algorithm works:

Let’s say you have some vector X that contains n data points. Running our algorithm consists of the following steps:

  1. Take random k points (called centroids) from X
  2. Assign every point to the closest centroid. The newly formed bunch of points is called cluster.
  3. For each cluster, find new centroid by calculating a new center from the points
  4. Repeat steps 2-3 until centroids stop changing

This image from Stack Overflow illustrates the process.

k-means clustering visual

I decided to use Scikit-learn’s KMeans function to analyze the image and group the colors into clusters. I wanted to show the dominant colors from left to right, which required some sorting of arrays and lists after the KMeans function ran. I output an equal percentage version and a weighted version and saved them as .png files.

equal parts color palette

weighted color palette

The weighted version shows that the image is about 45% dark purple and only 5% lavender. While this was neat, I didn’t include the weighted output in the final web version.

Once I was able to get the colors from an image locally, I created a new Django project to easily handle all the nuances of the web. The user uploads a valid image and chooses the number of colors between 3 and 7 using a select. I used the default SQLite database because I wasn’t going to do anything fancy with the database. I only needed it so I could save the image a user uploaded and then run the KMeans function on it. I used opencv-python to analyze the uploaded image, which needed the file saved on the server before it could run on the image. To help with performance I did a few things:

  1. Prevented images over 2MB. This was mostly because I didn’t want to store big files on the server.
  2. Downsized the image that KMeans ran on if the image was over a certain KB size. There are a few different breakpoints that get larger images down to about 250 x 250 pixels when they are run through the algorithm. A 1MB image without the downsize took 50 seconds to process the 3000 x 2500 pixels, but only 2 or 3 seconds to process after being downsized.

Once the algorithm finishes, it writes over the existing file in /media/outputs/color-palette.png and displays that file to the user along with the original image and hex codes. If this was a larger scale project I would have a new png be saved after each output, and then perhaps run a cron job to delete all the outputs every night to save storage space. But because this is a smaller project, using a single file that is displayed immediately back to the user works well.

The focus of this project was functionality. I used default Bootstrap styling and made sure the outputs collapsed nicely on mobile.

I deployed the project on Digital Ocean with the help of this guide.

jurassic park style color palette

flower style color palette