Автор телеграм-канала CODE BLOG Вадим Шванов написал для нас статью о работе с изображениями c использованием языка Python и Pillow. В ней он рассматривает основы работы с изображениями в Python, показывает, как создать фильтры для фотографий в библиотеке Pillow, преобразовать изображение в массив в библиотеке NumPy и использовать matplotlib для настраиваемого вывода результата на экран.
Дочитайте до конца: там вы найдете ссылку на .ipynb-документ со всем используемым кодом, который вы сможете загрузить.
Кому это нужно?
Обработку изображений применяют в разных сферах. Например:
- создание своего фоторедактора;
- создание масок для Instagram;
- анализ и распознавание образов в компьютерном зрении.
А я справлюсь?
В инструкции используются простые операции, поэтому она подойдет для новичков — достаточно уметь немного кодить на Python.
Установка пакетов
NumPy и matplotlib можно установить с помощью пакетного менеджера pip, запустив следующие команды в терминале:
pip install numpy
pip install matplotlib
С Pillow сложнее: Python старше версии 3.6 поддерживает установку этого пакета через pip, а с другими версиями может возникнуть ошибка. Совместимость версий можно посмотреть тут.
Для этого примера в качестве среды разработки выбран Jupyter Notebook.
Начало работы
Импортируйте все необходимые модули и загрузите изображение в объект Python:
Как правило, NumPy импортируется с псевдонимом np, а matplotlib.pyplot — plt.
Загрузите изображение с помощью функции open() подмодуля Image:
Jupyter Notebook выводит изображения по их имени. Вот то самое изображение, путь к которому мы передали в функцию:
Далее мы создадим свою функцию, чтобы у нас была возможность добавить надпись над фотографией (заголовок) или изменить ее размер.
Вывод изображений с matplotlib
Это функция, которую мы будем использовать далее:
Она принимает два параметра: img — массив, который вы получили из исходной фотографии, и title — заголовок, который по умолчанию имеет значение None. Измените размеры фигуры на 6×6, чтобы сделать вывод изображения больше, и выведите его на экран. Также проверьте, был ли указан заголовок. Если нет — установите его с помощью функции title(). Выключите пометки на осях, указав ‘off’ в функции axis().
Как сделать изображение черно-белым
Здесь мы будем использовать метод convert() класса изображения PIL.
Функция выглядит просто:
Мы представили изображение в RGB-формате, то есть каждый пиксель имеет три значения: красный (R), зеленый (G) и синий (B). Оттенки серого получаются, когда все эти три значения равны. Есть известная формула яркости пикселя:
Но Pillow использует свои коэффициенты:
Изображение потеряло в качестве из-за того, что его растянули с помощью matplotlib.
Как переформатировать изображение в массив
Теперь мы будем использовать инструменты NumPy, поэтому желательно конвертировать изображение в np.array:
Конструктор массива принимает изображение в качестве аргумента и создает такой массив. Форму массива можно узнать с помощью поля shape.
224×225 — размеры нашего изображения. «3» появляется из-за того, что каждый пиксель представлен тремя значениями.
Как добавить фильтр «Негатив»
Значения цветов могут меняться от 0 до 255. Негатив — эффект инвертирования цветов. Достигается он просто: от 255 нужно отнять значение цвета. Так как все операции над массивом NumPy выполняются поэлементно, то мы отнимем от 255 текущий массив:
С помощью функции show() оценим результат:
Как отзеркалить изображение
Следующая задача — отражение изображения слева направо (т. е. правая и левая стороны изображения меняются местами). В NumPy есть функция fliplr. Про ее применение можно найти информацию здесь.
Передайте исходный массив в fliplr:
Этот фрагмент кода не изменяет массив, а возвращает новый, что нам и нужно. Оценим результат работы:
Как добавить эффект
Идея этого эффекта проста — нужно сделать изображение как можно синее. Для этого замените каждое третье «значение пикселя» на максимальное — 255.
Здесь нужно поменять сам массив, и, чтобы не потерять исходное изображение, скопируйте последовательность с помощью np.copy().
Другой вариант конструкции:
arr[:, :, 2] = 255
Выводим результат:
Весь код из статьи вы сможете найти в этом документе.