使用numpy在Python中使用TIFF(导入,导出)


84

我需要一个python方法来打开TIFF图像并将其导入到numpy数组中,以便我可以分析和修改像素数据,然后再次将它们另存为TIFF。(它们基本上是灰度的光强度图,代表每个像素的相应值)

我找不到有关TIFF的PIL方法的任何文档。我试图弄清楚,但仅收到“错误模式”或“不支持的文件类型”错误。

我需要在这里使用什么?

Answers:


103

首先,我从此页面下载了名为的测试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>

4
我在数据类型方面遇到麻烦。对于某些工作正常,例如,如果我的数组中有numpy.int16数字,但对于numpy.uint16 image.fromarray,结果为:“ TypeError:无法处理此数据类型”
Jakob

4
从fromarray的源看,它似乎不处理无符号的16位数组。
jterrace 2011年

截至2020年6月,@ Jakob PIL不支持每种颜色的位数超过8位的彩色图像,您将不得不使用其他库(或自行提供功能)。
鲍里斯

56

我使用matplotlib读取TIFF文件:

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

并将I为类型ndarray

根据文档,尽管实际上是PIL在处理TIFF时在后台工作,因为matplotlib仅本地读取PNG,但这对我来说一直很好。

还有一个plt.imsave保存功能。


到目前为止,这是使用TIFF的最简单方法!尝试了十几种方法,而这一切都是门票。肯定支持!
zachd1_618

观看部分呢?
Monica Heddneck '18

5
matplotlib似乎改变了策略:ValueError: Only know how to handle extensions: ['png']; with Pillow installed matplotlib can handle more images
strpeter

17

您也可以使用GDAL执行此操作。我意识到这是一个地理空间工具包,但没有什么要求您拥有地图产品。

链接到用于Windows的预编译GDAL二进制文件(此处假定为Windows) http://www.gisinternals.com/sdk/

要访问阵列:

from osgeo import gdal

dataset = gdal.Open("path/to/dataset.tiff", gdal.GA_ReadOnly)
for x in range(1, dataset.RasterCount + 1):
    band = dataset.GetRasterBand(x)
    array = band.ReadAsArray()

上面的代码是单个TIF还是多页TIF?我想使用gdal将16位的tiff堆栈加载到nparrays中。
user391339 2015年

这应该读入输入数据类型,或者将所有内容移至numpy的float64。您可以在.astype(sometype)通话结束时添加通话以ReadAsArray()进行投射。不确定是否可以制作副本(只是未经测试)。
Jzl5325

@Chikinn来自点评:stackoverflow.com/review/suggested-edits/17962780 xrange不是错字,xrange是的python 2版本range。我接受了此修改,因为python 3仍在积极改进,而python 2却没有。
abccd

12

pylibtiff对我来说比PIL更好,后者截至2020年6月不支持每种颜色超过8位的彩色图像

from libtiff import TIFF

tif = TIFF.open('filename.tif') # open tiff file in read mode
# read an image in the currect 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 libtiff

pylibtiff的自述文件也提到了tifffile,但是我还没有尝试过,尽管它表面上是开源的,但我认为该代码已不再可用(除了从PyPI软件包中手动提取代码之外)。


2
这是非常好的。到目前为止,tifffile已包含在SciKit skimage.external.tifffile中,但是如果您从Christoph Gohlke先生那里下载tifffile.py,也可以将其作为模块导入
lesolorzanov

7

您也可以使用我是作者的pytiff

    import pytiff

    with pytiff.Tiff("filename.tif") as handle:
        part = handle[100:200, 200:400]

    # multipage tif
    with pytiff.Tiff("multipage.tif") as handle:
        for page in handle:
            part = page[100:200, 200:400]

这是一个很小的模块,可能没有其他模块那么多的功能,但是它支持切片tiff和bigtiff,因此您可以读取大图像的一部分。


此功能正是我所需要的!(能够读取大文件的一小部分)。但是,当我尝试点安装时,出现gcc错误
Fractaly

如果您使用错误消息创建问题,我将查看是否可以解决问题。
hnfl

是的,我也很感兴趣,但是在尝试安装它时也出现了错误。我是通过点子实现的-在Windows和Ubuntu下。不幸的是,它不起作用!我在这里创建了一个问题:github.com/FZJ-INM1-BDA/pytiff/issues/15
Dobedani

6

对于图像堆栈,我发现它更易于scikit-image阅读,matplotlib显示或保存。我已经使用以下代码处理了16位TIFF图像堆栈。

from skimage import io
import matplotlib.pyplot as plt

# read the image stack
img = io.imread('a_image.tif')
# show the image
plt.imshow(mol,cmap='gray')
plt.axis('off')
# save the image
plt.savefig('output.tif', transparent=True, dpi=300, bbox_inches="tight", pad_inches=0.0)

0

我建议使用与OpenImageIO的python绑定,这是处理vfx世界中各种图像格式的标准。我发现ovten与PIL相比,在读取各种压缩类型时更可靠。

import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")

除非已经有编译器,否则无法在Windows上安装Borderline。
吉米·卡特
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.