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

发布于 2024-12-07 08:01:38 字数 193 浏览 9 评论 0原文

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

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

我在这里需要使用什么?

I need a python method to open and import TIFF images into numpy arrays so I can analyze and modify the pixel data and then save them as TIFFs again. (They are basically light intensity maps in greyscale, representing the respective values per pixel)

I couldn't find any documentation on PIL methods concerning TIFF. I tried to figure it out, but only got "bad mode" or "file type not supported" errors.

What do I need to use here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

始终不够爱げ你 2024-12-14 08:01:38

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

First, I downloaded a test TIFF image from this page called a_image.tif. Then I opened with PIL like this:

>>> from PIL import Image
>>> im = Image.open('a_image.tif')
>>> im.show()

This showed the rainbow image. To convert to a numpy array, it's as simple as:

>>> import numpy
>>> imarray = numpy.array(im)

We can see that the size of the image and the shape of the array match up:

>>> imarray.shape
(44, 330)
>>> im.size
(330, 44)

And the array contains uint8 values:

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

Once you're done modifying the array, you can turn it back into a PIL image like this:

>>> Image.fromarray(imarray)
<Image.Image image mode=L size=330x44 at 0x2786518>
暮色兮凉城 2024-12-14 08:01:38

我使用 matplotlib 读取 TIFF 文件:

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

I 的类型为 ndarray

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

还有一个用于保存的 plt.imsave 函数。

I use matplotlib for reading TIFF files:

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

and I will be of type ndarray.

According to the documentation though it is actually PIL that works behind the scenes when handling TIFFs as matplotlib only reads PNGs natively, but this has been working fine for me.

There's also a plt.imsave function for saving.

Hello爱情风 2024-12-14 08:01:38

PyLibTiff 对我来说比 PIL 更好,截至 2023 年 4 月 仍然不支持每种颜色超过 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)

您可以使用

pip3 install numpy pylibtiff

PyLibTiff 的自述文件安装 PyLibTiff 还提到了 tifffile 库,但是我没试过。

PyLibTiff worked better for me than PIL, which as of April 2023 still doesn't support color images with more than 8 bits per color.

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)

You can install PyLibTiff with

pip3 install numpy pylibtiff

The readme of PyLibTiff also mentions the tifffile library but I haven't tried it.

毁我热情 2024-12-14 08:01:38

您也可以使用 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()

You could also use GDAL to do this. I realize that it is a geospatial toolkit, but nothing requires you to have a cartographic product.

Link to precompiled GDAL binaries for windows (assuming windows here)
Link

To access the array:

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()
溇涏 2024-12-14 08:01:38

对于图像堆栈,我发现使用 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)

In case of image stacks, I find it easier to use scikit-image to read, and matplotlib to show or save. I have handled 16-bit TIFF image stacks with the following code.

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)
冰之心 2024-12-14 08:01:38

有一个名为 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)

您可以阅读有关此软件包的更多信息 此处

There is a nice package called tifffile which makes working with .tif or .tiff files very easy.

Install package with pip

pip install tifffile

Now, to read .tif/.tiff file in numpy array format:

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

If you want to save a numpy array as a .tif/.tiff file:

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

or

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

You can read more about this package here.

羁拥 2024-12-14 08:01:38

您还可以使用我作为作者的 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,因此您可以读取大图像的部分内容。

You can also use pytiff of which I am the author.

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]

It's a fairly small module and may not have as many features as other modules, but it supports tiled TIFFs and BigTIFF, so you can read parts of large images.

微凉徒眸意 2024-12-14 08:01:38

使用CV2

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

Using cv2

import cv2
image = cv2.imread(tiff_file.tif)
cv2.imshow('tif image',image)
北笙凉宸 2024-12-14 08:01:38

如果您想使用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

if you want save tiff encoding with geoTiff. You can use rasterio package

a simple code:

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

for more detail about numpy 2 GEOTiff .you can click this: https://gis.stackexchange.com/questions/279953/numpy-array-to-gtiff-using-rasterio-without-source-raster

戏蝶舞 2024-12-14 08:01:38

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

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

I recommend using the python bindings to OpenImageIO, it's the standard for dealing with various image formats in the vfx world. I've ovten found it more reliable in reading various compression types compared to PIL.

import OpenImageIO as oiio
input = oiio.ImageInput.open ("/path/to/image.tif")
昔日梦未散 2024-12-14 08:01:38

读取 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 个通道。在查看 这篇文章,但仍然无法查看图像。

Another method of reading tiff files is using 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)

Output:

(512, 512, 4)

tensorflow documentation can be found here

For this module to work, a python package called tensorflow-io has to installed.

Athough I couldn't find a way to look at the output tensor (after converting to nd.array), as the output image had 4 channels. I tried to convert using cv2.cvtcolor() with the flag cv2.COLOR_BGRA2BGR after looking at this post but still wasn't able to view the image.

随遇而安 2024-12-14 08:01:38

这个问题的没有答案对我不起作用。所以我找到了另一种查看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

no answers to this question did not work for me. so i found another way to view tif/tiff files:

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

the code above will help you to view the tif files. also check below to be sure:

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

src.read(1) #prints the matrix
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文