Knowing if RGB images are almost BW/grayscale.

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?".
dedalus
Posts: 7
Joined: 2014-11-15T00:15:16-07:00
Authentication code: 6789

Knowing if RGB images are almost BW/grayscale.

Post by dedalus »

Hi,

I would understand if there is a "fast" way (the best "one line" command…) with IM to identify a nearly BW/grayscale (s)RGB picture.
I mean if an RGB image consists mainly of grays and/or black and white colors.

This demand because if I have a bunch of RGB jpg images and just some are almost as grayscale or close to be black and white, I would convert them in PNG format. A more suitable and convenient format than jpg in similar cases.

The hope is that someone has an idea to reach the goal so that it may be worth.
Searching the net, I couldn't find anything that would help. So please, if anyone had any helpful suggestions… Thanks a lot in advance.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Knowing if RGB images are almost BW/grayscale.

Post by snibgo »

The average (mean) saturation would do it:

Code: Select all

convert in.jpg -colorspace HSL -channel G -separate -format %[fx:mean] info:
This returns zero if the image if black/gray/white, 1.0 if it is fully saturated, slightly above zero if it is nearly gray, etc.
snibgo's IM pages: im.snibgo.com
dedalus
Posts: 7
Joined: 2014-11-15T00:15:16-07:00
Authentication code: 6789

Re: Knowing if RGB images are almost BW/grayscale.

Post by dedalus »

Hi,
Thanks for your idea, but trying it with some images I have, this is what I get:

0.545707 … a rgb B&W image ( "white" background)
0.477206 … a rgb with some colors image ( "white" background)
0.489378 … a rgb (similar to previous one)
0.607111 … a rgb with some colors image ( "white" background)
0.48623 … a rgb B&W image ( "white" background)
0.624553 … a rgb with colors image (color background)
0.672277 … a rgb with colors image (color background)
0.115445 … a rgb with some colors ( black background)

And if I convert the first image ( returning 0.545707 ) to grayscale and then I convert it back again to RGB ... In fact I get an unequivocal 0.
Therefore, the results do not seem to be very reliable for what I need. Also because where I write ( "white" background), the background can actually be very slightly yellowish or other shade.

A friend of mine had suggested this way:

Code: Select all

convert in.jpg -unique-colors -depth 8 txt: | wc -l
and with the same previous images I get

….9895 ( B&W )
..30184
..35913
..78500
..12114 ( B&W)
..63815
124700
..50726

With the grayscale back to RGB image, 257. So it seems a little better. Because it would seem that if I get values less than 15000, the image probably comes close to a B&W or grays.
Unfortunately, it seems a bit slow. And if I have 200 images becomes a bit long unless another idea.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Knowing if RGB images are almost BW/grayscale.

Post by snibgo »

My code gives the average saturation of the pixels, which is near zero for images without much saturation. Perhaps you mean something else by "nearly BW/grayscale".

If you put up the example images, and rank then in order of "nearly BW/grayscale", perhaps we can refine this.
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: Knowing if RGB images are almost BW/grayscale.

Post by fmw42 »

You could threshold the saturation image and get the total number of pixels with zero saturation (mean*width*height=total). You would have to decide what threshold to use to signify what is low saturation (nearly gray) and what is above that threshold (color).
dedalus
Posts: 7
Joined: 2014-11-15T00:15:16-07:00
Authentication code: 6789

Re: Knowing if RGB images are almost BW/grayscale.

Post by dedalus »

Well thanks, so here http://goo.gl/TObXPX (Dropbox, less than 1MB) you can download a zip file with some sample images. The "yes_100" .jpg are the ones to spot. Even those with "yes_90" it would be good to find. But maybe it's asking too much.

My aim is to optimize their weight. In fact, if the JPG is perfect for images such as "photos" with a lot of colors and shades, it is much less perfect for pictures look more graphic. As it's widely known and surely you know. So with a lot of images, it's rather important to find out quickly the most suitable for PNG conversion. Then using pngquant or pngnq and so on you can get the final files.

I've just tried in conjunction with AppleScript for a cycle on about 200 images, and using

Code: Select all

convert in.jpg -unique-colors -depth 8 txt: | wc -l
as I thought it was pretty slow but you get some results.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Knowing if RGB images are almost BW/grayscale.

Post by fmw42 »

look at the histogram of each image and get the percentage of all gray/black/white pixels relative to the total number of pixels. Then use some cuttoff on that percentage.
dedalus
Posts: 7
Joined: 2014-11-15T00:15:16-07:00
Authentication code: 6789

Re: Knowing if RGB images are almost BW/grayscale.

Post by dedalus »

If you believe that it's faster and more reliable, thanks for your suggestion fmw42.

But, ehm,.. I see here http://www.fmwconcepts.com/imagemagick/ ... or_percent two ways to get the percentage of just 1 color,.. I really don't know a smart way to get the percentage of 256 grays :? and so on all the rest. I manage quite well AppleScript, not so well Terminal and shell scripts.

So if you think it's simple enough and if you were so kind to show me how to do it practically, it would be greatly appreciated.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Knowing if RGB images are almost BW/grayscale.

Post by fmw42 »

Sorry, my concept won't work with your images, because most of them do not have pure black/white/gray, so I cannot filter on gray(xxx) as part of the histogram info. So you are really back to using the saturation channel and its mean or a variation of that.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Knowing if RGB images are almost BW/grayscale.

Post by fmw42 »

Here is another thought.

Convert the image to grayscale, do -compose difference -composite to get the difference between the color and grayscale image. Then separate the channels and get the average of the three channels. The threshold on some small percent that you consider to be close to black/white/gray in color. Then get the mean value. If too large (too much white from the difference, where black would be gray), it has too much color. I left in a -write show: to show a visual of the result.


Unix syntax:

Code: Select all

convert yes_90a.jpg \
\( -clone 0 -colorspace gray \) \
-compose difference -composite \
-separate -evaluate-sequence mean \
-threshold 4% -write show: -format "%[fx:mean]\n" info:
This returns 0.641184. You would have to test a number of images to see if it selects something reasonable for you. But I have my doubts this will give values consistent with your visual impression, since this image has lots of color and think it is gray by your "yes" label. So your threshold will need to be rather large and above this amount.
dedalus
Posts: 7
Joined: 2014-11-15T00:15:16-07:00
Authentication code: 6789

Re: Knowing if RGB images are almost BW/grayscale.

Post by dedalus »

Yes, seeing those images (often quite variable) I understand it's not so simple to find out a good method that can replace a direct look… Although, apart from imagemagick in particular, it seems strange in the year 2014 there is not an "easy" way to get the result I'm looking for.
So thanks a lot for your ideas, I'll try this last one and let you know about it.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Knowing if RGB images are almost BW/grayscale.

Post by fmw42 »

Check with IBM Watson, the researchers at Google and Stanford or try researching the literature such as http://m.gadgets.ndtv.com/apps/news/res ... are-622557

You likely need something more than just image processing, perhaps neural nets and the like.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Knowing if RGB images are almost BW/grayscale.

Post by snibgo »

The problem boils down to: is there a numeric measure that corresponds to what you want?

For this set of images, one answer is the proportion of pixels that are within 10% of zero saturation, in HCL colorspace. Windows BAT code:

Code: Select all

del jpgbw.lis

for %%F in (*.jpg) do (
  echo %%F

  %IM%convert ^
    %%F ^
    -colorspace HCL -channel G -separate ^
    +channel -set colorspace sRGB ^
    -write x1.png ^
    -threshold 10%% ^
    -format %%[fx:mean],%%F\n ^
    -write x.png ^
    info: >>jpgbw.lis
)

type jpgbw.lis
cSort /ijpgbw.lis /ojpgbw.srt

type jpgbw.srt
Results:

Code: Select all

0.000331765,yes_100c.jpg
0.000495175,yes_100e.jpg
0.000539469,yes_100a.jpg
0.0013594,yes_100b.jpg
0.0015814,yes_100d.jpg
0.00432996,yes_100g.jpg
0.225634,yes_90b.jpg
0.292746,yes_100f.jpg
0.64184,yes_90a.jpg
0.793481,no_d.jpg
0.803856,no_a.jpg
0.818112,no_b.jpg
0.879043,no_c.jpg
This gives what you want.
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: Knowing if RGB images are almost BW/grayscale.

Post by fmw42 »

If I run my code in a loop, surprisingly, I get pretty similar values to snibgo.

Code: Select all

cd
cd desktop/JPG
list=`ls`
for img in $list; do
convert $img \
\( -clone 0 -colorspace gray \) \
-compose difference -composite \
-separate -evaluate-sequence mean \
-threshold 4% -format "%f %[fx:mean]\n" info:
done | sort -k 2

Code: Select all

yes_100b.jpg 0.000415187
yes_100a.jpg 0.000456219
yes_100e.jpg 0.000556225
yes_100c.jpg 0.000653373
yes_100d.jpg 0.00217784
yes_100g.jpg 0.00557995
yes_90b.jpg 0.188031
yes_100f.jpg 0.29809
yes_90a.jpg 0.641184
no_a.jpg 0.783223
no_b.jpg 0.815581
no_d.jpg 0.820241
no_c.jpg 0.866189
So the threshold for separating yes from no seems to be between 0.641184 and 0.783223 (about 0.7?)
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Knowing if RGB images are almost BW/grayscale.

Post by snibgo »

Yes. Two different methods, but both distinguish between "yes" and "no".

I haven't experimented with the threshold value, 10% for my method. A different threshold might give a greater gap between "yes" and "no".
snibgo's IM pages: im.snibgo.com
Post Reply