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

问题描述 投票:0回答:12

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

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

我需要在这里使用什么?

python numpy python-imaging-library tiff
12个回答
144
投票

首先,我从这个页面下载了一个名为

a_image.tif
的测试TIFF图像。然后我用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>

66
投票

我使用 matplotlib 读取 TIFF 文件:

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

I
将是
ndarray
.

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

还有

plt.imsave
保存功能


20
投票

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

Windows 的预编译 GDAL 二进制文件链接(这里假设是 windows) 链接

访问数组:

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()

20
投票

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
库,但我没有尝试过。


13
投票

在图像堆栈的情况下,我发现使用

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(img,cmap='gray')
plt.axis('off')
# save the image
plt.savefig('output.tif', transparent=True, dpi=300, bbox_inches="tight", pad_inches=0.0)

10
投票

你也可以使用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,因此您可以读取大图像的部分内容。


9
投票

有一个名为

tifffile
的好包,它使处理 .tif 或 .tiff 文件变得非常容易。

使用 pip 安装包

pip install tifffile

现在,以 numpy 数组格式读取 .tif/.tiff 文件:

from tifffile import tifffile
image = tifffile.imread('path/to/your/image')
# type(image) = numpy.ndarray

如果你想将一个 numpy 数组保存为 .tif/.tiff 文件:

tifffile.imwrite('my_image.tif', my_numpy_data, photometric='rgb')

tifffile.imsave('my_image.tif', my_numpy_data)

您可以在这里阅读更多关于这个包的信息。


3
投票

使用 cv2

import cv2
image = cv2.imread(tiff_file.tif)
cv2.imshow('tif image',image)

1
投票

如果你想用

geoTiff
保存tiff编码。你可以使用
rasterio

一个简单的代码:

import rasterio

out = np.random.randint(low=10, high=20, size=(360, 720)).astype('float64')
new_dataset = rasterio.open('test.tiff', 'w', driver='GTiff',
                            height=out.shape[0], width=out.shape[1],
                            count=1, dtype=str(out.dtype),
                            )
new_dataset.write(out, 1)
new_dataset.close()

有关 numpy 2 GEOTiff 的更多详细信息。您可以单击此:https://gis.stackexchange.com/questions/279953/numpy-array-to-gtiff-using-rasterio-without-source-raster


0
投票

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

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

0
投票

另一种读取 tiff 文件的方法是使用 tensorflow api

import tensorflow_io as tfio
image = tf.io.read_file(image_path)
tf_image = tfio.experimental.image.decode_tiff(image)
print(tf_image.shape)

输出:

(512, 512, 4)

tensorflow 文档可以在这里

找到

要让这个模块工作,必须安装一个名为 tensorflow-io 的python 包

虽然我找不到查看输出张量的方法(在转换为 nd.array 之后),因为输出图像有 4 个通道。在看了

this post
之后,我尝试使用带有
cv2.cvtcolor()
标志的cv2.COLOR_BGRA2BGR进行转换,但仍然无法查看图像。


-1
投票

这个问题的答案对我不起作用。所以我找到了另一种查看 tif/tiff 文件的方法:

import rasterio
from matplotlib import pyplot as plt
src = rasterio.open("ch4.tif")
plt.imshow(src.read(1), cmap='gray')

上面的代码将帮助您查看tif文件。还要检查以下内容以确保:

type(src.read(1)) #see that src.read(1) is a numpy array

src.read(1) #prints the matrix
© www.soinside.com 2019 - 2024. All rights reserved.