how to get the number of channels from an image, in OpenCV 2?

Question:

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.

Asked By: LarsH

||

Answers:

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

Answered By: Abid Rahman K

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

Answered By: abhiTronix

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.

Answered By: songofhawk

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)

Answered By: desmond13
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.