在Python中使用numpy处理TIFF图像(导入、导出)
我需要一个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>