This is much easier using the LAB color space. I wrote an algorithm using the LAB color space several years ago to achieve something similar:<p><a href="http://i.imgur.com/M6Oo6dp.jpg" rel="nofollow">http://i.imgur.com/M6Oo6dp.jpg</a><p>Will open source it soon, perhaps.
There is an improvement that can be made here. There is no attempt to find the brightest colour. If you look at the dark image, the brightest colours (red) stand out over and above the dark colours. Using this knowledge is an illustration technique. Notice how the red stands out on one image, a small blue line on the other?<p>This particular algorythm and others that I've seen don't take this into account. Depending on the image, you could also take into account the lightness and darkness to find the dominant colour however small amounts in the image.
I wrote a small Go tool[1] that extracts a color palette from an image using either median or mean quantizer.<p>The quantizer code[2] is well documented and worth reading if you're looking at doing this in Go.<p>[1] <a href="https://github.com/andrewgleave/color-extract" rel="nofollow">https://github.com/andrewgleave/color-extract</a>
[2] <a href="https://github.com/soniakeys/quant" rel="nofollow">https://github.com/soniakeys/quant</a>
To find k dominant colors using kmeans and then replace all the colors with their closest dominant color, try this -
<a href="http://github.com/krishnanraman/colorquantization" rel="nofollow">http://github.com/krishnanraman/colorquantization</a><p>50 lines of Scala with lots of comments. I threw in some example images as well.
Does the while (1) {...} loop always terminate? I am not entirely sure about it and would like to hear some opinions. What if the first guess is already the best possible solution? Could there be any pictures that cause trouble? I.e. ones that consist of 4 (equally spaced) colors only.
I read the same article as the guy and was also discouraged by using PIL. Python 2 vs Python 3 just makes life hard for people not used to Python. Maybe someone should do something about that.<p>I just went ahead and implemented the code in C++ instead.