PIL.Image.filter: примеры (PYTHON)

Использование метода filter в библиотеке Pillow для Python
Раздел: Pillow, Обработка изображений
PIL.Image.filter(filter: ImageFilter): Image object

Основные сведения о методе PIL.Image.filter

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

Использование метода актуально для задач обработки изображений: размытия, повышения резкости, нахождения краев, добавления эффектов рельефа и тиснения. Он работает с изображениями в режимах "L", "RGB" и "RGBA". Для одноканальных изображений фильтр применяется к единственному каналу, для многоканальных - к каждому каналу отдельно, если не указано иное в описании фильтра.

Синтаксис метода: Image.filter(filter).

Единственный параметр filter является экземпляром класса ImageFilter. Библиотека предоставляет набор встроенных фильтров, таких как BLUR, CONTOUR, DETAIL, EDGE_ENHANCE, EDGE_ENHANCE_MORE, EMBOSS, FIND_EDGES, SHARPEN, SMOOTH, SMOOTH_MORE. Также возможно создание пользовательских фильтров через классы ImageFilter.Kernel, ImageFilter.GaussianBlur, ImageFilter.UnsharpMask, ImageFilter.RankFilter, ImageFilter.MedianFilter, ImageFilter.MinFilter, ImageFilter.MaxFilter.

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

Базовые примеры применения метода filter

Пример применения предопределенного фильтра размытия:

from PIL import Image, ImageFilter

# Открытие изображения
img = Image.open('example.jpg')
# Применение фильтра размытия
blurred_img = img.filter(ImageFilter.BLUR)
blurred_img.save('blurred_example.jpg')
blurred_img.show()

Результат - новое изображение с легким размытием.

Пример использования фильтра для обнаружения краев:

from PIL import Image, ImageFilter

img = Image.open('example.jpg').convert('L')  # Конвертация в оттенки серого
edges_img = img.filter(ImageFilter.FIND_EDGES)
edges_img.save('edges_example.jpg')

Результат - черно-белое изображение с выделенными контурами объектов.

Пример применения пользовательского ядра свертки 3x3 для создания эффекта рельефа:

from PIL import Image, ImageFilter

img = Image.open('example.jpg')
# Создание ядра для эффекта рельефа
kernel = ImageFilter.Kernel(
    size=(3, 3),
    kernel=[-2, -1, 0, -1, 1, 1, 0, 1, 2],
    scale=1,
    offset=0
)
embossed_img = img.filter(kernel)
embossed_img.save('custom_emboss.jpg')

Результат - изображение с эффектом объемного тиснения.

Альтернативные методы обработки изображений в Pillow

Библиотека Pillow предлагает другие методы для манипуляций с пикселями. Метод Image.point() применяет функцию к каждому пикселю, полезен для преобразований таблицы поиска (LUT), изменения яркости, контрастности или инверсии цветов. Он работает быстрее для поэлементных операций без учета соседних пикселей.

Метод ImageOps содержит готовые операции: ImageOps.autocontrast(), ImageOps.equalize(), ImageOps.mirror(), ImageOps.posterize(). Эти функции удобны для стандартных преобразований, не требующих создания фильтров.

Для сложных операций, таких как морфологические преобразования, доступен модуль ImageMorph. Метод Image.filter() предпочтителен для операций свертки и применения готовых фильтров, когда необходимо учитывать соседние пиксели. Для поэлементных преобразований чаще используют Image.point() или функции из ImageOps.

Реализации фильтрации изображений в других языках

В JavaScript для работы с изображениями в браузере используют Canvas API. Метод CanvasRenderingContext2D.filter применяет CSS-фильтры, такие как blur(), brightness(), contrast().

// JavaScript
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
img.onload = function() {
    ctx.filter = 'blur(5px)';
    ctx.drawImage(img, 0, 0);
};
img.src = 'example.jpg';

В Java для продвинутой обработки изображений применяют библиотеку Java Advanced Imaging (JAI) или BufferedImageOp интерфейс. Класс ConvolveOp выполняет свертку.

// Java
BufferedImage image = ImageIO.read(new File("example.jpg"));
Kernel kernel = new Kernel(3, 3, new float[] {
    0.0f, -1.0f, 0.0f,
    -1.0f, 5.0f, -1.0f,
    0.0f, -1.0f, 0.0f
});
ConvolveOp op = new ConvolveOp(kernel);
BufferedImage filteredImage = op.filter(image, null);

В C# в пространстве имен System.Drawing.Imaging используют класс ImageAttributes с ColorMatrix или сторонние библиотеки, например, ImageSharp с методом Mutate.

// C# с ImageSharp
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;

using (Image image = Image.Load("example.jpg"))
{
    image.Mutate(x => x.GaussianBlur(5f));
    image.Save("blurred.jpg");
}

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

Распространенные ошибки при работе с filter

Ошибка при использовании фильтра с неподдерживаемым режимом изображения. Некоторые фильтры требуют определенного количества каналов.

from PIL import Image, ImageFilter

img = Image.open('example.jpg').convert('P')  # Палитровый режим
try:
    img.filter(ImageFilter.BLUR)
except ValueError as e:
    print(f"Ошибка: {e}")  # Может возникнуть ошибка

Результат: возможное исключение, зависящее от реализации фильтра.

Ошибка создания пользовательского ядра с неверным количеством элементов.

from PIL import Image, ImageFilter

img = Image.open('example.jpg')
try:
    kernel = ImageFilter.Kernel((3, 3), [1, 0, -1, 0, 1, 0], 1, 0)  # 6 вместо 9 элементов
    img.filter(kernel)
except ValueError as e:
    print(f"Ошибка: {e}")  # "Wrong kernel size"

Результат: исключение ValueError с сообщением о несоответствии размера.

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

from PIL import Image, ImageFilter

img = Image.open('example_with_alpha.png')  # Режим RGBA
# Фильтр BLUR может размыть и альфа-канал, что иногда нежелательно
blurred = img.filter(ImageFilter.BLUR)
# Возможно, перед размытием нужно отделить альфа-канал

Рекомендуется проверять режим изображения и при необходимости выполнять раздельную обработку каналов.

Изменения в методе filter в последних версиях Pillow

В версии Pillow 9.0.0 были обновлены внутренние реализации некоторых фильтров для улучшения производительности и точности. Фильтр GaussianBlur получил оптимизацию для больших радиусов размытия.

В версии 8.0.0 добавлена поддержка фильтра BoxBlur через класс ImageFilter.BoxBlur. Этот фильтр обеспечивает быстрое размытие методом усреднения по прямоугольной области.

Начиная с версии 7.0.0, улучшена обработка граничных условий при свертке. Ранее значения за границами изображения считались нулевыми, теперь доступны и другие методы, такие как отражение границ для некоторых операций.

В более ранних версиях, таких как 6.0.0, была изменена точность вычислений при применении фильтров для изображений с высоким динамическим диапазоном (16-битные и 32-битные каналы).

Рекомендуется обращаться к официальной документации Pillow для получения актуальной информации о изменениях в конкретных версиях библиотеки.

Расширенные примеры использования фильтров

Пример комбинирования нескольких фильтров для создания эффекта акварели:

Пример python
from PIL import Image, ImageFilter

img = Image.open('landscape.jpg')
# Сначала немного размываем, затем повышаем резкость для имитации стиля
step1 = img.filter(ImageFilter.SMOOTH_MORE)
step2 = step1.filter(ImageFilter.SHARPEN)
step3 = step2.filter(ImageFilter.EDGE_ENHANCE)
step3.save('watercolor_effect.jpg')

Создание собственного фильтра для выделения текстуры с помощью ядра Лапласиана:

Пример python
from PIL import Image, ImageFilter

img = Image.open('texture.jpg').convert('L')
laplacian_kernel = ImageFilter.Kernel(
    (3, 3),
    [0, 1, 0, 1, -4, 1, 0, 1, 0],
    scale=1,
    offset=128  # Сдвиг для визуализации
)
texture = img.filter(laplacian_kernel)
texture.save('laplacian_texture.jpg')

Использование фильтра MedianFilter для удаления шума типа "соль-перец":

Пример python
from PIL import Image, ImageFilter
import random

# Создание зашумленного изображения программно
img = Image.new('L', (200, 200), color=128)
pixels = img.load()
for i in range(img.width):
    for j in range(img.height):
        if random.random() < 0.05:  # 5% шума
            pixels[i, j] = 0 if random.random() < 0.5 else 255
# Применение медианного фильтра с размером апертуры 3
denoisened = img.filter(ImageFilter.MedianFilter(size=3))
denoisened.save('denoised_median.jpg')

Фильтрация с использованием UnsharpMask для контролируемого повышения резкости:

Пример python
from PIL import Image, ImageFilter

img = Image.open('portrait.jpg')
# Радиус 2, процент 150, порог 3
sharpened = img.filter(ImageFilter.UnsharpMask(radius=2, percent=150, threshold=3))
sharpened.save('unsharp_masked.jpg')

Применение фильтра RankFilter для выделения максимальных значений в окрестности:

Пример python
from PIL import Image, ImageFilter

img = Image.open('details.jpg').convert('L')
# size=5, rank=0 (минимум), rank=24 (максимум для окна 5x5)
max_filtered = img.filter(ImageFilter.RankFilter(size=5, rank=24))
max_filtered.save('local_maxima.jpg')

Пакетная обработка нескольких изображений с использованием разных фильтров:

Пример python
from PIL import Image, ImageFilter
import os

filters = {
    'blur': ImageFilter.BLUR,
    'edges': ImageFilter.FIND_EDGES,
    'emboss': ImageFilter.EMBOSS
}
input_folder = 'input_images'
output_folder = 'filtered_images'
os.makedirs(output_folder, exist_ok=True)

for filename in os.listdir(input_folder):
    if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        img_path = os.path.join(input_folder, filename)
        img = Image.open(img_path)
        for filter_name, filter_obj in filters.items():
            result = img.filter(filter_obj)
            base_name = os.path.splitext(filename)[0]
            result.save(os.path.join(output_folder, f"{base_name}_{filter_name}.jpg"))

питон PIL.Image.filter function comments

En
PIL.Image.filter Apply filter to image