The answers at Can I determine the number of channels in cv::Mat Opencv answer this question for OpenCV 1: you use the Mat.channels() method of the image.

But in cv2 (I’m using 2.4.6), the image data structure I have doesn’t have a channels() method. I’m using Python 2.7.

Code snippet:

cam = cv2.VideoCapture(source)
ret, img = cam.read()
# Here's where I would like to find the number of channels in img.

Interactive attempt:

>>> img.channels()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AttributeError: 'numpy.ndarray' object has no attribute 'channels'
>>> type(img)
<type 'numpy.ndarray'>
>>> img.dtype
dtype('uint8')
>>> dir(img)
['T',
 '__abs__',
 '__add__',
...
 'transpose',
 'var',
 'view']
# Nothing obvious that would expose the number of channels.

Thanks for any help.

Use img.shape

It provides you the shape of img in all directions. ie number of rows, number of columns for a 2D array (grayscale image). For 3D array, it gives you number of channels also.

So if len(img.shape) gives you two, it has a single channel.

If len(img.shape) gives you three, third element gives you number of channels.

For more details, visit here

I’m kind of late but there is another simple way out there:

Use image.ndim Source, will give your right number of channels as below:


if image.ndim == 2:

    channels = 1 #single (grayscale)

if image.ndim == 3:

    channels = image.shape[-1]

Edit: In one-liners:

channels = image.shape[-1] if image.ndim == 3 else 1

Since a image is a nothing but a numpy array. Checkout OpenCV docs here: docs

As i know, u should use image.shape[2] to determine number of channels, not len(img.shape), the latter gives the dimensions of the array.

I would like to add here a self-contained script using the PIL library and another one using the cv2 library

CV2 Library script

import cv2
import numpy as np

img = cv2.imread("full_path_to_image")

img_np = np.asarray(img)

print("img_np.shape: ", img_np.shape)

The last column of the last print will show the number of channels, for example

img_np.shape: (1200, 1920, 4)

PIL Library script

from PIL import Image
import numpy as np

img = Image.imread("full_path_to_image")

img_np = np.asarray(img)

print("img_np.shape: ", img_np.shape)

The last column of the last print will show the number of channels, for example

img_np.shape: (1200, 1920, 4)

Note: from the scripts above you would be tempted (I was) to use img_np.shape[2] to retrieve the number of channels. However, if your image contains 1 channel (e.g., grayscale), that line would give you a problem (IndexError: tuple index out of range). Instead with just a simple print of shape (as I did in my script) you will get something like this

img_np.shape: (1200, 1920)