如何使用 matplotlib 读取 32 位整数图像?

How to read a 32-bit integer image using matplotlib?

我需要使用 Python2 从磁盘读取 单通道 32 位整数 TIFF 图像 以执行一些图像分析。我尝试了 matplotlib 中的 image.imread 但我无法让代码工作,因为数据被读取为 4 通道 8 位整数图像:

>>> import numpy as np
>>> import matplotlib.image as mpimg
>>> img = mpimg.imread('my_image.tif')
>>> img.shape
(52, 80, 4)
>>> img[0:2, 0:2]
array([[[255, 255, 255, 255],
        [255, 255, 255, 255]],

       [[255, 255, 255, 255],
        [255, 255, 255, 255]]], dtype=uint8)

问题:是否可以使用 matplotlib 读取单通道 32 位整数图像?

我知道在 Python 中有其他方法可以读取这样的图像,例如使用来自 PIL 的 Image.open

>>> from PIL import Image
>>> img = np.asarray(Image.open('my_image.tif'))
>>> img.dtype
dtype('int32')
>>> img.shape
(52, 80)
>>> img[0:2, 0:2]
array([[8745, 8917],
       [8918, 9479]])

另一种可能性是使用 scikit-learn 中的 io.imread

>>> from skimage import io
>>> img = io.imread('my_image.tif')

另一种方法是利用 OpenCV 的 imread 函数。但在这种情况下,数据必须转换为 32 位整数:

>>> import cv2
>>> img = cv2.imread('my_image.tif', -1)
>>> img[0:2, 0:2]
array([[  1.22543551e-41,   1.24953784e-41],
       [  1.24967797e-41,   1.32829081e-41]], dtype=float32)
>>> img.dtype = np.int32
>>> img[0:2, 0:2]
array([[8745, 8917],
       [8918, 9479]])

根据this tutorial,无法使用 matplotlib 读取 32 位整数图像:

Matplotlib plotting can handle float32 and uint8, but image reading/writing for any format other than PNG is limited to uint8 data.

作为参考,我从 SciPy 中找到了另一个基于 ndimage.imread 的解决方法:

from scipy import ndimage
img = ndimage.imread('my_image.tif', mode='I')

基于 tifffile 的方法(@Warren Weckesser 建议)也可以正常工作:

from tifffile import TiffFile

with TiffFile('my_image.tif') as tif:
    img = tif.asarray()

SciPy no longer supports imread (versions 1.3.0+)

您可以将 imageio 用于科学图像:

import imageio

im = imageio.imread('imageio:astronaut.png') 

im.shape  # im is a numpy array