7

I have about 3000 images and 13 different colors (the background of the majority of these images is white). If the main color of an image is one of those 13 different colors, I'd like them to be associated.

I've seen similar questions like Image color detection using python that ask for an average color algorithm. I've pretty much copied that code, using the Python Image Library and histograms, and gotten it to work - but I find that it's not too reliable for determining main colors.

Any ideas? Or libraries that could address this?

Thanks in advance!

:EDIT: Thanks guys - you all pretty much said the same thing, to create "buckets" and increase the bucket count with each nearest pixel of the image. I seem to be getting a lot of images returning "White" or "Beige," which is also the background on most of these images. Is there a way to work around or ignore the background?

Thanks again.

Community
  • 1
  • 1
dchang
  • 2,440
  • 4
  • 24
  • 27

3 Answers3

11

You can use the getcolors function to get a list of all colors in the image. It returns a list of tuples in the form:

(N, COLOR)

where N is the number of times the color COLOR occurs in the image. To get the maximum occurring color, you can pass the list to the max function:

>>> from PIL import Image
>>> im = Image.open("test.jpg")
>>> max(im.getcolors(im.size[0]*im.size[1]))
(183, (255, 79, 79))

Note that I passed im.size[0]*im.size[1] to the getcolors function because that is the maximum maxcolors value (see the docs for details).

jterrace
  • 64,866
  • 22
  • 157
  • 202
2

Personally I would split the color space into 8-16 main colors, then for each pixel I'd increment the closest colored bucket by one. At the end the color of the bucket with the highest amount of pixels wins.

Basically, think median instead of average. You only really care about the colors in the image, whereas averaging colors usually gives you a whole new color.

Blindy
  • 65,249
  • 10
  • 91
  • 131
1

Since you're trying to match a small number of preexisting colors, you can try a different approach. Test each image against all of the colors, and see which one is the closest match.

As for doing the match, I'd start by resizing each image to a smaller size to reduce the amount of work you'll be doing for each; our perception of the color of an image isn't too dependent on the amount of detail. For each pixel of the smaller image, find which of the 13 colors is the closest. If it's within some threshold, bump a counter for that color. At the end whichever of the 13 has the highest count is the winner.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622