我需要一个 python 方法来打开 TIFF 图像并将其导入 numpy 数组,以便我可以分析和修改像素数据,然后再次将它们保存为 TIFF。 (它们基本上是灰度的光强度图,代表每个像素的相应值)
我找不到任何关于 TIFF 的 PIL 方法的文档。我试图弄清楚,但只有“错误模式”或“不支持的文件类型”错误。
我需要在这里使用什么?
首先,我从这个页面下载了一个名为
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>
我使用 matplotlib 读取 TIFF 文件:
import matplotlib.pyplot as plt
I = plt.imread(tiff_file)
和
I
将是 ndarray
.
根据文档,虽然在处理 TIFF 时实际上是 PIL 在幕后工作,因为 matplotlib 仅本地读取 PNG,但这对我来说一直很好。
还有
plt.imsave
保存功能
您也可以使用 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()
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
tifffile
库,但我没有尝试过。
在图像堆栈的情况下,我发现使用
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)
你也可以使用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,因此您可以读取大图像的部分内容。
有一个名为
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)
您可以在这里阅读更多关于这个包的信息。
import cv2
image = cv2.imread(tiff_file.tif)
cv2.imshow('tif image',image)
如果你想用
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
我建议使用 Python 绑定到 OpenImageIO,它是处理 vfx 世界中各种图像格式的标准。与 PIL 相比,我经常发现它在读取各种压缩类型时更可靠。
import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")
另一种读取 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
进行转换,但仍然无法查看图像。
这个问题的答案对我不起作用。所以我找到了另一种查看 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