在Python中使用numpy处理TIFF图像(导入、导出)

138 投票
12 回答
395383 浏览
提问于 2025-04-17 03:11

我需要一个Python的方法,能够打开TIFF格式的图片,并把它们导入到numpy数组中,这样我就可以分析和修改每个像素的数据,然后再把它们保存回TIFF格式。(这些图片基本上是灰度的光强度图,表示每个像素的具体值)

我找不到关于PIL库处理TIFF格式的相关文档。我尝试自己搞明白,但总是遇到“模式错误”或“文件类型不支持”的问题。

我需要用什么呢?

12 个回答

27

PyLibTiff 对我来说比 PIL 更好用,因为截至 2023 年 4 月,PIL 仍然不支持 每种颜色超过 8 位的彩色图像。

from libtiff import TIFF

tif = TIFF.open('filename.tif') # open tiff file in read mode
# read an image in the current TIFF directory as a numpy array
image = tif.read_image()

# read all images in a TIFF file:
for image in tif.iter_images(): 
    pass

tif = TIFF.open('filename.tif', mode='w')
tif.write_image(image)

你可以通过以下方式安装 PyLibTiff:

pip3 install numpy pylibtiff

PyLibTiff 的说明文档中还提到了 tifffile 这个库,但我还没有尝试过。

70

我用matplotlib来读取TIFF文件:

import matplotlib.pyplot as plt
I = plt.imread(tiff_file)

而且I的类型会是ndarray

不过根据说明文档,其实在处理TIFF文件时,背后是PIL在工作,因为matplotlib本身只支持直接读取PNG格式的文件,但对我来说,这样用一直没问题。

还有一个plt.imsave函数可以用来保存文件。

153

首先,我从这个页面下载了一张测试用的TIFF图片,叫做a_image.tif。然后我用PIL打开它,代码是这样的:

>>> from PIL import Image
>>> im = Image.open('a_image.tif')
>>> im.show()

打开后,显示出了一幅彩虹的图片。要把它转换成numpy数组,其实很简单:

>>> import numpy
>>> imarray = numpy.array(im)

我们可以看到,图片的大小和数组的形状是匹配的:

>>> imarray.shape
(44, 330)
>>> im.size
(330, 44)

而且这个数组里面的值是uint8类型的:

>>> imarray
array([[  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       ..., 
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246],
       [  0,   1,   2, ..., 244, 245, 246]], dtype=uint8)

一旦你修改完这个数组,就可以像这样把它再转换回PIL图片:

>>> Image.fromarray(imarray)
<Image.Image image mode=L size=330x44 at 0x2786518>

撰写回答