views:

419

answers:

3

What is the best (result, not performance) algorithm to fetch dominant colors from an image. The algorithm should discard the background of the image.

I know I can build an array of colors and how many they appear in the image, but I need a way to determine what is the background and what is the foreground, and keep only the second (foreground) in mind while read the dominant colors.

The problem is very hard especially for gradient backgrounds or backrounds with patterns (not plain)

+1  A: 

As far as my knowledge of image processing algorithms extends , there is no certain way to get the "foreground"; it is only possible to get the borders between objects. You'll probably have to make do with an average, or your proposed array count method. In that, you'll want to give colours with higher saturation a higher "score" as they're much more prominent.

Aviral Dasgupta
If the foreground was sharp, and the background slightly out of focus, then there's enough information in the raw image to determine the foreground from the background. Having said that, I'm not sure exactly how to do it :)
Drew Noakes
It can be done, but it requires two or more than two stereoscopic images or a depthmap.
Aviral Dasgupta
+1  A: 
Drew Noakes
I know this techniquem but this is not an answer to my question.The simplest method for the above approach is:@product = Product.find(params[:id])@image = Magick::ImageList.new(@product.photo.path)@image = @image.quantize(quantisation_level)
astropanic
@Drew: pixelation like this basically just averages pixels into blocks anyway, so it doesn't really answer this question.
MusiGenesis
@MusiGenesis -- I did point out that it won't find the foreground from the background (first sentence of my answer), however it is an easy and useful means of finding the dominant colours from an image (first sentence of the question.)
Drew Noakes
+2  A: 

I would say this problem is closer to "impossible" than "very hard". The only approach to it that I can think of would be to make the assumption that the background of an image is likely to consist of solid blocks of similar colors, while the foreground is likely to consist of smaller blocks of dissimilar colors.

If this assumption is generally true, then you could scan through the whole image and weight pixels according to how similar or dissimilar they are to neighboring pixels. In other words, if a pixel's neighbors (within some arbitrary radius, perhaps) were all similar colors, you would not incorporate that pixel into the overall estimate. If the neighbors tend to be very different colors, you would weight the pixel heavily, perhaps in proportion to the degree of difference.

This may not work perfectly, but it would definitely at least tend to exclude large swaths of similar colors.

MusiGenesis