Search code examples
pythonpython-3.xtiff

Python problem with exporting numpy matrix to tiff file using cv2.imshow then reading it


I am trying to export my NumPy matrix to a .tiff file then to read its contents to verify if it worked. Given the following snippet

import numpy as np
import cv2

data = np.array([[-0.1 for _ in range(128)] for _ in range(128)], dtype=np.float32)
cv2.imwrite('temp.tiff', data)
print('tiff file written')

image = cv2.imread('temp.tiff')
print(image)

returns

tiff file written
[ WARN:0@19.816] global /io/opencv/modules/imgcodecs/src/grfmt_tiff.cpp (629) readData OpenCV TIFF: TIFFRGBAImageOK: Sorry, can not handle images with 32-bit samples

So then I lower down the dtype parameter to dtype=np.float16

data = np.array([[-0.1 for _ in range(128)] for _ in range(128)], dtype=np.float16)

but then I get another error...

, line 50, in export_images_to_tiff
    cv2.imwrite('temp.tiff', a)
cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'imwrite'
> Overload resolution failed:
>  - img data type = 23 is not supported
>  - Expected Ptr<cv::UMat> for argument 'img'
[1]    24228 abort      python3 main.py

I am honestly going nuts with this feature I'm trying to implement. Is there any alternatives or fix to the above? I read the documentation but that didn't help, and looking online these error codes yield nothing relevant. Do I just assume that the tiff file was successfully written in the first 32-bit pass and call it a day?


Solution

  • cv2.imread() has a second parameter, flags, which specifies how to read the image file. According the the docs, the default value of the flags argument to imread() is this:

    IMREAD_COLOR
    If set, always convert image to the 3 channel BGR color image.

    Source: imread docs, IMREAD_COLOR docs.

    By default, OpenCV attempts to coerce a file into 3-channel color. Since you have only a single channel, that's not going to work. However, there is a flag which will work:

    image = cv2.imread('temp.tiff', cv2.IMREAD_UNCHANGED)
    

    (Thanks to this answer for pointing me in the right direction.)