Joshu Leonardy
空 · 間 · 濾 · 波

Spatial Filtering Lab

In lab 02 every output pixel depended on one input pixel. Here each output is computed from a small neighbourhood around it, using a grid of weights called a kernel. That one change is enough to blur, remove noise, sharpen and find edges. Each operation is shown here as a kernel, as the arithmetic at the pixel you point at, and as a result on your own image.

— 01 —
近 · 傍

A kernel and its neighbourhood

Gonzalez & Woods, 4th ed. §3.4 Fundamentals of Spatial Filtering (pp. 153–163)  ·  Burger & Burge — Filters

Place the kernel over a pixel, multiply each weight by the pixel beneath it, and add up the products. The sum is the output value for that pixel. Point at the image and the inspector shows every product. You can type your own weights into the kernel; fractions like 1/9 work too.

g(x, y) = aΣs = −abΣt = −bw(s, t) f(x + s, y + t)

This is correlation. Convolution is the same sum with the minus signs, which is the same as rotating the kernel 180° first. For a symmetric kernel such as a box or a Gaussian the two give identical results. For an asymmetric one they differ, and the Shift kernel shows which way. The border setting decides what f means outside the image, because the kernel still needs values to read there.

Kernel

Presets
Size
Operation
Border
Display negatives as
— 02 —
平 · 滑 · 化

Smoothing: box versus Gaussian

Gonzalez & Woods, 4th ed. §3.5: Box and Lowpass Gaussian Filter Kernels (pp. 165–166); §3.4: Separable Filter Kernels (p. 161)  ·  Burger & Burge — Filters: smoothing, separability

A smoothing kernel has positive weights that add up to 1, so it replaces each pixel with a weighted average of its neighbours. A box kernel weights every neighbour equally. A Gaussian kernel gives most weight to the nearest neighbours and less to the far ones. The row profile below plots the brightness along one row of the image, so you can see how each kernel spreads out a sharp edge. Point at the image to choose which row is plotted.

w(s, t) = K e−(s² + t²) / 2σ² = K e−s² / 2σ² · e−t² / 2σ²

The second form is the useful one. A 2-D Gaussian is a 1-D Gaussian along the rows multiplied by one along the columns. That means you can blur every row with a short 1-D kernel and then every column with the same kernel, which costs 2n multiplications per pixel instead of n². A box kernel is separable in the same way. The weights are cut off at 3σ from the centre, because beyond that they add less than 0.3% to the sum.

Kernel
Box size
Gaussian σ
1-D kernel weights
Row profile
— 03 —
雑 · 音 · 除 · 去

Noise, and why the median wins

Gonzalez & Woods, 4th ed. §3.5: Order-Statistic (Nonlinear) Filters (p. 174); §5.2 Noise Models; §5.3 Restoration in the Presence of Noise Only  ·  Burger & Burge — Filters: nonlinear filters

Averaging reduces noise, but it also blurs whatever the noise is sitting on. A single 255 among eight values of 40 raises a 3×3 mean by almost 24. The median ignores that outlier completely: sort the nine values and take the middle one. That makes it an order-statistic filter. Unlike every filter in section 01, it is not a weighted sum, so no kernel can represent it. The scoreboard measures each result against the clean image using PSNR, where higher means closer to the original.

g(x, y) = median { f(s, t) : (s, t) ∈ Sxy }    PSNR = 10 log10(255² / MSE)
Point at the image to see the window sorted.
Noise
Density
Sample
Filter
Window
Row profile
PSNR against the clean image · same window size
— 04 —
鮮 · 鋭 · 化

Sharpening: adding the detail back

Gonzalez & Woods, 4th ed. §3.6: The Laplacian (p. 178), Unsharp Masking and Highboost Filtering (p. 182)  ·  Burger & Burge — Edges and contours: sharpening

Smoothing averages detail away. Sharpening works in the opposite direction: it measures the detail and adds more of it back. The Laplacian measures detail with a second derivative, which is zero where the image is flat and large where brightness changes abruptly. Unsharp masking measures detail as the difference between the image and a blurred copy of it. Either way, watch the row profile for overshoot: values pushed past the original on both sides of an edge. That overshoot is what makes an edge look crisp, and when it is too strong it shows up as a halo or gets clipped at 0 or 255.

Point at an edge to put its numbers through the equation.
Method
Neighbours
Strength c
Blur σ
Amount k
Show
Row profile · shaded bands are outside 0–255 and will clip
— 05 —
輪 · 郭

Gradients and edges

Gonzalez & Woods, 4th ed. §3.6: The Gradient (p. 184), eqs. 3-58 to 3-65; §10.2 Point, Line, and Edge Detection  ·  Burger & Burge — Edges and contours

The first derivative measures how quickly brightness changes. You need two kernels: one responds to change from left to right, the other to change from top to bottom. Together they form the gradient, a vector that points uphill in brightness. Its length is the edge strength. The Sobel kernel is a derivative with a small amount of smoothing built in, which is why it copes with noise better than the plain Roberts cross.

M(x, y) = √(gx² + gy²)  ≈  |gx| + |gy|
Point at an edge to see gx and gy computed from its nine neighbours.

A note on axes when reading the book: Gonzalez & Woods take x down the rows and y across the columns. Here, as in most software, x runs left to right. So for all three operators, this lab's gx is the book's gy and the other way round (compare the book's eqs. 3-60, 3-63 and 3-64). The magnitude is the same either way.

Operator
Show
Smooth first
Edge threshold
An edge map from a threshold is only a first step. The edges come out thick, broken, and full of small fragments from noise. Canny's detector fixes each of those problems in turn: it thins the edges to one pixel, then links them using two thresholds instead of one. You can step through it in lab 07.