Using python and k-means to find dominant colors in images
charlesleifer.com
Using python and k-means to find dominant colors in images
1–10 of 34 posts
Re: Using python and k-means to find dominant colors in images
#2Re: Using python and k-means to find dominant colors in images
#3Re: Using python and k-means to find dominant colors in images
#4Re: Using python and k-means to find dominant colors in images
#5Color theme generator for Xresources and more: https://gist.github.com/3946121
Reference to similar features in scipy: http://docs.scipy.org/doc/scipy/reference/cluster.vq.html
Old-school computer graphics w/kmeans: http://pragprog.com/magazines/2011-12/revisiting-graphics-ha...
There was also some discussion on using different color spaces than RGB to get better results, lab*, HSL, YUV, etc. And recommending using something like Numpy to make this shit hum.
Re: Using python and k-means to find dominant colors in images
#6One problem I ran into but never solved was ignoring the background color. For example in the second picture it might be more interesting to bring out the oranges of the tail-lights and the light-blues of the street lights, rather than just the dark blues of the roads. You could ignore the largest cluster, but that's not always necessarily the background color. Have you thought about this at all?
Re: Using python and k-means to find dominant colors in images
#7Re: Using python and k-means to find dominant colors in images
#8Cool, I did something like this for an e-commerce store so that I could programmatically sort new products into color bins. Scipy handled the kmeans stuff for me though. One problem I ran into but never solved was ignoring the background color. For example in the second picture it might be more interesting to bring out the oranges of the tail-lights and the light-blues of the street lights, rather than just the dark…
Re: Using python and k-means to find dominant colors in images
#9Cool, I did something like this for an e-commerce store so that I could programmatically sort new products into color bins. Scipy handled the kmeans stuff for me though. One problem I ran into but never solved was ignoring the background color. For example in the second picture it might be more interesting to bring out the oranges of the tail-lights and the light-blues of the street lights, rather than just the dark…
Either that, or be sure that the background is consistent every time you take the picture for sorting into the color bins. It may be cheaper than trying to create a catch-all solution.
Re: Using python and k-means to find dominant colors in images
#10See the effect here: http://cl.ly/KElb
Here's the Python I use to do it: https://github.com/samuelclay/NewsBlur/blob/master/utils/Ima...
from PIL import Image
import scipy
import scipy.cluster
from pprint import pprint
image = Image.open('logo.png')
NUM_CLUSTERS = 5
# Convert image into array of values for each point.
ar = scipy.misc.fromimage(image)
shape = ar.shape
# Reshape array of values to merge color bands.
if len(shape) > 2:
ar = ar.reshape(scipy.product(shape[:2]), shape[2])
# Get NUM_CLUSTERS worth of centroids.
codes, _ = scipy.cluster.vq.kmeans(ar, NUM_CLUSTERS)
# Pare centroids, removing blacks and whites and shades of really dark and really light.
original_codes = codes
for low, hi in [(60, 200), (35, 230), (10, 250)]:
codes = scipy.array([code for code in codes
if not ((code[0] hi and code[1] > hi and code[2] > hi))])
if not len(codes): codes = original_codes
else: break
# Assign codes (vector quantization). Each vector is compared to the centroids
# and assigned the nearest one.
vecs, _ = scipy.cluster.vq.vq(ar, codes)
# Count occurences of each clustered vector.
counts, bins = scipy.histogram(vecs, len(codes))
# Show colors for each code in its hex value.
colors = [''.join(chr(c) for c in code).encode('hex') for code in codes]
total = scipy.sum(counts)
color_dist = dict(zip(colors, [count/float(total) for count in counts]))
pprint(color_dist)
# Find the most frequent color, based on the counts.
index_max = scipy.argmax(counts)
peak = codes[index_max]
color = ''.join(chr(c) for c in peak).encode('hex')