使用 numpy 在 Python 中处理 TIFF(导入、导出)
- 2025-03-18 08:55:00
- admin 原创
- 44
问题描述:
我需要一种 Python 方法来打开 TIFF 图像并将其导入 numpy 数组,以便我可以分析和修改像素数据,然后再次将它们保存为 TIFF。(它们基本上是灰度光强度图,代表每个像素的相应值)
我找不到任何有关 TIFF 的 PIL 方法文档。我尝试解决它,但只收到“错误模式”或“文件类型不受支持”错误。
我这里需要用什么?
解决方案 1:
首先,我从这个名为的页面下载了一个测试 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>
解决方案 2:
我使用 matplotlib 读取 TIFF 文件:
import matplotlib.pyplot as plt
I = plt.imread(tiff_file)
并且I
将是 类型ndarray
。
虽然根据文档,在处理 TIFF 时实际上是 PIL 在后台工作,因为 matplotlib 只能本机读取 PNG,但这对我来说工作正常。
还有plt.imsave
保存功能。
解决方案 3:
对我来说, 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
库,但我还没有尝试过。
解决方案 4:
您也可以使用 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()
解决方案 5:
对于图像堆栈,我发现它更易于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)
解决方案 6:
有一个很好的软件包,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)
您可以在此处阅读有关此包的更多信息。
解决方案 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,因此您可以读取大图像的部分内容。
解决方案 8:
使用 cv2
import cv2
image = cv2.imread(tiff_file.tif)
cv2.imshow('tif image',image)
解决方案 9:
如果你想用 保存 tiff 编码geoTiff
。你可以使用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
解决方案 10:
我建议使用 OpenImageIO 的 Python 绑定,它是处理视觉特效世界中各种图像格式的标准。我发现与 PIL 相比,它在读取各种压缩类型方面更可靠。
import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")
解决方案 11:
读取 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 个通道。在查看此帖子cv2.cvtcolor()
后,我尝试使用标志进行转换,但仍然无法查看图像。cv2.COLOR_BGRA2BGR
解决方案 12:
这个问题没有答案,对我来说没有用。所以我找到了另一种查看 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
扫码咨询,免费领取项目管理大礼包!