How to check image color or back and white

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?".
darksndr
Posts: 7
Joined: 2016-06-30T13:11:30-07:00
Authentication code: 1151

Re: How to check image color or back and white

Post by darksndr »

fmw42 wrote: Due to HSL being a double hexcone model [...] In its place, use HCL, HCLp, HSI or HSB above. These are all single hexcone type models and should work fine in the above equation.
Thank you fmw42, so if I use this command I can safely distinguish a color image from a grayscale's one:

Code: Select all

convert image -colorspace HSI -channel g -separate +channel -format "%[fx:mean]" info:
by testing the saturation percentage (0 = grayscale, >0 = color).

I have another question: how can I distinguish these three type of images:

Image

1- is a rich color image (saturation ~ 40%)
2- is a grayscale image (saturation = 0%)
3- is a mostly two color gradient images (saturation ~ 15-30%)

both (1) and (3) have a quite high saturation value and so I can not distinguish between the two of them :(

My task is to process book pages (japanese comics), the cover is always colored and the pages are often grayscale but sometimes mostly two color gradient:
  • - if the page is colored (like fig#1): keep colors, resize and convert to JPG
    - if the page is grayscale (like fig#2): keep grayscale, resize and convert to GIF with dirthering
    - if the page is mostly two color gradient (like fig#3): convert to grayscale GIF with dirthering
Can somebody help me? :)
Last edited by darksndr on 2016-07-11T03:38:11-07:00, edited 1 time in total.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: How to check image color or back and white

Post by fmw42 »

I have another question: how can I distinguish these three type of images:
Look at the standard deviation of the hue channel (of non-gray images) to see if it is low. (Or the distribution of hues in the histogram of the hue channel). If low (or only a few hues), then case 3, if large then lots of different hues so case 1. (untested thoughts)
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to check image color or back and white

Post by snibgo »

Separating hue and counting unique colors is often useful, but your image 3 is too noisy for that to be meaningful. Perhaps the full-size scan is okay.

Code: Select all

convert 3-gradient.jpg -colorspace HSL -channel H -separate -unique-colors -format %w info:

602
Another possibility:

Code: Select all

convert 3-gradient.jpg -colorspace HSL -channel H -separate -define histogram:unique-colors=true -format %c histogram:info:- |sort
Again, no good for your example, but might be okay full-size.
snibgo's IM pages: im.snibgo.com
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: How to check image color or back and white

Post by anthony »

Image 3 can only be separated by doing a test that looks to see if the color form a line in 3D colorspace. That is a color gradient.

I have done this though it is tricky. I talk about it in..
http://www.imagemagick.org/Usage/compare/#type_linear

The script was written in perl, and uses the perl Math::VectorReal module from CPAN.

The way it works (using a fixed number of colors by resizing the image to a smaller fixed size)
* find the average of the colors (origin)
* average the vector direction of all colors from this origin
* get a least squares error of all colors from the line formed by that origin-vector
If the error value is small, the colors are basically linear along that line (even if there is a slight curve due to color space differences). If the image is a mash of multiple colors (like the first image), then you will get a large error value, and the image is not a linear color image.

This worked extremely well for me when I was sorting thousands of images, grouping them based on image metrics, before eye-balling possible matches.

This basically separates color images from black-white, greyscale, and linear color images.

WARNING: Simple line drawing images (without shading) can often end up in either group as the image is almost entirely a single background color. They should be separated out before doing this test.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to check image color or back and white

Post by snibgo »

Image three has gradients from 3 colours: black, white and light-purple. It also has pixels that are outside any of those colour-gradients, possibly caused by JPEG compression.
snibgo's IM pages: im.snibgo.com
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: How to check image color or back and white

Post by anthony »

Hmm yes you are right. it is essentially a greyscale image with color highlight. or perhaps with a parabolic curve so mid-greys -> some highlight color.

So colors would generally all lie in a plane (or curved path), rather than as a line. The same sort of vector test (planar rather than linear) would sort it out.

Hmm such images could be generated using 'light' compositions
http://www.imagemagick.org/Usage/compose/#light
or mid-tone tinting
http://www.imagemagick.org/Usage/color_mods/#tint
or even sepia-tone (which makes whites a little more yellow)
http://www.imagemagick.org/Usage/color_mods/#sepia-tone

testing for such images would be tricky, but perhaps a useful thing.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
darksndr
Posts: 7
Joined: 2016-06-30T13:11:30-07:00
Authentication code: 1151

Re: How to check image color or back and white

Post by darksndr »

Hi all,

I took some time to think about a solution for my needs based on your suggestions.

I ended up with this solution:
1. compute the mean saturation percentage (1-100%)
2. compute the standard deviation of the unique hues (without considering their absolute frequency)
3. if sat_mean >= 30, then it's a colore image
4. if the sat_mean < 10, then it's a grayscale image
5. if the sat_mean is between 10 and 30, then check hue_st_dev: if hue_st_dev > 25 then it's a colored image otherwise it's a grayscale one.

In order to compute those two values I extracted the image's histogram, converting the image to 64 colors:

Code: Select all

convert fname.ext -dither FloydSteinberg -colors 64 -colorspace HSB -format %c histogram:info:-
in this manner I have a good enough approximation of the image hues and a smaller dataset to elaborate.

Before computing hue std.dev I removed the first and last values as they seems to be representing the background color (the big part of a grayscale comic page).

I wrote a Ruby script to perform this test, you can view it here: http://pastebin.com/bJQCN90v

For this image set:
Image

the results are the following (the images in the collage are in alphabetical order):

Code: Select all

bash$ for i in *; do ../test.rb $i; done
1-color.jpg              S:58.40  H:33.84  N: 64  O:  3%  =>  color
1-color-low.jpg          S:48.27  H:31.39  N: 64  O:  3%  =>  color
2-gray1.png              S: 0.00  H: 0.00  N: 64  O: 73%  =>  grey
2-gray2.png              S: 0.00  H: 0.00  N: 64  O: 82%  =>  grey
2-gray3.png              S: 0.00  H: 0.00  N: 64  O: 83%  =>  grey
3-col1_H240-S50-L0.png   S:17.38  H: 0.00  N: 63  O: 11%  =>  grey
3-col1_H250-S60-L0.png   S:18.88  H: 0.53  N: 64  O: 11%  =>  grey
3-col1_H40-S50-L0.png    S:17.38  H: 0.74  N: 64  O: 73%  =>  grey
3-col2_H360-S80-L0.png   S:15.12  H: 0.00  N: 63  O: 12%  =>  grey
3-col3_H360-S80-L40.png  S:20.81  H: 0.00  N: 61  O: 74%  =>  grey
3-gradient.jpg           S:23.02  H:19.82  N: 64  O: 41%  =>  grey
4-monochrome.png         S: 0.00  H: 0.00  N:  2  O:100%  =>  grey
5-white-red.png          S:20.88  H: 0.00  N:  2  O:100%  =>  grey
the columns are: [S]aturation mean, unique [H]ue standard deviation, [N]umber of colors, percent of [O]utlayered pixels, and resulting image type.

It seems to work well. What do you think?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to check image color or back and white

Post by snibgo »

Thanks for the update. That looks interesting.

It might be useful not to think of this as colour/grayscale, but in terms the colours of inks: black only, some other colour only, black plus one other, or multicolour (probably CMYK).

Beware of the standard deviation of the hue, as this wraps around at 360 degrees.
snibgo's IM pages: im.snibgo.com
darksndr
Posts: 7
Joined: 2016-06-30T13:11:30-07:00
Authentication code: 1151

Re: How to check image color or back and white

Post by darksndr »

snibgo wrote:Beware of the standard deviation of the hue, as this wraps around at 360 degrees.
Yes, but these image colorizations are often centered around a particular degree distant from 0° and 360°, in addition (I think) the exclusion of the first and last hue values from the histogram should attenuate this problem a bit.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: How to check image color or back and white

Post by anthony »

darksndr wrote:
snibgo wrote:Beware of the standard deviation of the hue, as this wraps around at 360 degrees.
Yes, but these image colorizations are often centered around a particular degree distant from 0° and 360°, in addition (I think) the exclusion of the first and last hue values from the histogram should attenuate this problem a bit.
But it can still easily fail with regard to the red hue. I would probably do it twice, the second time with the hues rotated 180 degress. You will either get roughly the same standard deviation, or wildly different. If the second one in that case would probably be very small, in which case you have a image with a red midtone coloring.

When testing I would separate them into three groups. black and white, colored, or midtone colored. You want to process them differently anyway, so may as well seperate them into three groups.

Also take your test images and save and reload them using the JPEG format, with a very very low quality setting. It will make the images fuzzy and distorted, thus present you with a test group that should much more realistic of what you may need to deal with.

Also before doing the standard deviation I would remove not only the pure black and white colors, but any color that has a very, very low saturation (greys). When the saturation is near zero, the hue has very little meaning, and could point in any direction. Your not really interested in them for that test anyway.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
darksndr
Posts: 7
Joined: 2016-06-30T13:11:30-07:00
Authentication code: 1151

Re: How to check image color or back and white

Post by darksndr »

anthony wrote: But it can still easily fail with regard to the red hue. I would probably do it twice, ...

When testing I would separate them into three groups...

Also take your test images and save and reload them using the JPEG format, with a very very low quality setting...

...remove not only the pure black and white colors, but any color that has a very, very low saturation (greys). ...
Thank you for your very useful insights :-)
I applied all of them and the results are now more bullet proof than the previous version.

Code: Select all

bash$ ls|sort|while read fname; do ../test.rb "$fname"; done
hq_1-color.jpg                  S:58.40  H:35.78  H2:21.83  N:64  R: 5  O: 20%  =>    colored
hq_1-color-low.jpg              S:48.27  H:33.78  H2:24.44  N:64  R: 6  O: 24%  =>    colored
hq_2-gray1.png                  S: 0.00  H: 0.00  H2: 0.00  N:64  R:64  O:100%  =>    grayscale
hq_2-gray2.png                  S: 0.00  H: 0.00  H2: 0.00  N:64  R:64  O:100%  =>    grayscale
hq_2-gray3.png                  S: 0.00  H: 0.00  H2: 0.00  N:64  R:64  O:100%  =>    grayscale
hq_3-col1_H240-S50-L0.png       S:17.38  H: 0.00  H2: 0.00  N:63  R: 5  O: 74%  =>    monochrome_mid_sat
hq_3-col1_H250-S60-L0.png       S:18.88  H: 0.49  H2: 0.49  N:64  R: 4  O: 73%  =>    monochrome_mid_sat
hq_3-col1_H40-S50-L0.png        S:17.38  H: 0.72  H2: 0.72  N:64  R: 5  O: 74%  =>    monochrome_mid_sat
hq_3-col2_H360-S80-L0.png       S:15.12  H: 0.00  H2: 0.00  N:63  R: 3  O: 82%  =>    monochrome_mid_sat
hq_3-col3_H360-S80-L40.png      S:20.81  H: 0.00  H2: 0.00  N:61  R: 4  O: 75%  =>    monochrome_mid_sat
hq_3-gradient.jpg               S:23.02  H: 7.88  H2: 5.97  N:64  R:11  O: 50%  =>    monochrome_mid_sat
hq_4-monochrome.png             S: 0.00  H: 0.00  H2: 0.00  N: 2  R: 2  O:100%  =>    grayscale
hq_5-white-red.png              S:20.88  H:  NaN  H2:  NaN  N: 2  R: 1  O: 79%  =>    monochrome
lq_1-color.jpg                  S:54.94  H:35.62  H2:22.30  N:64  R:12  O: 30%  =>    colored
lq_1-color-low.jpg              S:44.92  H:33.14  H2:24.68  N:64  R:10  O: 33%  =>    colored
lq_2-gray1.jpg                  S: 0.00  H: 0.00  H2: 0.00  N:16  R:16  O:100%  =>    grayscale
lq_2-gray2.jpg                  S: 0.00  H: 0.00  H2: 0.00  N:16  R:16  O:100%  =>    grayscale
lq_2-gray3.jpg                  S: 0.00  H: 0.00  H2: 0.00  N:16  R:16  O:100%  =>    grayscale
lq_3-col1_H240-S50-L0.jpg       S:15.24  H:16.70  H2:16.87  N:64  R:16  O: 74%  =>    monochrome_mid_sat
lq_3-col1_H250-S60-L0.jpg       S:17.24  H:16.48  H2:16.74  N:64  R:15  O: 75%  =>    monochrome_mid_sat
lq_3-col1_H40-S50-L0.jpg        S:16.57  H:20.04  H2:15.23  N:64  R:18  O: 71%  =>    monochrome_mid_sat
lq_3-col2_H360-S80-L0.jpg       S:14.02  H:41.89  H2:14.72  N:64  R:18  O: 80%  =>    monochrome_mid_sat
lq_3-col3_H360-S80-L40.jpg      S:23.07  H:38.80  H2:16.24  N:64  R: 9  O: 56%  =>    monochrome_mid_sat
lq_3-gradient.jpg               S:12.58  H:10.14  H2:10.39  N:64  R:17  O: 78%  =>    monochrome_mid_sat
lq_4-monochrome.jpg             S: 0.00  H: 0.00  H2: 0.00  N:16  R:16  O:100%  =>    grayscale
lq_5-white-red.jpg              S:24.19  H:41.33  H2:20.64  N:64  R: 4  O: 69%  =>    monochrome_mid_sat
The H2 column is the 180 degree shifted unique hue standard deviation.
The R column is the number of removed rows from the histogram.

I wrote a post about this test and attached the ruby script to it: https://acavalin.com/p/test_img_color_grayscale
Last edited by darksndr on 2018-07-24T07:20:19-07:00, edited 2 times in total.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: How to check image color or back and white

Post by anthony »

I can see that the stddev of saturation basically halved in the two images with red mid-tones. There were also a reduction in both color images showing that they had overall more red colors than blue-green colors.

Judging by the sudden jump in 'color counts' (N) in the 'lq' I can see you did apply the 'low quality jpg' filter I suggested, and that has changed the classification of some of the 'simplier' images, as I expected it would.

Glad you found the ideas useful. :-)
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: How to check image color or back and white

Post by fmw42 »

I do not know if this would be useful or not, but you might look at the YCbCr (Cb vs Cr) plane for analysis of color. See https://en.wikipedia.org/wiki/YCbCr
Hjkma
Posts: 7
Joined: 2015-03-07T15:48:52-07:00
Authentication code: 6789

Re: How to check image color or back and white

Post by Hjkma »

darksndr, I want to use your script to check my images for greyscale color, but I do not know how to use this ruby script in Windows 7, I do not understand anything about it. What do I need to do? Please describe the instructions step by step how to use this.

After I installed the Ruby installer for Windows, I put the script and images in ImageMagick folder and ran the script and it showed that message "ERROR:file not found!".
darksndr
Posts: 7
Joined: 2016-06-30T13:11:30-07:00
Authentication code: 1151

Re: How to check image color or back and white

Post by darksndr »

Hjkma wrote: 2017-04-06T14:59:22-07:00 darksndr, I want to use your script to check my images for greyscale color, but I do not know how to use this ruby script in Windows 7, I do not understand anything about it. What do I need to do? Please describe the instructions step by step how to use this.

After I installed the Ruby installer for Windows, I put the script and images in ImageMagick folder and ran the script and it showed that message "ERROR:file not found!".
Hello Hjkma, that is a command line script, it means that you have to run it via the "Command prompt" program.

First thing you have to add ruby to your path, the installer should have done this for you, check it this way:
  • Windows Menu > Run > type "cmd" > ENTER (this sould open the command prompt)
  • type: ruby -v (this should print your ruby version number)
if that works, then create in your images folder a new TXT file, rename it like "test_images.rb", open it in Notepad and paste these lines:

Code: Select all

Dir['*'].grep(/\.(jpg|jpeg|png|gif)$/i).each{|img| system %Q|ruby color_greyscale_image_test.rb "#{img}"| }
puts "Hit RETURN to continue"
STDIN.gets
save and run it. It iterates over each file and call the test script (must be in the same folder) passing the image name.

For simplicity you can edit my script and delete lines 156-162 so it will print only file name and result.

You will also need the imagemagick "convert" executable file in your path (or copy it in the folder with the scripts), you can download it here:

https://www.imagemagick.org/script/bina ... hp#windows (choose the Q16 static version for your pc)
Post Reply