Page 1 of 2

Common colors?

Posted: 2009-01-08T22:14:40-07:00
by andrewpthorp
Does anyone know how I can take an image and find the most common colors in that image?

We are building something that sets up branding, and when a company uploads their logo, we want to scan the logo and suggest 3 colors to use for their brand, it doesn't have to be perfect, but if it could pick out 3 dominant colors (non white/black) and give the results back, it would be perfect!

any help is greatly appreciated!

Re: Common colors?

Posted: 2009-01-08T22:35:16-07:00
by andrewpthorp
convert logo.jpg -colors 16 -depth 8 -format "%c" histogram:info: | head -n 3 colors.txt

this function seems to do what I want, the only difference is that I want it to get rid of anything white (ffffff, fefefe, fdfdfd, etc) or black (000000, 010101, 020202, etc)

any help!?

Re: Common colors?

Posted: 2009-01-09T20:56:35-07:00
by anthony
If you can figure out roughly how many colors are in an image. do a color quantization to than many colors.

For example 4 major colors...

Code: Select all

   convert image.jpg  +dither -colors 4 -unique-colors txt:-
NOTE however this does not tend to generate 'pure' colors, just the center of color groups.

Re: Common colors?

Posted: 2010-05-24T10:57:07-07:00
by JoaCHIP

Code: Select all

convert logo.jpg -colors 16 -depth 8 -format "%c" histogram:info: | head -n 3 colors.txt
This one keeps the first three colors out of 16. ImageMagick sorts the colors by brightness, so you're throwing away the brighter colors, and not the less common ones.

I wish there were a way to sort colors by how much they're used in the image, rather than brightness?

PS: Reducing to 3 or 4 colors would not give the same result, as much more averaging is done in this case, and the colors become more bland. You can see this one the color patches below (created using different settings in imagemagick):
Image
Notice the red shirt and the corresponding red square (quantizing to 16 colors) below.

Re: Common colors?

Posted: 2010-05-24T12:45:07-07:00
by fmw42
try

convert logo: -colors 16 -depth 8 -format "%c" histogram:info: | sort -r -k 1 | head -n 3 > colors.txt

or to list to terminal

convert logo: -colors 16 -depth 8 -format "%c" histogram:info: | sort -r -k 1 | head -n 3

Re: Common colors?

Posted: 2010-05-24T19:13:58-07:00
by anthony
andrewpthorp wrote:convert logo.jpg -colors 16 -depth 8 -format "%c" histogram:info: | head -n 3 colors.txt

this function seems to do what I want, the only difference is that I want it to get rid of anything white (ffffff, fefefe, fdfdfd, etc) or black (000000, 010101, 020202, etc)

any help!?
You can simplify that by mapping any colors not wanted to a special color such as None,
then using the previously specified technique get the 4 most common colors, then either junk
'None' or the last color.

If you set the setting "-quantize transparent" before applying colors. the color reduction will
ignore transparency.

Re: Common colors?

Posted: 2010-05-24T19:42:58-07:00
by fmw42
Anthony wrote:If you set the setting "-quantize transparent" before applying colors. the color reduction will
ignore transparency.
This is a bit misleading. It does not ignore the transparent colors, but just seems to ignore the transparency and lumps the underlying colors.

# without -quantize transparent
convert logo: -transparent white -colors 16 -depth 8 -format "%c" histogram:info: | sort -r -k 1 | head -n 3
253348: ( 0, 0, 0, 0) #00000000 none
13661: ( 2, 89,164,255) #0259A4 rgba(2,89,164,1)
8410: ( 32, 28, 29,255) #201C1D rgba(32,28,29,1)


# with -quantize transparent
convert logo: -transparent white -quantize transparent -colors 16 -depth 8 -format "%c" histogram:info: | sort -r -k 1 | head -n 3
256632: (213,209,210,255) #D5D1D2 rgba(213,209,210,1)
13527: ( 2, 89,164,255) #0259A4 rgba(2,89,164,1)
7996: ( 32, 28, 29,255) #201C1D rgba(32,28,29,1)


I think what he will need to do is map to transparent and then just filter out "none"

# with grep -v "none"
convert logo: -transparent white -colors 16 -depth 8 -format "%c" histogram:info: | grep -v "none" | sort -r -k 1 | head -n 3
13661: ( 2, 89,164,255) #0259A4 rgba(2,89,164,1)
8410: ( 32, 28, 29,255) #201C1D rgba(32,28,29,1)
5817: (232,229,229,255) #E8E5E5 rgba(232,229,229,1)

Re: Common colors?

Posted: 2010-05-24T20:24:46-07:00
by anthony
He will also need a -fuzz factor to remove the near unwanted colors. EG off-whites and off blacks.

Re: Common colors?

Posted: 2010-05-24T20:57:18-07:00
by fmw42
not clear whether he wants exact or close colors to white and black to be remove? if the latter, then you are correct in pointing that out.

Re: Common colors?

Posted: 2010-05-25T05:03:58-07:00
by JoaCHIP
fmw42 wrote:convert logo: -colors 16 -depth 8 -format "%c" histogram:info: | sort -r -k 1 | head -n 3
Ahh brilliant. I'm pretty sure this solves my problem at least. I'll try this when i get home from work.

Re: Common colors?

Posted: 2010-05-25T09:27:38-07:00
by fmw42
to get rid of white and black (exact colors), you can convert them to transparent and then skip the transparent color in the list as follows

convert logo: -transparent white -colors 16 -depth 8 -format "%c" histogram:info: | grep -v "none" | sort -r -k 1 | head -n 3


see details above in my earlier post

Re: Common colors?

Posted: 2010-07-01T12:22:24-07:00
by GeekNeck
Hi all,
The great Oracle of Google has brought me to this thread, as I am also trying to find dominant colors. I have this image for which I am trying to find the dominant color:

Image

My eye tells me the dominant color is yellow but ImageMagick tells me the dominant color is a subdued brown

Code: Select all

$ convert 20100530_breakfast_steam_002.jpg -colors 16 -depth 8 -format "%c" histogram:info:|sort -rn|head -3
     78023: ( 16, 15, 11) #100F0B rgb(16,15,11)
     33536: ( 79, 40, 26) #4F281A rgb(79,40,26)
     26934: ( 44, 42, 36) #2C2A24 rgb(44,42,36)
Yuck! I know that dark colors are truly what dominates, but that is not what the human eye sees. Does anyone have any suggestions for an alternate method of getting the more subjective dominant color? Thanks in advance for any input!

Re: Common colors?

Posted: 2010-07-01T13:21:18-07:00
by fmw42
mask the image on thresholded graylevel to capture the brightest colors and make everything else transparent, then skip the transparent pixels

Re: Common colors?

Posted: 2010-07-01T15:57:31-07:00
by snibgo
The general problem is complex. If you have a small area of solid brown and a larger area of many slightly different shades of yellow, a simple histogram will find brown as most frequent.

How sophisticated do you want to get? "Subjective dominance":

- yellow > red
- red > green
- light > dark
- saturated > unsaturated
- green > blue

This suggests you need to weight the number of pixels of a colour by where it falls in the hierarchy of subjective dominance.

Not difficult: from the histogram, convert each colour to HLS (or favoured colourspace), apply the weighting, sum appropriately, and there you go.

Re: Subdued brown vs. yellow

Posted: 2010-07-11T05:08:04-07:00
by JoaCHIP
Just a thought on the sideline here: The subdued brown color you mention is probably just yellow in a very dark version, because dark yellow is basically some sort of brown.

I've found out that when comparing colors (like for example searching through a database with images), comparing colors in the HSV color space works much better. The trick is to put different emphasis on the Hue, Sat and Value channels:

Hue: VERY important when comparing.
Saturation: Only somewhat important.
Value / Lightness: Not important at all.

This way searching for "yellow" through a bunch of colors will both react on real yellow and the subdued brown one.