Ben Gorman

Ben Gorman

Life's a garden. Dig it.

Challenge

One of these three images is not a grayscale image.

Tomatoes 1 Tomatoes 1

Tomatoes 2 Tomatoes 2

Tomatoes 3 Tomatoes 3

Download each image and do some investigative work in Python to figure out which one is the grayscale imposter.

Bonus

When I originally put this problem together, I tried using JPEG files instead of PNGs. But every time I saved the imposter image, it reverted back to being a non-imposter.

What was my mistake?

Solution

Tomatoes 2 is the imposter!

Grayscale images are usually represented by a 2-Dimensional array like this

Grayscale as 2-D array
[[0.1, 0.0, 0.9]
 [0.0, 0.3, 0.0]
 [0.1, 0.0, 0.5]]

However, when you load a PNG file into Python with XXX or YYY and convert it to an array, you'll get back a 3-Dimensional array with Red, Green, and Blue color channels included.

Grayscale as 3-D array
[[[0.1, 0.1, 0.1], [0.0, 0.0, 0.0], [0.9, 0.9, 0.9]]
 [[0.0, 0.0, 0.0], [0.3, 0.3, 0.3], [0.0, 0.0, 0.0]]
 [[0.1, 0.1, 0.1], [0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]],

In such cases, gray pixels have an equal amount of each color channel. So, for a grayscale image, R == G == B for every pixel.

With this in mind, we can do some basic NumPy array logic to find the imposter.

import numpy as np
from PIL import Image
 
def is_grayscale(filepath):
    """Given the path to an image file, check if it's a grayscal image"""
    
    # Load the image file
    img = Image.open(filepath)
    
    # Convert to array
    arr = np.array(img)
    
    # Check if R == G == B for every pixel
    rg = np.all(arr[:, :, 0] == arr[:, :, 1])
    rb = np.all(arr[:, :, 0] == arr[:, :, 2])
    
    return bool(rg & rb)
 
is_grayscale("CV-tomatoes1.png")  # true
is_grayscale("CV-tomatoes2.png")  # false
is_grayscale("CV-tomatoes3.png")  # true

Bonus Solution

JPEG uses lossy compression whereas PNG uses lossless compression.

When I saved my JPEG file, the compression algorithm decided that my slightly not-gray pixel was unimportant enough to be discarded.

In general, this is why people often recommend using PNG when you care about preserving quality and JPEG when you care about minimizing file size.