Color Quantization
May 20, 2024
To inaugurate this blog, I'd like to present a simple article involving a topic I've spent many months studying: clustering. While the application to color quantization is not complicated, it will serve as an excuse to show off the fancy formatting and data visualization tools I've included in this site.
Let's inspect the following image:
If you were asked to list the prominent colors in this image, how would you respond? At a minimum, I would identify:
- Green (background foliage)
- Light Violet (flower petals)
- Yellow (flower centers)
Fundamentally, this image is an array of pixels. The color of each pixel is described by a combination of three integers, each in the range 0-255. You know this as RGB color encoding. Pure black is encoded as (0,0,0) and pure white as (255,255,255).
Knowing this, we can determine the number of unique colors in this image by counting the number of unique RGB triplets:
This reports 665,000 pixels with 141,862 unique colors. More than you thought, right? What if we were operating under strict storage/bandwidth limitations? Could we devise a simple compression technique to reduce the size of this image while maintaining the original resolution? You already employed a clever strategy at the beginning of this article: reduce the diverse color space to a handful of prominent representative colors.
K-Means Clustering
How can we algorithmically identify the most faithful representatives of our color space? A simple solution is K-Means clustering. We start by choosing the number of colors to appear in our compressed image, n. We randomly cast out n points, called centroids, into the color space. Then, we repeatedly run the following two steps to guide the centroids to popular pockets of the space:
- Assign each point (pixel) to the nearest centroid.
- Move each centroid to the mean position of the points that are currently assigned to it.
The animation below shows three centroids gravitating to three natural clusters with this simple logic:
Let's give this a try on our image. We configure K-Means with 3 centroids and iterate until convergence. We then replace the color of each pixel with the color of the nearest centroid:
A pale imitation. What happened here? We can visualize the final positions of the centroids in the color space to better understand this result:
Drag to rotate and scroll to zoom. Use the legend on the right to disable the pixel markers and reveal the obscured centroids.
With only 3 centroids, it appears that some regions are left without a close representative. Light violet and dark green are well-served, but notice the empty pocket of yellow. What if we try again with 10 centroids?
Much better. Additional centroids will yield diminishing returns, so let's call this a victory.
Attributions
Brachyscome iberidifolia by David Stang, licensed under CC BY-SA 4.0.
Source: Wikimedia Commons
Modifications: Cropped and resizedK-means convergence by Chire, licensed under GNU Free Documentation License.
Source: Wikimedia Commons