Используя Image.point () метод в PIL для управления пиксельными данными

Я пользуюсь Библиотекой Обработки изображений Python к colorize черно-белое изображение с таблицей поиска, которая определяет цветные отношения. Таблица поиска является просто списком с 256 элементами кортежей RGB:

>>> len(colors)
256
>>> colors[0]
(255, 237, 237)
>>> colors[127]
(50, 196, 33)
>>> 

Моя первая версия, используемая getpixel() и putpixel() методы:

    for x in range(w):
        for y in range(h):
            pix = img.getpixel((x,y))
            img.putpixel((x,y), colors[pix[0]])

Это было ужасно медленно. A profile отчет, на который указывают putpixel и getpixel методы как преступники. Немного расследования (т.е., прочитайте документы), и я нахожу "Примечание, что этот метод является относительно медленным". ре: putpixel. (фактическое время выполнения: 53 в putpixel и 50-е getpixel для 1024x1024 изображение)

На основе предложения в документах я использовал im.load() и прямой пиксельный доступ вместо этого:

    pixels = img.load()
    for x in range(w):
        for y in range(h):
            pix = pixels[x, y]
            pixels[x, y] = colors[pix[0]]                

Обработка, ускоренная порядком величины, но, является все еще медленной: приблизительно 3,5 с для обработки 1024x1024 изображение.

Более полное исследование документов PIL, кажется, указывает Image.point() точно предназначается с этой целью:

im.point(table) => изображение

im.point(function) => изображение

Возвращает копию изображения, где каждый пиксель был отображен через данную таблицу. Таблица должна содержать 256 значений на полосу в изображении. Если функция используется вместо этого, она должна взять отдельный аргумент. Функция вызвана однажды для каждого возможного пиксельного значения, и получающаяся таблица применяется ко всем полосам изображения.

Я провел некоторое время, бездельничая с интерфейсом, но, может вполне казаться, не разбираюсь в нем. Простите мое незнание, но документы PIL кратки, и у меня нет большого опыта обработки изображений. Я погуглил вокруг немного и поднял несколько примеров, но ничто, что сделало использование "щелчком" для меня. Таким образом, наконец, мои вопросы:

  • Image.point() правильный инструмент для этого задания?
  • Что делает формат/структура Image.point() ожидать таблицу?
  • Кто-то может набросать вчерне реализацию в качестве примера? Каждое повторение, которое я попробовал до сих пор, закончилось с прямым черным изображением.

19
задан J.J. 2 February 2010 в 01:12
поделиться

2 ответа

это изображение. Только () правильный инструмент для Эта работа?

Действительно, Image.point () идеально подходит для этой работы

Какой формат / структура делает Image.point () Ожидайте таблицу?

Вы должны сгладить список, так что вместо [(12, 140, 10), (10, 100, 200), ...] Использование:

[12, 140, 10, 10, 100, 200, ...]

Вот быстрый пример, который я просто попробовал:

im = im.point(range(256, 0, -1) * 3)

alt text alt text

и, кстати, если вам нужно больше контроля над цветами, и вы чувствуете, что image.point не для вас, вы также можете использовать Image.getdata и Image.PutData Чтобы изменить цвета быстрее, чем нагрузка , так и Putpixel . Это медленнее, чем изображение . Точка , хотя.

Image.getData Дает список всех пикселей, измените их и записывайте их обратно с помощью Image.putdata . Это так просто. Но попробуйте сделать это, используя Image.point Сначала.


Редактировать

Я допустил ошибку в первом объяснении, теперь я сейчас объясню:

Цветовая таблица на самом деле похож на этот

[0, 1, 2, 3, 4, 5, ...255, 0, 1, 2, 3, ....255, 0, 1, 2, 3, ...255]

каждая диапазон полосы рядом с другой. Чтобы изменить цвет (0, 0, 0) до (10, 100, 10). Это должно стать так:

[10, 1, 2, 3, 4, 5, ...255, 100, 1, 2, 3, ....255, 10, 1, 2, 3, ...255]

Чтобы преобразовать свой цветный список в правильный формат, попробуйте:

table = sum(zip(*colors), ())

Я думаю, что мой первый пример должен продемонстрировать формируемый для вас.

15
ответ дан 30 November 2019 в 04:59
поделиться

Я думаю, что это могло бы быть более типичным для точки для каждой полосы частот, как это (взято непосредственно из учебника PIL ):

# split the image into individual bands
source = im.split()

R, G, B = 0, 1, 2

# select regions where red is less than 100
mask = source[R].point(lambda i: i < 100 and 255)

# process the green band
out = source[G].point(lambda i: i * 0.7)

# paste the processed band back, but only where red was < 100
source[G].paste(out, None, mask)

# build a new multiband image
im = Image.merge(im.mode, source)
3
ответ дан 30 November 2019 в 04:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: