News for hackers. Stuff that matters.
Re:Using python and k-means to find dominant colors in images by conesus on Wednesday October 24, 2012 @04:30PM (#4694910)
Awesome, I used this technique to find the dominant color in favicons so I could create a gradient in NewsBlur.

See 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] < low and code[1] < low and code[2] < low) or
                                     (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')
Re:Using python and k-means to find dominant colors in images by chuckbot on Thursday October 25, 2012 @01:11AM (#4696461)
I like this solution much better, here is why:

k-means is not a mode seeking algorithm, I think. You are clustering your color space, but you're not even guaranteed to end up with colors that are very close to those in your image. With a high k you're getting actual colors in the image, but they're not really dominant anymore.

What about mean shift? It's based on one method of non-parametric density estimation. Another method is this: Some sort of histogramming, which is another method of non-parametric density estimation.

Also other colors spaces will pay off immensely.

Re:Using python and k-means to find dominant colors in images by eidorb on Thursday October 25, 2012 @04:27AM (#4696793)
I love subtle flairs like this. It's something that a lot of people would only notice if removed and I think that's an indicator of good design.