I have some JPG files and want to automatically determine which are black & white. They are all encoded in RGB.

How can I do this using commandline tools?


You could start by converting the image to grayscale and compareing that to the original image. If the image is already black and white, you'd expect the two images to be very similar; if it's full color, you'd expect them to be different.

Clarification: Given the two comments below, I think I wasn't clear enough here. Certainly, the grayscale version of a B&W image stored as RGB will likely not be exactly the same as the original image, but it should be pretty close. Subtracting the grayscale version from the original will yield a dark frame with a faint ghost of the original image. You could threshold this image to get a completely black frame. A full color image, on the other hand, will be significantly different from its grayscale counterpart, and subtracting the latter from the former will give an image that still has a lot of color even after thresholding (exactly what colors depends on how the grayscale conversion is done).

Another option: Thinking about the problem some more, another option is to convert the image to a neutral white point and then compare the red, green, and blue channels. In a color image, these will have significant differences; in a black and white image, they should be very similar. Again, they might not be exactly the same, depending on how the image was acquired in the first place, but the differences should be small enough that they can be easily filtered out. This is effectively the same idea as the one above, but the approach is perhaps more straightforward.

  • 2
    If they are JPG, maybe the decoding will give different results?
    – Max
    Jun 26 '15 at 13:29
  • Conversion to greyscale means averaging the channel values to a single value. This averaging is weighted one. the channels have a different influence on the resulting value. this is due to our different perception of colors. this means that there are many different conversions to b&w, with differently weighted channels. If one doesn't apply the same conversion, both converted images will be b&w, but still not equal. The comparison suggested should take this into account and should not just compare pixel values.
    – null
    Jun 26 '15 at 15:28

Building on Romeo's answer:

You can use imagemagick to convert to HSV color space and get statistics on the color distribution.

HSV means Hue, Saturation, Value

color space

For a true grayscale image, saturation must be constantly zero.

You can use the following command:

identify -colorspace HSL -verbose <infile>

and obtain something like the following for a true grayscale image (among other output)

  min: 0 (0)
  max: 0 (0)
  mean: 0 (0)
  standard deviation: 0 (0)
  kurtosis: 0
  skewness: 0
  min: 0 (0)
  max: 0 (0)
  mean: 0 (0)
  standard deviation: 0 (0)
  kurtosis: 0
  skewness: 0
  min: 1 (0.00392157)
  max: 255 (1)
  mean: 116.501 (0.456867)
  standard deviation: 102.305 (0.401195)
  kurtosis: -1.82316
  skewness: 0.0719237

Apparently Imagemagick does not care to change the name of the components from red, green, blue to HSV , but the mapping is accordingly. Take a note of the Green/Saturation channel, it has to have a max of 0, then you have grayscale.

Scans, Sepia and Stuff

For non-ideal input images, and for Sepia-like mono-chromatic images I would probably simply look into small variance of hue. Also this might still fail, as unsaturated colors may have any hue value without changing much.


With imagemagic you can use command identify to get info about the image

identify -verbose image.jpg

From the output you can check for standard deviation of red, blue and green. For grayscale images the should have very close values (theoretically equivalent values)
P.S. You can check also this site for some scripts for such tests

  • I think this is not necessarily true. The RGB values should correlate perfectly, but this is not deducible from looking at the variance. What you really need to check is whether the color values lie within a one-dimensional subspace of R^3. This condition would capture grayscale and "colorscale" images like sepia.
    – ziggystar
    Jun 26 '15 at 14:03
  • @ziggystar, please forgive my ignorance but for me b/w image mean i have only black, white and pure gray "colours" in the image. Of course there is probability i have 1/3 red, 1/3 green and 1/3 blue bands in the image and deviation will show equivalent values Jun 26 '15 at 14:22
  • 1
    Yes I was not clear, I'm looking for slight sepia too. They're scans so won't be computationally black and white Jun 26 '15 at 15:07
  • @OneSolitaryNoob I've added a short section about sepia to my answer, it's still not perfect.
    – ziggystar
    Jun 26 '15 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.