← All projects
Machine learning & AI · Python
IK

imgkit

Image processing, written out — 2D convolution, Gaussian & median filters, Sobel edges and Otsu threshold on canvas, before/after side by side.

Source image

Upload image…

Sample is a fixed-seed procedural scene (shapes + gradients) so every run is comparable — same idea as tools/make_images.py.

Apply a filter

Filter
original
Kernel
—
Multiply counts
—
Wall time
—

Before / after

Original

Result

Pick a filter and press Apply — or click a filter button to run it immediately.

Convolution is not correlation

Almost every "convolution" in image code is correlation: the kernel slides in place, no flip. For symmetric kernels (box, Gaussian) they match. For Sobel they differ by sign — correlate(sobel) == -convolve(sobel).

The UI notes cover both mental models; edges use correlation like the Python correlate() path.

Separable Gaussian

A 2D Gaussian is rank-1: two 1D passes cost O(k) per pixel instead of O(k²). The kernel line counts above show the speed-up for the current σ.

Padding reflects (not zeros), so edges do not invent a black frame for the detector to find.

What each filter does

FilterArithmetic
Grayscale0.2126R + 0.7152G + 0.0722B (Rec. 709, not average)
Gaussian blurseparable 1D passes, radius = ⌈3σ⌉
Median 3×3neighbourhood median — kills salt & pepper
SharpenI − strength · Laplacian(I)
Sobel edges‖∇I‖ via 3×3 correlate with sobel-x / sobel-y
Canny-styleblur → gradients → non-max suppression → hysteresis
Otsumaximise between-class variance; mid of tied range
EqualiseCDF stretch over 256 bins
42 tests · Python 3.10–3.12 · sample images from a fixed seed · Built by Umer Hashmi