Basic image information

Hello.
I am new to OpenCV and I am porting some software from C++ to Python (for a number of reasons), and in C++ it is pretty easy to get number of channels and bit depth from an image loaded with imread. In Python? Cannot find this most basic image data - there does not seem to be any methods equivalent to C++ channels() and depth(). Can anyone help? Thanks in advance.

Hi,
opencv image are numpy arrays : use img.shape to get number of rows columms and channel
tutorials in python are here

Thanks Laurent!
I have tried this but my problem was that I was not getting the same information as the C++ code for the same image. I have a TIFF image with indexed colors, the C++ code gives me image.channels() = 1, and Python image.shape = [h, w, 3].

…Would have uploaded the image but it doesn’t seems to accept TIFF files…

MRE is required. for both languages. we don’t know what you did.

the numpy shape (h,w,3) indicates 3-channel data. your claim that in C++ image.channels() returns 1 would suggest you have 1-channel data there.

so your codes must not be equivalent.

Hello.
It is the exact same image file, it is an indexed TIFF file which this forum engine forbids to upload unfortunately. I made test code in both C++ and Python:

C++

#include <opencv.hpp>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    cv::Mat input_image;
    cv::Size size;
    int numChannels = 0;
    string imageFile = "test.tif";

    input_image = cv::imread(imageFile, -1);
    if (input_image.data == NULL)
    {
        cout << "Could not open file " << imageFile << endl;
        return -1;
    }

    size = input_image.size();
    numChannels = input_image.channels();

    cout << imageFile << ": height=" << size.height << ", width=" << size.width << ", channels=" << numChannels << endl;

    return 0;
}

And Python:

import sys
import cv2

if __name__ == "__main__":
    imageFile="test.tif"
    inputImage = None

    try:
        inputImage = cv2.imread(imageFile, -1)
        if inputImage is None:
            print("Could not load image.")
            exit()
    except Exception as e:
        print("Exception - ",str(e))
        exit()
    imgHeight, imgWidth, numChannels = inputImage.shape
    print(f"{imageFile}: height={imgHeight}, width={imgWidth}, channels={numChannels}")
exit()

Output from C++:

test.tif: height=512, width=512, channels=1

Output from Python:

test.tif: height=512, width=512, channels=3

By the way, the C++ results is what I would expect, the Python result seem not to be correct.
Running opencv_version in terminal gives me 4.2.0.
Printing cv2.__version__ in Python gives me 4.6.0.

so it’s a fixed bug, or a regression. or whatever tiff library was upgraded and that changed the behavior.

you need to determine the behavior when you use the same version in both languages.

please use IMREAD_UNCHANGED instead of the magic constant -1.

Hello and thanks for your reply.

I built OpenCV 4.6 from source and yes, now I get the same results from C++ as I got with Python. It looks like imread converts the palette image to 3-channel image and totally breaks the old C++ code. The code is in the realm of GIS processing where channels are used differently so using OpenCV 4.6 is going to cause some additional work, if it will at all be possible…

Anyway, thanks a lot for your assistance!

Weird!
Can you post original image?

palette image? you didn’t say that before. is it a color palette or a grayscale palette?

hm, what to do with a palette image when IMREAD_UNCHANGED, is a tough design decision.

some people would want the palette data resolved into color. others would want the palette labels…

OpenCV is not prepared to handle palette data. there’s no way to carry the palette with the image (Mat).

you could propose (feature request/issue) a new IMREAD flag that gives you the palette labels only.

for the equivalent functionality in imwrite(), you’d probably need a new function that takes a label image and the corresponding palette in some form.

Hello,

It’s a TIFF file, the forum engine does not allow it to be uploaded. It does not seem to be specific to the image I was working with - I created a sample image in GIMP, switched it to indexed colors and saved it and tried to load it in OpenCV imread. It looks like at some point between version 4.2 and 4.6 the behavior of image loading has been changed.