Обработка изображений на Python: инструменты и методы
Обзор библиотек для работы с изображениями
Python предлагает несколько библиотек для обработки изображений. Наиболее распространена Pillow (форк PIL), но существуют и другие инструменты с разными возможностями. Ниже рассмотрены основные варианты с примерами кода и типичными проблемами.
Как выполнить базовые операции с изображениями в Python?
Библиотека Pillow (установка: pip install Pillow) позволяет открывать, изменять размеры, обрезать, поворачивать и фильтровать изображения. Пример открытия и сохранения в другом формате:
from PIL import Image
img = Image.open('photo.jpg')
img.save('photo.png')Python image library (библиотека изображений python)
Изменение размера с сохранением пропорций:
img.thumbnail((400, 300)) # уменьшает до заданного прямоугольника
img.save('thumb.jpg')
Обрезка области:
box = (10, 10, 200, 200) # left, upper, right, lower
cropped = img.crop(box)
cropped.save('crop.jpg')
Применение фильтра (размытие):
from PIL import ImageFilter
blurred = img.filter(ImageFilter.GaussianBlur(radius=5))
blurred.save('blur.jpg')
ImageOps.exif_transpose(). Ошибка OSError: cannot identify image file – повреждённый файл или неподдерживаемый формат.Как применить продвинутую обработку с помощью OpenCV?
OpenCV (установка: pip install opencv-python) предназначен для компьютерного зрения. Он работает с numpy-массивами, что даёт гибкость. Пример чтения, конвертации в оттенки серого и бинаризации:
import cv2
img = cv2.imread('image.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
cv2.imwrite('binary.jpg', thresh)
Детектирование границ алгоритмом Canny:
edges = cv2.Canny(gray, 50, 150)
cv2.imwrite('edges.jpg', edges)
cv2.cvtColor(img, cv2.COLOR_BGR2RGB). Файл не найден, если путь содержит кириллицу – используйте cv2.imdecode(np.fromfile(path, np.uint8), cv2.IMREAD_COLOR).Какие научные методы доступны в библиотеке scikit-image?
scikit-image (установка: pip install scikit-image) предоставляет алгоритмы сегментации, морфологии, восстановления. Пример сегментации водоразделом:
from skimage import io, color, filters, segmentation
image = io.imread('cells.tif')
gray = color.rgb2gray(image)
edges = filters.sobel(gray)
markers = filters.peak_local_max(edges)
segmented = segmentation.watershed(edges, markers)
io.imsave('segmented.png', segmented)
ValueError при несовпадении типов данных – преобразуйте в float64 или uint8.Как использовать ImageMagick через библиотеку Wand?
Wand (установка: pip install Wand) – обёртка для ImageMagick. Пример конвертации изображения в PDF:
from wand.image import Image
with Image(filename='photo.jpg') as img:
img.format = 'pdf'
img.save(filename='output.pdf')
Изменение размера с высоким качеством:
with Image(filename='input.jpg') as img:
img.resize(800, 600, filter='lanczos')
img.save(filename='resized.png')
MissingDelegateError – отсутствует поддержка формата.Как обрабатывать изображения напрямую через numpy?
Изображение можно представить как трёхмерный массив numpy. Пример инвертирования цветов:
import numpy as np
from PIL import Image
img = Image.open('photo.jpg')
arr = np.array(img)
inv_arr = 255 - arr
inv_img = Image.fromarray(inv_arr)
inv_img.save('inverted.jpg')
Поэлементные операции (увеличение яркости):
bright = np.clip(arr * 1.3, 0, 255).astype(np.uint8)
Image.fromarray(bright).save('bright.jpg')
Расширенные примеры работы с изображениями
Чтение и изменение EXIF-данных в Pillow
Извлечение метаданных из JPEG и их модификация.
from PIL import Image
from PIL.ExifTags import TAGS
img = Image.open('image.jpg')
exif = img._getexif()
for tag_id, value in exif.items():
tag_name = TAGS.get(tag_id, tag_id)
print(f'{tag_name}: {value}')
# Изменение ориентации
exif_data = img.info.get('exif')
if exif_data:
from PIL.ExifTags import Base
# Устанавливаем ориентацию 1 (нормальная)
exif_dict = {}
for k, v in img._getexif().items():
exif_dict[TAGS.get(k)] = v
exif_dict['Orientation'] = 1
# Сохраняем с новым exif (требуется конвертация)
# Проще использовать ImageOps.exif_transpose()
Результат: вывод списка тегов, например 'DateTimeOriginal: 2023:01:15 12:30:00'. При изменении ориентации изображение автоматически поворачивается.
Создание анимированного GIF из последовательности кадров
Объединение нескольких изображений в GIF-анимацию.
from PIL import Image
frames = []
for i in range(10):
img = Image.new('RGB', (200, 200), color=(i*25, 50, 100))
frames.append(img)
frames[0].save('animation.gif',
save_all=True,
append_images=frames[1:],
duration=100,
loop=0)
Создан файл animation.gif с 10 кадрами, каждый длительностью 100 мс, бесконечный цикл.
Использование маски для вырезания объекта
Наложение маски (чёрно-белого изображения) для извлечения части изображения.
from PIL import Image
image = Image.open('portrait.jpg')
mask = Image.open('mask.png').convert('L') # маска в оттенках серого
result = Image.composite(image, Image.new('RGB', image.size, (0,0,0)), mask)
result.save('cutout.jpg')
Объект на белом фоне заменяется прозрачным (или чёрным). Альфа-канал маски учитывается.
Чтение изображений большого размера без полной загрузки
Использование ImageFile.Parser для потоковой обработки.
from PIL import ImageFile
parser = ImageFile.Parser()
with open('large_image.tif', 'rb') as f:
chunk = f.read(8192)
while chunk:
parser.feed(chunk)
chunk = f.read(8192)
img = parser.close()
print(img.size)
Выводится размер изображения без загрузки всего файла в память (эффективно для TIFF с LZW сжатием).
Конвертация в оттенки серого с сохранением альфа-канала
Стандартные методы преобразования теряют альфа. Сохраняем прозрачность вручную.
from PIL import Image
img = Image.open('logo.png').convert('RGBA')
if img.mode == 'RGBA':
r, g, b, a = img.split()
gray = Image.merge('RGB', (r, g, b)).convert('L')
gray_rgba = Image.merge('RGBA', (gray, gray, gray, a))
else:
gray_rgba = img.convert('L')
gray_rgba.save('gray_logo.png')
Сохраняется прозрачность исходного PNG. В результирующем изображении цветные пиксели становятся серыми, альфа-канал неизменен.