Search code examples
imagemagick

imagemagick check if image is of almost one single color


Friends,

I have a stack of color-scanned images. Some are from regular white paper with text or images, others were scanned from colored paper (blank pages, same green colored paper used.)

I'd like to identify these colored paper images. Problems:

  1. paper's color ("background") is not scanned very uniformly, often has a wavy or structured pattern
  2. green tone is quite different depending on the scanner used
  3. scanner does not catch the full sheet resulting in a white or shadowed "border" around green area

My idea was to see if say 90% of the image is some sort of green and tried using a sorted histogram. But because of (1) and esp. (2) I have a hard time picking a working color value from the histogram data.

Any help appreciated!

Edit: Here are three sample images, scanned from the same sheet of paper. enter image description here enter image description here enter image description here


Solution

  • Have a look at HSV colourspace on Wikipedia - specifically this diagram.

    It should be a better place to find the colour of your images, regardless of scanner and calibration.

    Now, let's create a lime-green, yellow and cyan block and derive its colour using ImageMagick:

    magick -size 100x100 xc:lime -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
    120
    
    magick -size 100x100 xc:yellow -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
    60
                                                                                                                                      
    magick -size 100x100 xc:magenta -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
    300
                                                                                                                                                                     
    magick -size 100x100 xc:cyan -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info:
    180   
    

    Hopefully you can see we are correctly calculating the Hue angle. Now to your image. I have added an artificial frame so you can see how to remove the edges:

    enter image description here

    We can remove the frame like this:

    magick YOURSCAN.jpg -gravity center -crop 80% cropped.jpg 
    

    enter image description here


    So, my complete suggestion would be to crop and convert to HSV and check the mean Hue. You could also test if the image is fairly saturated so it doesn't pick up grey-ish, uncoloured images. You could also test the variance in the Hue channel to see if there are many different colours - or the spread of the hues is large and reject ones where it is large.

    magick YOURSCAN.jpg -gravity center -crop 80% -colorspace HSV -channel 0 -separate -format "%[fx:mean*360]" info: 
    

    Just for reference, your 3 images come up with the following Hue angles on a scale of 0..360:

    79, 68, 73
    

    I would suggest you test a few more samples to establish a reasonable range.