Открыть список
Как стать автором
Обновить

Комментарии 25

PIL на Python

Всё же речь не о PIL, а о Pillow. Оригинальная библиотека PIL никогда не была внутри модуля PIL, это самодеятельность Pillow. Оригинальный PIL не разрабатывается с 2011-го и не существует для Python 3.


PIL работает с изображениями в формате RGB.

Pillow поддерживает режимы 1, L, P, RGB, RGBA, CMYK, YCbCr, LAB, HSV, I, F.


нам нужно получить среднее арифметическое значение

Это не единственный и при этом не самый лучший алгоритм обесцвечивания


r = pix[x, y][0]
g = pix[x, y][1]
b = pix[x, y][2]

r, g, b = pix[x, y] — даже такая мелочь ускоряет код на 20%

Спасибо. Статью немного дописал. Код писал с акцентом на понимание, а не на оптимизацию.

Правильная формула для получения серого цвета:
Y = 0.299 R + 0.587 G + 0.114 B

А правильная функция:
grayscale_image = image.convert("L")
НЛО прилетело и опубликовало эту надпись здесь
Да, в интернете много формул с акцентом на то, что цвета человеческий глаз воспринимает иначе и соответственно алгоритмы совершенно другие. Спасибо за замечание, статью дополнил, но для общего понимания, я считаю, приведённого алгоритма достаточно.
хорошее замечание

Вот бы вы еще написали что за PIL, о каких "более сложных алгоритмах обработки (изображений?)" идет речь и зачем вот это все надо.

Небольшой код ревью: у вас очень много одинакового кода в примерах, не было бы проще вынести отдельную функцию вроде handle(x, y, [ r, g, b]) и в каждом параграфе определить конкретную реализацию?


def handlePixel(( x, y ), [ r, g, b ]):
  pass

for x in range(width):
  for y in range(height):
    draw.point((x, y), handlePixel(( x, y ), pix[x, y]))

# позже в статье
def handlePixel(( x, y ), [ r, g, b ]):
  sr = (r + g + b) // 3
  return ( 255 - sr, 255 - sr, 255 - sr )

Ну и я бы использовал кортежы везде (вместо массива [r,g,b]), но эт такое

зачем у вас ( x, y ) в
def handlePixel(( x, y ), [ r, g, b ])
?

у меня отлично так работает, проверено лично в PyCharm:

def handlePixel(r, g, b):
    sr = (r + g + b) //3
    return (255 - sr, 255 - sr, 255 - sr )

for x in range(width):
  for y in range(height):
      r,g,b=pix[x, y]
      draw.point((x, y), handlePixel(r,g,b))

во-первых, странно что вам понадобилось запускать код в PyCharm чтобы это увидеть


во-вторых, да, можно и без этого обойтись — координаты не используются ни в одном куске кода. но как знать — может в какой-то момент и понадобится нечто большее? ;) например, для тех же фильтров пригодится окно изображения — размеры окна, координаты куда писать и данные пикселей окна. но принцип YAGNI говорит что не надо этот параметр функции добавлять =)


def handlePixel([ r, g, b ])

вполне себе заработает. передавать цвет пикселя массивом — банально проще:


# не нужно деструктурировать в три переменных здесь
draw.point((x, y), handlePixel(pix[x, y])
более того, вы в определении функции передаете параметры в таком виде
def handlePixel([ r, g, b ])

def handlePixel(( x, y ), [ r, g, b ])

(smiling)

не понял что вас смущает — pix[x, y] — это массив из трех элементов, я их деструктуририрую в определении функции, вроде ничего необычного. а координаты я передал в виде кортежа — просто так (на самом деле я думал что можно будет рисовать прямо в этой функции).

Запись со списком в заголовке определения функции — это синтаксическая ошибка.


Например, код


def f([a, b, c]):
    return a + b + c

просто упадёт с ошибкой парсинга.


Кстати, pix[x, y] — это не массив, а кортеж, если быть точным. Массивы могут быть многомерными и обычно ассоциируются с массивами Numpy или стандартным array.array. Здесь же функция просто возвращает три значения. И [r, g, b] — это тоже не массив, а список.

таки да, ~переоценил~ перепутал я питон с жаваскриптом, деструктурирование в параметрах функций отсутствует.

Снова люди, вчера изучившие питон, пытаются научить ему других. А потом все думают, что питон "медленный" и "непонятный"

Девочка няшная.
Насчёт PIL – не разбираюсь, однако же, не торопитесь закидывать помидорами. Имел опыт с OpenCV под плюсы и Пайтон и могу сообщить, что поток выполнения может проводить большУю часть времени в алгоритмах обработки, а не в отрисовке даже в плюсах.
Вывод 1 – большинство либ для рисования предоставляют подобный функционал не на одном языке.
Вывод 2 – язык Пайтон, к сожалению, не лучший для обработки изображений с большим количеством точек, как и для других нужд, где желательна (ну например) возможность обработки видео без потери кадров в секунду.

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

Фи, питон. Лучше бы что-нибудь поинтереснее выбрал:load 'media/imagekit'
load 'primitives'
mean =: +/ % #
round =: floor f. @ +&0.5
gray =: round f. @ #~&3"0 @ mean f. rows
negative =: 255&-
negative_gray =: negative f. @ gray f.

image =: read_image 'input.jpg'
(negative_gray image) write_image 'output.jpg'
view_image 'output.jpg'

Откройте для себя scikit-image и/или OpenCV и не занимайтесь ерундой. Писать на Python циклы с попиксельным обходом изображений — это бесперспективно и бессмысленно.


Pillow неплохая библиотека, но не для image processing. Хотя в ней несомненно есть некоторые функции обработки изображений. Кстати, рекомендую почитать.

В ней изображения обрабатываются циклами в Python. Я бы не стал эту статью кому-то советовать.

Да, только статьи уж больно похожи
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.