I am trying to find a way to get the number of channels of an image using Pillow. This seems rather trivial but I couldn't find it (the simple answer).
I know I can work it around with a minor overhead like (2 possibilities thought):
array.shape
image.size[0]*image.size[1]
against len(image.getdata())
so I am not really interested in finding a working solution but rather in accomplishing this using pillow.
The code I am using is straight forward:
from PIL import Image
image = Image.open(image_path)
image.size # <- this gives the size of the image but not the channel as in numpy.
(609, 439)
I also found this approach inspired by this answer (which also imports overhead of course):
num_channel = len(image.split())
To me it seems really peculiar I cannot find this simple answer.
I decided to answer my own question (although I basically will sum up the comment of @cryptonome).
Well, when it comes to PIL the options as I get it are:
image.mode
: returns a str containing the mode of the data read. Typical values are "RGB"
and "L"
for RGB and gray-scale images respectively. Modes are presented here.im2.info
: which returns a dict containing various information about the image. This is image format specific. For jpg images for example it (possibly) contains fields with keys:
dpi
, jfif
, jfif_density
, exif
etc. More information about jpg images can be found here.image.getbands()
: which returns a tuple (even a 1 element one) containing all different channel present in the data. For a typical RGB image this would be ('R', 'G', 'B')
and for a typical gray-scale image would be ('L',)
.So, judging from the above the more concise method in my opinion would be to compare image.mode
against L
and RGB
strings to find if an image is gray-scale or not or if the number of channels (as in this question) is the main question then a simple len(image.getbands())
would do the job.
Normally len(image.mode)
will coincide with len(image.getbands())
and could be used in its place but since there is at least one mode YCbCr
which contains 5 characters but only 3 channels (3x8-bit pixels, color video format) it's safer to use len(image.getbands())
I guess.