Eypros
Eypros

Reputation: 5723

Number of channels in pil (pillow) image

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):

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.

Upvotes: 31

Views: 60627

Answers (1)

Eypros
Eypros

Reputation: 5723

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.

Upvotes: 63

Related Questions