Extract main colors from image

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
YayBjorn
Posts: 4
Joined: 2010-10-11T05:57:00-07:00
Authentication code: 8675308

Extract main colors from image

Post by YayBjorn »

Hi

I need to extract colorinfomation from images. I know I can resize an image to a 1x1 pixel and get the "average-color" of the image, but this is not sufficient. Sometimes an image consist of too, three or more major colors, and the average does not tell me much.

What I need is an algorithm where I can ask "does this image contain x percentage of colors in a certain color-range". I plan to have 12 "categories" of colors. Each category will be a "color-range". For each image I analyse I want to set a boolean value identifying if the image has enough of that color or not.

This way I can later search for stuff like this:
"red and black"
"pink"
"white and green not red"

Is there a smart way to use ImageMagick for this purpose, or do I have to go hard-core and write the algorithm myself, looking at each pixel in the image?

Bjorn
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Extract main colors from image

Post by fmw42 »

I have a bash unix script, locatecolors, that finds all the pixels within a certain range of colors. You can use that to create a mask. Then get the percentage of pixels in the mask. see link below.
YayBjorn
Posts: 4
Joined: 2010-10-11T05:57:00-07:00
Authentication code: 8675308

Re: Extract main colors from image

Post by YayBjorn »

I will have a go with your script, but preferably I wan't to do this the most efficient way possible. Potensially I will have to do this do this to a huge amount of images (millions), and performance is of the essence. I don't like the idea of creating 12 masks and then counting the pixels in each one to much. I'd rather loop through the pixels, and put in pixel in one of 12 category-counters, and then at the end just look at the pixels-count in each category. Can this be achieved? Are you able to write such a script?

Bjorn
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Extract main colors from image

Post by fmw42 »

Scripting is limited and I would have to approach it as multiple masks. I suggest you or someone else write a program or use on of the APIs to do the hard work.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Extract main colors from image

Post by fmw42 »

Here is another approach. Use -map (-remap) to transform your image into a limited set of colors via a color palette image that is the set of 12 or so colors that are the centers of your ranges. Then get the histogram of the transformed image which will contain only those 12 or so colors. IM -map will find the closest color from the 12 colors or so to map each color in your image.

see example at http://www.imagemagick.org/Usage/quantize/#web_safe or http://www.imagemagick.org/Usage/quantize/#map

if you add +dither, then dithering will be turned off and you get exactly those colors
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Extract main colors from image

Post by anthony »

fmw42 wrote:see example at http://www.imagemagick.org/Usage/quantize/#web_safe or http://www.imagemagick.org/Usage/quantize/#map

if you add +dither, then dithering will be turned off and you get exactly those colors
You always get just the colors you specify (though maybe not all of then.

+dither just turns of IM's attempt to make an local area look more like the original color by using a mix of the available colors next to each other. Instead colors will be assigned strictly by nearest provided color to the original source images color (in RGB colorspace).
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Extract main colors from image

Post by fmw42 »

anthony wrote:
You always get just the colors you specify (though maybe not all of then.

+dither just turns of IM's attempt to make an local area look more like the original color by using a mix of the available colors next to each other. Instead colors will be assigned strictly by nearest provided color to the original source images color (in RGB colorspace).

Thanks Anthony for the clarification about dithering. I know little about it, but thought perhaps one got other colors. I stand corrected.
YayBjorn
Posts: 4
Joined: 2010-10-11T05:57:00-07:00
Authentication code: 8675308

Re: Extract main colors from image

Post by YayBjorn »

fmw42 wrote:Here is another approach. Use -map (-remap) to transform your image into a limited set of colors via a color palette image that is the set of 12 or so colors that are the centers of your ranges. Then get the histogram of the transformed image which will contain only those 12 or so colors. IM -map will find the closest color from the 12 colors or so to map each color in your image.

see example at http://www.imagemagick.org/Usage/quantize/#web_safe or http://www.imagemagick.org/Usage/quantize/#map

if you add +dither, then dithering will be turned off and you get exactly those colors
Hi, I've been investigating this approach myself actually, and it looks quite promissing. I've created a bmp file with my 12 colors, then I run something like:

convert original.jpg -dither None -map colors.bmp converted.bmp
convert converted.bmp -format %c histogram:info:-

This gives me the number of pixels in each category. I guess I'll have to do some testing to get the right "percentages" for the categories now. Does anybody have any thought as to if this is a "smart" way to categorize images according to colors? It's seems fast and simple to me.

Bjorn
Post Reply