Kkov
Kkov

Reputation: 1512

OpenCV - Reading a 16 bit grayscale image

I'm trying to read a 16 bit grayscale image using OpenCV 2.4 in Python, but it seems to be loading it as 8 bit.

I'm doing:

im = cv2.imread(path,0)
print im

[[25 25 28 ...,  0  0  0]
[ 0  0  0 ...,  0  0  0]
[ 0  0  0 ...,  0  0  0]
..., 

How do I get it as 16 bit?

Upvotes: 40

Views: 63564

Answers (5)

K. Bogdan
K. Bogdan

Reputation: 535

Just complementing the other answers. The -1 flag corresponds to the cv2.IMREAD_UNCHANGED flag. You can check all flags available in the imread modes documentation with its corresponding values at the imread codes definition. It is a good practice to use the flags instead of the values directly, as other users pointed out, since the flags values are prone to changes.

Example from OpenCV 4.9.0 version.

   IMREAD_UNCHANGED = -1, // If set, return the loaded image as is (with alpha channel, otherwise it gets cropped). Ignore EXIF orientation.
   IMREAD_ANYDEPTH  = 2,  // If set, return 16-bit/32-bit image when the input has the corresponding depth, otherwise convert it to 8-bit.

So, to read your 16-bit grayscale image, the following flag could be enough:

image = cv2.imread(path, cv2.IMREAD_ANYDEPTH)

But, cv2.IMREAD_ANYDEPTH does not preserve the color channels as expected and if you are not sure if the image has color channels or is in fact 16-bit to further check after reading, is better to read with cv2.IMREAD_UNCHANGED as it tries to preserve the original image contents:

image = cv2.imread(path, cv2.IMREAD_UNCHANGED)

Upvotes: 0

Breadman10
Breadman10

Reputation: 111

This question suggests that image = cv2.imread('16bit.png', cv2.IMREAD_UNCHANGED) will also solve your problem.

Upvotes: 5

Kkov
Kkov

Reputation: 1512

Figured it out. In case anyone else runs into this problem:

im = cv2.imread(path,-1)

Setting the flag to 0, to load as grayscale, seems to default to 8 bit. Setting the flag to -1 loads the image as is.

Upvotes: 52

Thomio
Thomio

Reputation: 1433

To improve readability use the flag cv2.IMREAD_ANYDEPTH

image = cv2.imread( path, cv2.IMREAD_ANYDEPTH )

Upvotes: 39

Eric Olmon
Eric Olmon

Reputation: 1089

I had the same issue (16-bit .tif loading as 8-bit using cv2.imread). However, using the -1 flag didn't help. Instead, I was able to load 16-bit images using the tifffile package.

Upvotes: 9

Related Questions