Home / Tools / Kernel designer

Convolution kernel designer

Change the numbers, see what happens to the picture, take the Pillow code away.

Nothing is uploaded. The convolution runs in your browser.

What a kernel is

Every output pixel is a weighted sum of the pixels around it. The grid holds the weights. The middle cell is the pixel itself, the cells around it are its neighbours. Put 1 in the middle and 0 everywhere else and nothing changes, which is why that one is called the identity.

Scale and offset

After the sum, Pillow divides by scale and adds offset. Leave scale empty and it uses the sum of the weights, which keeps the overall brightness the same. That is why a box blur of nine ones does not come out nine times too bright.

Offset matters for kernels that sum to zero, such as edge detectors and emboss. Without it, everything that is not an edge comes out black. An offset of 128 puts the flat areas back in the middle grey.

A few that are worth knowing

KernelDoes
0 -1 0 / -1 5 -1 / 0 -1 0Sharpen. The centre is boosted, the neighbours subtracted
1 1 1 / 1 1 1 / 1 1 1Box blur, with scale 9
-1 -1 -1 / -1 8 -1 / -1 -1 -1Edge detect. Sums to zero
-2 -1 0 / -1 1 1 / 0 1 2Emboss. Asymmetric, so it looks lit from one side
-1 0 1 / -2 0 2 / -1 0 1Sobel, finds vertical edges

In Pillow

from PIL import Image, ImageFilter

kernel = ImageFilter.Kernel(
    (3, 3),
    [0, -1, 0,
     -1, 5, -1,
     0, -1, 0],
    scale=1,
)

im = Image.open("photo.jpg")
im.filter(kernel).save("out.png")
Pillow only accepts 3 by 3 and 5 by 5 kernels, and only on L and RGB images. Convert a palette image to RGB first.

Is this what Pillow does

Yes. The same arithmetic, in JavaScript. Checked against Pillow 12 on a 360 by 240 image with both a sharpen and a blur kernel: every interior pixel came out identical, no difference at all. The edges differ slightly, because this tool repeats the border pixel while Pillow leaves the outermost rows untouched.

See the filter gallery for the ready made filters.