- PVSM.RU - https://www.pvsm.ru -
Чтобы дойти до сложных алгоритмов обработки, стоит проанализировать стандартные схемы, с чего я и предлагаю начать.
Для примеров обработки будет использоваться изображение с различным наборов цветов:

Для старта нам потребуется два модуля библиотеки:
from PIL import Image, ImageDraw
Настроим инструменты для комфортной дальнейшей работы:
image = Image.open('test.jpg') # Открываем изображение
draw = ImageDraw.Draw(image) # Создаем инструмент для рисования
width = image.size[0] # Определяем ширину
height = image.size[1] # Определяем высоту
pix = image.load() # Выгружаем значения пикселей
PIL работает с изображениями в формате RGB.
Значения пикселя в изображении задаются в формате: (x,y),(red, green, blue), где x,y — координаты, а числовые значения RGB находятся в диапазоне от 0 до 255. То есть работаем с 8-битным изображением. [1]
Серый оттенок появляется в случае равенства всех палитр цветов, поэтому нам нужно получить среднее арифметическое значение во всех трёх пунктах:
for x in range(width):
for y in range(height):
r = pix[x, y][0] #узнаём значение красного цвета пикселя
g = pix[x, y][1] #зелёного
b = pix[x, y][2] #синего
sr = (r + g + b) // 3 #среднее значение
draw.point((x, y), (sr, sr, sr)) #рисуем пиксель
image.save("result.jpg", "JPEG") #не забываем сохранить изображение

Инверсия получается путём вычета из 255 текущего цвета:
for x in range(width):
for y in range(height):
r = pix[x, y][0]
g = pix[x, y][1]
b = pix[x, y][2]
draw.point((x, y), (255 - r, 255 - g, 255 - b))

Совмещая два предыдущих алгоритма можно написать следующий код:
for x in range(width):
for y in range(height):
r = pix[x, y][0]
g = pix[x, y][1]
b = pix[x, y][2]
sr = (r + g + b) // 3
draw.point((x, y), (255 - sr, 255 - sr, 255 - sr))

Для этого алгоритма нужно определить пороговое значение, которое я возьму за 100:
for x in range(width):
for y in range(height):
r = pix[x, y][0]
g = pix[x, y][1]
b = pix[x, y][2]
if (r+g+b)>100: #если сумма значений больше 100 , то используем инверисю
sr = (r + g + b) // 3
draw.point((x, y), (255-sr, 255-sr, 255-sr))
else: #иначе обычный оттенок серого
sr = (r + g + b) // 3
draw.point((x, y), (sr, sr, sr))

В следующих статьях я хотел бы рассказать о том, как более локально подходить к фильтрации изображения, путём разделения его на области, а также показать интересные возможности DFS [2] в алгоритмах обработки изображения
Автор: Yunow
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/317050
Ссылки в тексте:
[1] 8-битным изображением.: https://ru.wikipedia.org/wiki/%D0%93%D0%BB%D1%83%D0%B1%D0%B8%D0%BD%D0%B0_%D1%86%D0%B2%D0%B5%D1%82%D0%B0
[2] DFS: https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%B2_%D0%B3%D0%BB%D1%83%D0%B1%D0%B8%D0%BD%D1%83
[3] Источник: https://habr.com/ru/post/451074/?utm_campaign=451074
Нажмите здесь для печати.