Home / Library / PIL / Handbook / The ImageFilter module

The ImageFilter module

Filters are passed to im.filter(), which returns a new image.

from PIL import Image, ImageFilter

im = Image.open("photo.jpg")
soft = im.filter(ImageFilter.GaussianBlur(3))

The adjustable ones

FilterWhat it does
GaussianBlur(radius=2)A proper Gaussian blur. The one to use for blurring
BoxBlur(radius)Cheaper, slightly blockier
UnsharpMask(radius=2, percent=150, threshold=3)Sharpening. The threshold stops it from sharpening noise
MedianFilter(size=3)Replaces each pixel with the median around it. Removes speckle while keeping edges
MinFilter, MaxFilterErode and dilate, useful on masks
ModeFilter(size)The most common value nearby. Good on flat colour art
RankFilter(size, rank)The general form of the three above

The fixed ones

BLUR, CONTOUR, DETAIL, EDGE_ENHANCE, EDGE_ENHANCE_MORE, EMBOSS, FIND_EDGES, SHARPEN, SMOOTH and SMOOTH_MORE take no arguments and are passed as they are:

edges = im.filter(ImageFilter.FIND_EDGES)

They are small fixed kernels. Handy for a quick effect, but for anything you care about, the adjustable filters give you control over the strength.

Sharpening after resizing

Shrinking an image always softens it, because several original pixels are averaged into one. A light unsharp mask afterwards puts the crispness back:

im.thumbnail((1200, 1200), Image.Resampling.LANCZOS)
im = im.filter(ImageFilter.UnsharpMask(radius=1.2, percent=110, threshold=3))

Your own kernel

sharpen = ImageFilter.Kernel(
    (3, 3),
    [0, -1, 0,
     -1, 5, -1,
     0, -1, 0],
    scale=1,
    offset=0,
)
im = im.filter(sharpen)

Kernels work on L and RGB images only, and the size must be 3 by 3 or 5 by 5. If scale is left out, Pillow uses the sum of the kernel values, which keeps the overall brightness the same.

Mode matters

Filtering a mode P image filters the palette indexes rather than the colours, which produces nonsense. Convert to RGB first.

Related