Подтвердить что ты не робот

Работа с TIFF (импорт, экспорт) в Python с использованием numpy

Мне нужна подпрограмма python, которая может открывать и импортировать изображения TIFF в массивы numpy, поэтому я могу анализировать и изменять содержащиеся данные, а затем сохранять их снова как TIFF. (Они представляют собой карты интенсивности света в оттенках серого, представляющие соответствующие значения на пиксель)

Я пытался найти что-то, но нет документации по методам PIL относительно TIFF. Я попытался понять это, но только получил неправильный режим/тип файла, не поддерживаемые ошибки.

Что мне нужно использовать здесь?

4b9b3361

Ответ 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.

В соответствии с документацией, хотя на самом деле PIL работает за кулисами при обработке TIFF, поскольку matplotlib только считывает PNG изначально, но это отлично работает для меня.

Также существует функция plt.imsave для сохранения.

Ответ 3

Вы также можете использовать GDAL для этого. Я понимаю, что это геопространственный инструментарий, но ничто не требует от вас картографического продукта.

Ссылка на предварительно скомпилированные двоичные файлы GDAL для окон (при условии, что здесь находятся окна) 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()

Ответ 4

pylibtiff работал лучше для меня, чем PIL, который не поддерживает цветные изображения с более чем 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

В readme of pylibtiff также упоминается tifffile.py, но я не пробовал.

Ответ 5

Вы также можете использовать 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]

Это довольно небольшой модуль и может иметь не так много функций, как другие модули, но он поддерживает tiled tiff и bigtiff, поэтому вы можете читать части больших изображений.

Ответ 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)

Ответ 7

Я рекомендую использовать привязки Python к OpenImageIO, это стандарт для работы с различными форматами изображений в мире vfx. Я нашел его более надежным при чтении различных типов сжатия по сравнению с PIL.

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