Page 1 of 1
Identify Black & White or Color for printing
Posted: 2015-09-30T15:23:38-07:00
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
Re: Identify Black & White or Color for printing
Posted: 2015-09-30T16:56:05-07:00
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.
Re: Identify Black & White or Color for printing
Posted: 2015-09-30T17:13:25-07:00
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.
Re: Identify Black & White or Color for printing
Posted: 2015-10-01T06:00:37-07:00
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.
Re: Identify Black & White or Color for printing
Posted: 2015-10-01T06:29:19-07:00
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.
Re: Identify Black & White or Color for printing
Posted: 2015-10-01T07:38:25-07:00
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.
Re: Identify Black & White or Color for printing
Posted: 2015-10-01T07:46:57-07:00
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.
Re: Identify Black & White or Color for printing
Posted: 2015-10-01T13:10:56-07:00
by jwms
Thanks snibgo! I will put it to the test and let you know what I find.