SooIn
SooIn

Reputation: 33

How to check whether a jpeg image is color or grayscale using only Python PIL? (not using OpenCV)

I found this method really helpful and it's actually working quite accurately. BUT this uses OpenCV.. and I want to use the same method using PIL.

code using PIL instead of OpenCV:

from PIL import Image
import numpy as np

###test image
img=Image.open('')
img=img.load()

### splitting b,g,r channels
r,g,b=img.split()

### getting differences between (b,g), (r,g), (b,r) channel pixels
r_g=np.count_nonzero(abs(r-g))
r_b=np.count_nonzero(abs(r-b))
g_b=np.count_nonzero(abs(g-b))

### sum of differences
diff_sum=float(r_g+r_b+g_b)

### finding ratio of diff_sum with respect to size of image
ratio=diff_sum/img.size

if ratio>0.005:
    print("image is color")
else:
    print("image is greyscale")

I changed cv2.imread('') to Image.open('') and added img=img.load(). and I changed b,g,r=cv2.split(img) to r,g,b=img.split()

I know that split() method exists in PIL. but I'm having this error.

AttributeError: 'PixelAccess' object has no attribute 'split'

How can I solve this? Thank you in advance!!

Upvotes: 2

Views: 1382

Answers (1)

stateMachine
stateMachine

Reputation: 5805

You are mixing data types like you are mixing Red Bull and Vodka. The load method is producing the error because it converts the PIL image into a PixelAccess object, an you need a PIL image for split(). Also, count_nonzero() does not work because it operates on NumPy arrays, and you are attempting to call that method on a PIL image. Lastly, size returns a tuple (width and height) of the image, so you need to modify your code accordingly:

from PIL import Image
import numpy as np

###test image
img=Image.open("D://opencvImages//lena512.png")

### splitting b,g,r channels
r,g,b=img.split()

### PIL to numpy conversion:
r = np.array(r)
g = np.array(g)
b = np.array(b)

### getting differences between (b,g), (r,g), (b,r) channel pixels
r_g=np.count_nonzero(abs(r-g))
r_b=np.count_nonzero(abs(r-b))
g_b=np.count_nonzero(abs(g-b))

### sum of differences
diff_sum=float(r_g+r_b+g_b)

### get image size:
width, height = img.size

### get total pixels on image:
totalPixels = width * height

### finding ratio of diff_sum with respect to size of image
ratio = diff_sum/totalPixels

print("Ratio is: "+ratio)

if ratio>0.005:
    print("image is color")
else:
    print("image is greyscale")

Let's check out the Lena image in color and grayscale:

Color Lena returns this:

Ratio is: 2.981109619140625
image is color

And Grayscale Lena returns this:

Ratio is: 0.0
image is greyscale

Upvotes: 3

Related Questions