Я пользуюсь Библиотекой Обработки изображений 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()
ожидать таблицу?это изображение. Только () правильный инструмент для Эта работа?
Действительно, Image.point ()
идеально подходит для этой работы
Какой формат / структура делает Image.point () Ожидайте таблицу?
Вы должны сгладить список, так что вместо [(12, 140, 10), (10, 100, 200), ...]
Использование:
[12, 140, 10, 10, 100, 200, ...]
Вот быстрый пример, который я просто попробовал:
im = im.point(range(256, 0, -1) * 3)
и, кстати, если вам нужно больше контроля над цветами, и вы чувствуете, что 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), ())
Я думаю, что мой первый пример должен продемонстрировать формируемый для вас.
Я думаю, что это могло бы быть более типичным для точки
для каждой полосы частот, как это (взято непосредственно из учебника 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)