Exact Average Color of an 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
hmaugans

Exact Average Color of an Image

Post by hmaugans »

Hi,

I'm dealing with fairly large images (wallpaper size), and I'm looking for a way to find an exact average color of the image represented as a single number (ie, to the 20th decimal point- very, very accurate).

I'm considering stepping through every pixel of the image, averaging all the colors, however as the images are quite large, this would take a long time.

The purpose of this is to establish a "fingerprint" for each image, so I can compare it to thousands of other fingerprints, and return other images that are within a certain threshold (so many decimals apart from each other). In other words, I'm looking to establish a system to quickly compare thousands of images together, and find ones that are very similar, using some kind of decimal as a key. I need to keep it a fuzzy match, so there can be slight variations in the images (brightness adjustments, small text copyright notices at the bottom, etc), but still return as a match. The number also needs to stay relatively close between different sizes of the same image, so if an image is resized, it'll still return a match.

Aside from average colors question I had above, can anyone think of a better way, or does that seem to be the best?

Thank you, and I look forward to you responses. :)
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Exact Average Color of an Image

Post by Bonzo »

A couple of thoughts:

1/ With ImageMagick you can get image details all or selected; could you use these ?
Channel statistics:
Red: Min: 0 (0) Max: 255 (1) Mean: 129.429 (0.507566) Standard deviation: 66.6698 (0.26145)
Green: Min: 0 (0) Max: 255 (1) Mean: 92.4053 (0.362374) Standard deviation: 47.2879 (0.185443)
Blue: Min: 0 (0) Max: 255 (1) Mean: 85.3009 (0.334513) Standard deviation: 54.4362 (0.213475)

2/ A suggestion from Anthony before was to resize the image to one pixel and get the colour of that - I was only looking for the averidge colour of an area of an image but it should work for the whole image ?
hmaugans

Re: Exact Average Color of an Image

Post by hmaugans »

Bonzo wrote:A couple of thoughts:

1/ With ImageMagick you can get image details all or selected; could you use these ?
Channel statistics:
Red: Min: 0 (0) Max: 255 (1) Mean: 129.429 (0.507566) Standard deviation: 66.6698 (0.26145)
Green: Min: 0 (0) Max: 255 (1) Mean: 92.4053 (0.362374) Standard deviation: 47.2879 (0.185443)
Blue: Min: 0 (0) Max: 255 (1) Mean: 85.3009 (0.334513) Standard deviation: 54.4362 (0.213475)

2/ A suggestion from Anthony before was to resize the image to one pixel and get the colour of that - I was only looking for the averidge colour of an area of an image but it should work for the whole image ?
1- Hum, how did you get that? If you modify a handful of pixels on an image, will those numbers stay relatively close? What about if the image is brightened or a hue is applied.. that'd offset everything and make the "fingerprints" very different wouldn't it. Would the overall average color be any better or worse than this?

2 - I saw Anthony's reply in another thread, but unfortunately I don't think that will be accurate enough. :(

I appreciate the reply, and look forward to hearing your (and others) further thoughts. :)
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Exact Average Color of an Image

Post by anthony »

Color Channel static are output from verbose "identify".
A average color is simply a -scale 1x1\!, then output to a "txt:" image.
http://www.imagemagick.org/Usage/compare/#metrics

I have in the last couple of days been wrestling with finding metrics (image fingerprints) for reducing the number of images being compared.

First, the bigger problem in comparing images isn't changes in hue or color,
or even chnaging a few pixels. It matching images that have been cropped or trimmed!!!!

From my own experiments a 'average color' to 16 bit value is only a bare mininum finger print, and rather useless. Averaging colors is a sharpening process, a few pixels does not change the value much. A hue change however will.

A better metric I am finding is to use a 3x3 matrix of average colors (after the outside 10% borders is removed).
If hue changes is a big problem, you can subtract the overall average color from the 3x3 color matrix, leaving a pattern of color differences representing the image. That will remove the effect of the overal image color, though not a contrast change.

I have added this to the above 'compare' examples page. but it may be a day or so before it appears.

My own personal image metric tests have been with a 'colorless' edge deteted metric. This should be basically indepandant of image color/brightnes/contrast chnages. But then most of the images I compare are cartoon like.

See the new section at the bottom of the comapre page...
I create a 'edge' image such as...

Code: Select all

  convert logo: -scale 100x100\! -median 3 \
          -quantize YIQ +dither -colors 3 -edge 1 \
          -colorspace gray -blur 0x1   outline_image.gif
Which is itself a good image to 'compare two images' without worying about color difference, though I am still working out the best way to do this.
The metric itself is a 3x3 matric of the greyscale image...

Code: Select all

  convert outline_image.gif -scale 3x3\! -compress none pgm:- | tail -1
Giving me...
4433 7672 3951 541 10105 5031 0 4083 6323
I wrote scripts ot generate and cache these metrics, so they only need to be done once per image, as needed.

I also used -colors rather than the more logical -segment as that later is so SLOW!!!!! It also appears to be wrong when you compare IM's version with the results of the segmentation algorthim from leptonica The -median is great for ignoring fine detail in images.

When I compare these metrics I discount the 'corner' metric that has the worst difference, that way I avoid logos that may have been added to an image.

This works!!! That simple metric seems to find all near matching images. and seems to best to compare the metric using a 'manhatten' comparision (add the differences), rather than a multi-dimensional distance (pythagorian) or reject is any difference is beyond a 'threeshold' (hyper-cube).

NOTE: metrics will always find more non-matching and matching. its job is to reduce the number of full image compares you do, not actullay to find matching images. That is the job of the next stage, comparing images with simular metrics.

If you like to contact me personally I would love to here of your own ideas and problems. Anthony_AT_griffith_DOT_edu_DOT_au
Or just continue this thread.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Exact Average Color of an Image

Post by anthony »

following from your mail, I tried out some matrix metrics involving color differences.
It works very well and I discovered some images I 'missed' in previous runs.

I have re-organized and updated the IM Examples Compare section, with lots more information and general techniques. give it a day or so for the changes to appear.


As alwasy ideas and suggestions are very welcome.

Current problem.... Seperating images of line drawings and sketches, from color images (cartoon and real world). the line drawing generally have all their colors in a linear line, but that line may not be greyscale. EG the sketch may be on yellow paper.
I need to fast way diffentiate this from some other non-linear color image.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply