Работа с TIFF (импорт, экспорт) в Python с использованием numpy - PullRequest
60 голосов
/ 27 сентября 2011

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

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

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

Ответы [ 7 ]

77 голосов
/ 27 сентября 2011

Сначала я загрузил тестовое изображение в формате TIFF с этой страницы с именем a_image.tif. Затем я открыл PIL, как это:

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

Это показало изображение радуги. Чтобы преобразовать в простой массив, это просто:

>>> 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>
44 голосов
/ 27 сентября 2011

Я использую matplotlib для чтения файлов TIFF:

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

и I будут иметь тип ndarray.

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

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

13 голосов
/ 27 сентября 2011

Вы также можете использовать 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()
5 голосов
/ 05 июля 2017

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 для Pylibtiff также упоминается tifffile.py , но я не пробовал.

4 голосов
/ 17 ноября 2017

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

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

2 голосов
/ 01 июля 2018

В случае стеков изображений мне проще использовать 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)
0 голосов
/ 17 декабря 2018

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

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