Комментарии 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]
), но эт такое
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. Хотя в ней несомненно есть некоторые функции обработки изображений. Кстати, рекомендую почитать.
PIL на Python от простого к сложному