Getting the predominant colour in an image?

13,090

Solution 1

Imagemagick's identify -verbose provides a palette histogram table, but only if the number of unique colors is below a limit (1024 in the versions I've checked, v6.x up to v6.8.3).

Instead you can just "convert" your image to a histogram, this output is not limited by number of unique colors:

convert image.jpg  -format %c -depth 8  histogram:info:histogram_image.txt
sort -n histogram_image.txt | tail -1

Sorting the output numerically by the first column sorts by frequency of pixel colors. (Frequency of specific colour pixels might not correspond to a human perception of predominant color of course.)

If you're reducing colors, you can probably just trust convert to do it for you by your choice of dithering and/or posterizing. Even specifically to the web-safe 216:

convert image.png  +dither -remap netscape:  image_websafe.png

You would probably get closer to a perceived predominant color by some combination of blurring, resizing and posterizing, this is not a simple problem to define and solve:


See also the following link for dcolors, a script which uses Imagemagick to determine a set of predominant colors in an image, uses include coordinating your desktop color scheme with your chosen desktop image: http://javier.io/blog/en/2015/09/30/using-imagemagick-and-kmeans-to-find-dominant-colors-in-images.html

Solution 2

I found this elegant and short answer here http://blog.endpoint.com/2011/04/determining-dominant-image-color.html

$ convert Waffle.jpg -scale 1x1\! -format '%[pixel:u]' info:-
rgb(219,166,94)
Share:
13,090

Related videos on Youtube

Richard
Author by

Richard

Updated on September 18, 2022

Comments

  • Richard
    Richard almost 2 years

    Is it possible to get the predominant colour in an image from the command line? Ideally I'd like it back as hex or RGB.

    I thought it might be possible to do this with imagemagick's identify command, but I couldn't see an option for doing this in the documentation.

    • gronostaj
      gronostaj about 11 years
      Could you be more specific about what is a predominant color for you? 24-bit RGB pixel has 16777216 possible color values and I doubt if finding the most repeating one is useful in any way.
    • Richard
      Richard about 11 years
      I'd like to narrow it down to a fairly small number of colours... I'm no expert on colours, but the sixteen HTML safe colours or the X11 colour names would be ideal. I guess this would need some kind of process like (i) reduce the colour space of the image (ii) create a table of pixels by colour (iii) map the dominant colour to the closest colour name. No idea how to do any of that, though!
  • Richard
    Richard about 11 years
    Thanks - great answer and the first two commands actually work pretty well! One final question: what do you think is the best way to map the predominant hex value to the nearest websafe value? Is this just a question of hex arithmetic or is there a more sophisticated way?
  • mr.spuratic
    mr.spuratic about 11 years
    Given the palette is so limited, treating (R,G,B) as a 3d space and finding the minimal Euclidean distance to a defined colour would probably suffice for most purposes. You can get convert to do this for you by adding -remap netscape: after -depth 8 in the first command above.
  • Buzut
    Buzut over 5 years
    It doesn't work any more
  • Michael
    Michael almost 4 years
    it might work better to convert to the HSV colour space, then only consider the "H" portion in the histogram. Is this possible with IM?
  • mr.spuratic
    mr.spuratic almost 4 years
    You can add "-colorspace HSV" before -format in the first example to show HSV instead of sRGB in the histogram output, but you will need to process the hsv() values separately I think. If you use -modulate 0,0,100 to perform a transform in HSL or HSV, you get a zero hue too, per-spec. Perhaps something smarter using -fx or -color-matrix could work, but that's beyond me today...
  • ivan866
    ivan866 over 3 years
    on windows, this should be run through Cygwin