Identify Black & White or Color for printing

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
jwms
Posts: 4
Joined: 2015-09-29T10:24:55-07:00
Authentication code: 1151

Identify Black & White or Color for printing

Post by jwms »

Hi,

I'm a complete newbie to ImageMagick so please bear with me.

We need to identify if JPG images are more appropriate for sending to a B&W printer or a color printer. I.e. If the image is all or mostly B&W, it should be tagged as B&W. If there is color in the image it should be tagged as color.

I'm imagining a script that will take a list of files and return a list that will indicate the category based on a threshold. It looks like compare will do it but I'm having trouble identifying a good starting point.

In the samples below, 1.jpg and 2.jpg should go to B&W. 3.jpg should go to color.

https://www.dropbox.com/sh/9v9h3bz8wx7c ... j51Da?dl=0

Thanks for any help!

OS: Windows 7
Version: ImageMagick 6.9.2-3 Q16 x64 2015-09-19
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Identify Black & White or Color for printing

Post by snibgo »

The "C" channel of HCL gives it, but the difference is rather small.

Code: Select all

f:\web\im>%IM%convert 1.jpg -colorspace HCL -format "%[fx:mean.g]" info:
0.00028421
f:\web\im>%IM%convert 2.jpg -colorspace HCL -format "%[fx:mean.g]" info:
0.0173751
f:\web\im>%IM%convert 3.jpg -colorspace HCL -format "%[fx:mean.g]" info:
0.0212596
f:\web\im>
When evaluating the images, the overall saturation doesn't distinguish them. Instead, we should find the saturation of small areas. The maximum saturation across the entire image tells us if this is "B/W" or "colour".

Code: Select all

f:\web\im>%IM%convert 1.jpg -colorspace HCL -channel G -separate -crop 50x50 +repage -scale 1x1! -background Black -compose Lighten -layers merge -format "%[fx:mean]" info:

0.0212253

f:\web\im>%IM%convert 2.jpg -colorspace HCL -channel G -separate -crop 50x50 +repage -scale 1x1! -background Black -compose Lighten -layers merge -format "%[fx:mean]" info:

0.057145

f:\web\im>%IM%convert 3.jpg -colorspace HCL -channel G -separate -crop 50x50 +repage -scale 1x1! -background Black -compose Lighten -layers merge -format "%[fx:mean]" info:

0.265339
Each image is changed to HCL, just the saturation channel, then chopped up into squares 50x50. Each square is scaled down to a single pixel, then we find the lightest one (ie the most saturated), and we print that saturation, on a scale of 0.0 to 1.0.

Your threshold could be somewhere between 0.06 and 0.26.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Identify Black & White or Color for printing

Post by fmw42 »

Just check the r,g,b mean values. If all three are nearly equal, then it is grayscale; otherwise it is color.

In unix syntax:

In the last 3 commands, 1 is gray and 0 is color. I do not know Windows, so some one will need to help you with variables and variable substitution, since unix and windows scripting are different. Chage the threshold as desired.

Code: Select all

convert 1.jpg -scale 1x1! -format "%[fx:100*u.r],%[fx:100*u.g],%[fx:100*u.b]\n" info:
84.5472,84.5441,84.567

convert 2.jpg -scale 1x1! -format "%[fx:100*u.r],%[fx:100*u.g],%[fx:100*u.b]\n" info:
63.2517,63.1464,64.6403

convert 3.jpg -scale 1x1! -format "%[fx:100*u.r],%[fx:100*u.g],%[fx:100*u.b]\n" info:
70.9041,69.6864,70.1183

thresh=0.5
convert 1.jpg -scale 1x1! -format "%[fx:(100*u.r-100*u.g)<$thresh && (100*u.r-100*u.b)<$thresh && (100*u.g-100*u.b)<$thresh?1:0]\n" info:
1

convert 2.jpg -scale 1x1! -format "%[fx:(100*u.r-100*u.g)<$thresh && (100*u.r-100*u.b)<$thresh && (100*u.g-100*u.b)<$thresh?1:0]\n" info:
1

convert 3.jpg -scale 1x1! -format "%[fx:(100*u.r-100*u.g)<$thresh && (100*u.r-100*u.b)<$thresh && (100*u.g-100*u.b)<$thresh?1:0]\n" info:
0

P.S. I see that snibgo beat me to the reply by a little bit. We were posting at about the same time. Our solutions are similar. He used HCL and I use RGB color spaces. Both rely upon the mean of the appropriate channels.
jwms
Posts: 4
Joined: 2015-09-29T10:24:55-07:00
Authentication code: 1151

Re: Identify Black & White or Color for printing

Post by jwms »

Thank you snibgo and Fred. I will try both methods against a large population to see which works best. Another consideration is speed since this will at times need to be run on thousands of pages.

Regards.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Identify Black & White or Color for printing

Post by snibgo »

Of the methods given, my technique of chopping into squares will certainly be the slowest. You can vary the size of the pieces, eg to be 10% of the image, so there are "only" 100 rectangles.

And, of course, you can mix the methods, eg chop into rectangles then use Fred's idea of taking the means of the RGB channels for each rectangle.

Please post any conclusions -- it adds to the knowledge base.
snibgo's IM pages: im.snibgo.com
jwms
Posts: 4
Joined: 2015-09-29T10:24:55-07:00
Authentication code: 1151

Re: Identify Black & White or Color for printing

Post by jwms »

It looks like the slowest method is also the most accurate but they all have useful data.

For now I need to figure out how to run the commands in a batch for large collections. Any sugestions?

MS DOS .bat/.cmd files think the % symbol is for a variable so it breaks the string.

Output should be to a text file identifying the image and the result. Something like...

1 : 0.0212253
2 : 0.057145
3 : 0.265339

Once I get it down I will run each method on a large collection, QC the output results and post my conclusion.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Identify Black & White or Color for printing

Post by snibgo »

When used in a BAT file, double each %, so you have:

Code: Select all

-format "%%[fx:100*u.r],%%[fx:100*u.g],%%[fx:100*u.b]\n"
For multiple images, I generally use FOR loops. Results can be echoed to a text file.

My pages have many examples of using IM in BAT files.
snibgo's IM pages: im.snibgo.com
jwms
Posts: 4
Joined: 2015-09-29T10:24:55-07:00
Authentication code: 1151

Re: Identify Black & White or Color for printing

Post by jwms »

Thanks snibgo! I will put it to the test and let you know what I find.
Post Reply