Python PIL For Loop для работы с TIFF с несколькими изображениями

Каждый файл tiff содержит 4 изображения. Я не хочу извлекать и сохранять их, если это возможно, я просто хотел бы использовать цикл for для просмотра каждого из них. (например, посмотрите на пиксель [0,0] ) и в зависимости от того, какого он цвета во всех 4, я буду что-то делать соответственно.

Возможно ли это с помощью PIL? Если нет, что я должен использовать.


person 1478963    schedule 03.09.2013    source источник


Ответы (5)


Вы можете использовать метод «искать» изображения PIL, чтобы иметь доступ к различным страницам tif (или кадрам анимированного gif).

from PIL import Image

img = Image.open('multipage.tif')

for i in range(4):
    try:
        img.seek(i)
        print img.getpixel( (0, 0))
    except EOFError:
        # Not enough frames in img
        break
person MatthieuW    schedule 06.09.2013
comment
К вашему сведению, это решение работало в 1000 раз быстрее для более позднего доступа к отдельным пикселям в кадре (0,0002 с), чем библиотека pims (0,348093 с). pims предположительно основан на tiffile.py. PIL все еще был медленнее, чем opencv (6.7e-05sec), но opencv не поддерживает многостраничные tiff (стеки tiff). - person user391339; 28.05.2015

Вместо того, чтобы зацикливаться до EOFError, можно перебирать страницы изображений, используя PIL.ImageSequence (что фактически эквивалентно тому, что показано на исходный код).

from PIL import Image, ImageSequence

im = Image.open("multipage.tif")

for i, page in enumerate(ImageSequence.Iterator(im)):
    page.save("page%d.png" % i)
person Maxim    schedule 13.12.2017

Пришлось сделать то же самое сегодня,

Я следовал коду @stochastic_zeitgeist с улучшением (не выполняйте ручной цикл для чтения попиксельно), чтобы ускорить процесс.

from PIL import Image
import numpy as np

def read_tiff(path):
    """
    path - Path to the multipage-tiff file
    """
    img = Image.open(path)
    images = []
    for i in range(img.n_frames):
        img.seek(i)
        images.append(np.array(img))
    return np.array(images)
person Mohd Shahril    schedule 12.06.2019

Вот метод, который читает многостраничный TIFF и возвращает изображения в виде массива numpy

from PIL import Image
import numpy as np

def read_tiff(path, n_images):
    """
    path - Path to the multipage-tiff file
    n_images - Number of pages in the tiff file
    """
    img = Image.open(path)
    images = []
    for i in range(n_images):
        try:
            img.seek(i)
            slice_ = np.zeros((img.height, img.width))
            for j in range(slice_.shape[0]):
                for k in range(slice_.shape[1]):
                    slice_[j,k] = img.getpixel((j, k))

            images.append(slice_)

        except EOFError:
            # Not enough frames in img
            break

    return np.array(images)
person stochastic_zeitgeist    schedule 05.07.2017
comment
PIL/Pillow хранит и ссылается на изображения, используя [col, row], тогда как numpy использует [row, col]. Я заставил приведенный выше код работать, изменив расположение высоты и ширины, то есть slice_ = np.zeros((img.width, img.height)) - person StuckInPhDNoMore; 09.11.2018
comment
Количество кадров в файле TIFF хранится в свойстве n_frames. Кроме того, чтобы преобразовать их в массив numpy, вам не нужно копировать каждый отдельный пиксель - это так же просто, как numpy.array(image), где image - изображение PIL. - person Maksym Ganenko; 16.04.2019

Благодаря ответам в этой теме я написал этот модуль Python для чтения и работы с многостраничными tiff-файлами: https://github.com/mpascucci/multipagetiff

Он также позволяет кодировать стек изображений цветом «по глубине» и делать z-проекции.

Надеюсь, это может помочь

person MarcoP    schedule 10.11.2019