Categories: ML

Обработка изображений при помощи Pillow

В настоящее время Python является одним из наиболее распространенных языков программирования в мире. Используя его простой синтаксис, можно выполнять различные функции и задачи. Одна из них — автоматическая обработка цифровых изображений, которая может быть выполнена с помощью бибиотеки Pillow.

В этом учебном пособии мы покажем, как обрабатывать изображения с помощью Pillow. Затем мы сделаем еще один шаг вперед и продемонстрируем, как реализовать некоторые базовые операции с изображениями.

Для работы с этим учебным пособием необходимо иметь базовые знания языка Python и установленный на локальной машине интерпретатор Python 3.

Друзья, подписывайтесь на наш телеграм канал Pythonist. Там еще больше туториалов, задач и книг по Python.

Что такое Pillow?

Pillow является форком библиотеки Python Imaging Library (PIL). Это бесплатная библиотека с открытым исходным кодом для работы с изображениями и их обработки.

PIL сама по себе является мощной библиотекой, но она не обновлялась с 2009 года и не поддерживает Python 3. Pillow предоставляет больше возможностей.

Pillow поддерживает различные форматы файлов изображений, такие как .PNG, .JPEG, .PPM, .GIF, .TIFF и .BMP. С помощью этой библиотеки можно выполнять различные операции с изображениями, такие как обрезка, изменение размера, добавление текста, поворот, преобразование к оттенкам серого и многое другое.

Установка и настройка проекта

Установить Pillow можно с помощью pip, менеджера пакетов для Python:

python3 -m pip install --upgrade pip
python3 -m pip install --upgrade Pillow

Pillow предоставляет объект Image, в котором есть встроенные функции и свойства, с помощью которых можно выполнять манипуляции с изображениями.

Чтобы начать работу, сначала импортируйте объект Image  в Python-файл.

from PIL import Image

Далее следует загрузить изображение, вызвав функцию Image.open(), которая возвращает объект Image.

image = Image.open('sample.jpg')

Для наших примеров мы будем использовать образцы изображений с сайта Unsplash.

Также стоит отметить, что изображения находятся в том же каталоге, что наш файл с кодом Python.

Свойства объекта Image

Существует несколько свойств изображения, к которым можно обращаться для получения дополнительных данных о нем:

  • image.width возвращает ширину изображения
  • image.height возвращает высоту изображения
  • image.format возвращает формат файла изображения (например, .JPEG, .BMP, .PNG и т.д.)
  • image.size возвращает кортеж высоты и веса изображения
  • image.palette возвращает таблицу цветовой палитры, если таковая существует
  • image.mode возвращает пиксельный формат изображения (например, 1, L, RGB, CMYK).

Основные операции с изображениями

Мы также можем считывать и изменять данные изображения с помощью различных операций.

Любые изменения, внесенные в объект Image, могут быть сохранены в файл изображения с помощью метода save(). Все повороты, изменение размеров, обрезка, рисование и другие манипуляции с изображением выполняются через вызовы методов объекта Image.

Рассмотрим некоторые из этих операций более подробно.

Изменение формата изображения

Pillow поддерживает большое количество форматов изображений. Изображение может быть преобразовано из одного формата в другой следующим образом:

image = Image.open('sample.jpg')
image.save('sample_formatted.png')

Сначала загружается изображение. Затем Pillow видит расширение файла, указанное как PNG, поэтому перед сохранением изображения в файл оно преобразуется в .PNG.

Создание миниатюр

Вы можете изменять размеры изображений, создавая их миниатюры с помощью Pillow.

С помощью метода thumbnail() можно изменить размер изображения с сохранением соотношения сторон. При этом принимаются два значения, представляющие максимальную ширину и максимальную высоту миниатюры.

image = Image.open('sample.jpg')
image.thumbnail((200, 200))
image.save('sample_thumbnail.jpg')

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

Отражение и поворот изображений

Pillow позволяет отражать изображения. Для этого используется метод transpose, который принимает любой из следующих параметров:

  • Image.FLIP_LEFT_RIGHT — отражает изображение по горизонтали
  • Image.FLIP_TOP_BOTTOM — отражает изображение по вертикали
  • Image.ROTATE_90 — поворачивает изображение на определенный угол в зависимости от значения параметра.
image = Image.open('sample.jpg')

image.transpose(Image.FLIP_TOP_BOTTOM)
image.save('sample_flip.jpg')

Полученное изображение отражается по вертикали.

В качестве альтернативы можно повернуть изображение с помощью метода rotate(). Он принимает число (целое или с плавающей точкой), представляющее градусы поворота, и возвращает новый объект Image с повернутым изображением. Поворот осуществляется против часовой стрелки.

image = Image.open('sample.jpg')

image.rotate(90)
image.save('image_rotate90.jpg')

Изображение повернуто на 90 градусов.

Обрезка изображений

Обрезать изображение — значит вырезать из него только определенную часть. Обрезка часто используется при редактировании картинок для веб-приложений.

Функция crop() в Pillow требует, чтобы область обрезки была прямоугольной. Метод принимает кортеж, который определяет положение и размер области обрезки, и возвращает объект Image, представляющий обрезанное изображение.

Область обрезки определяется кортежем с четырьмя элементами, где координаты задаются в формате (лево, верх, право, низ).

image = Image.open('sample.jpg')

image.crop(200, 50, 450, 300)
image.save('sample_cropped.jpg')

В приведенном примере первые два значения представляют собой начальную позицию слева вверху. Третье и четвертое значения — нижняя правая точка.

Полный размер обрезанного изображения можно рассчитать как 250×250 пикселей.

Цветовое преобразование

Существуют различные формы представления пикселей, включая L (яркость), RGB и CMYK.

Pillow позволяет преобразовывать изображения между различными пиксельными представлениями с помощью метода convert().

Библиотека поддерживает преобразования между всеми поддерживаемыми режимами, а также между режимами «L» и «RGB». Для преобразования между другими режимами может потребоваться изображение в формате «RGB».

image = Image.open('sample.jpg')

grayscale_image = image.convert('L')
grayscale_image.save('sample_grayscale.jpg')

С помощью функции convert образец изображения переводится из режима RGB в режим L (luminance), в результате чего получается изображение в оттенках серого.

Фильтры изображений

Для изменения и улучшения изображений можно использовать такой функционал Pillow как фильтры.

Используя модуль ImageFilter из Pillow, можно получить доступ к методу filter() и задействовать различные способы фильтрации. Такие как:

  • BLUR
  • CONTOUR
  • DETAIL
  • EDGE_ENHANCE
  • EDGE_ENHANCE_MORE
  • EMBOSS
  • FIND_EDGES
  • SHARPEN
  • SMOOTH
  • SMOOTH_MORE

Для примера рассмотрим фильтр FIND_EDGES:

from PIL import Image, ImageFilter

image = Image.open('sample.jpg')
edges_image = image.filter(ImageFilter.FIND_EDGES)
edges_image.save('sample_edges.jpg')

Фильтр позволяет получить контурное изображение объекта на картинке.

Любое изображение может быть обработано с помощью любого из имеющихся фильтров для получения желаемого результата.

Практический пример обработки изображений с помощью Pillow

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

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

Для решения этой задачи можно создать Python-файл с именем script.py в той папке, где лежат изображения.

Сначала импортируйте все необходимые модули:

import os
from PIL import Image

Модуль OS в Python предоставляет функции для создания и удаления файлов и директорий.

Создайте каталог для обработанных изображений:

os.makedirs('watermarked_images')

Задайте ширину и высоту изображения логотипа:

logo_image = Image.open('watermark_logo.png')
logo_image = logo_image.resize((50, 50))
logo_width, logo_height = logo_image.size

Используйте функцию os.listdir вместе с циклом for:

for image in os.listdir('./images'):
    try:
    # Separting the filepath from the image's name
       path, filename = os.path.split(image)
       filename = os.path.splitext(filename)[0]

Откройте изображение:

       image = Image.open('./images/'+image)
#Resizing the image to a set size.
       edited_image = image.resize((300, 300))
#Setting the position for the placement
       width = edited_image.width
       height = edited_image.height

Для размещения логотипа на изображении используйте функцию вставки:

edited_image.paste(logo_image, (width - logo_width, height - logo_height), logo_image)

Сохраните изображения в новом каталоге:

  edited_image.save('./watermarked_Images/' + filename + ".jpg")

Каждое изображение в каталоге было обработано и на него был добавлен водяной знак. Этот скрипт позволил нам эффективно выполнить задачу за меньшее время.

Полный код и ресурсы, связанные с этим руководством, можно также посмотреть в репозитории GitHub.

Заключение

Pillow — это мощная библиотека для обработки изображений на языке Python. Прочитав эту статью, вы получили базовое представление о том, как выполнять основные операции над изображениями в Python с помощью Pillow.

Если вы хотите узнать больше, ознакомьтесь с официальной документацией по Pillow.

Перевод статьи «Image processing in Python using Pillow».

alexander

Recent Posts

Сборка мусора в Python: ключевые концепции и механизмы

Управление памятью - важный, но часто упускаемый из виду аспект программирования. При неправильном подходе оно…

6 дней ago

Круговой импорт в Python и как его избежать

Как возникает круговой импорт? Эта ошибка импорта обычно возникает, когда два или более модуля, зависящих…

2 недели ago

Библиотека tqdm: визуализация прогресса выполнения скриптов Python

Вы когда-нибудь оказывались в ситуации, когда скрипт на Python выполняется очень долго и вы задаетесь…

3 недели ago

Символы новой строки в Python

В этом руководстве мы разберем все, что нужно знать о символах перехода на новую строку…

2 месяца ago

if __name__ == «__main__» в Python: полное объяснение

Блок if __name__ == "__main__" в Python позволяет определить код, который будет выполняться только при…

2 месяца ago

Как писать модульные тесты для методов экземпляра в Python

Давайте разберем, как настроить модульные тесты для экземпляров классов. Мы напишем тесты для проверки функциональности…

4 месяца ago