Problem solved in full
-
Gradient magnitude at pixel (31, 3) of the checkerboard test image 9 steps
The checkerboard test image — pure black and white, squares 32 pixels wide — at σ = 1.0 with the 3×3 blur kernel, Tlo = 30 and Thi = 80. Derive the gradient magnitude at pixel (31, 3), the last white column before the first vertical boundary, and then work out how many pixels wide the edge it belongs to comes out.
-
Grayscale first, and on this image it does nothing: the three weights add to exactly 1, so a pixel with equal red, green and blue keeps its value. White stays 255, black stays 0, so every number below comes from just those two values.
-
The Gaussian weights fall off with the square of the distance. At σ = 1 the centre gets 1, the 4 pixels sharing an edge get e-0.5 = 0.6065 and the 4 corners get e-1 = 0.3679; dividing through by the total 4.8976 makes them a weighted average.
-
Row 3 lies well inside a horizontal band, so the 3 rows of any window there are identical and the kernel's vertical structure cancels out. Only its column totals matter, and there are just 2 of them.
-
Blur across the boundary. At x = 31 the window covers 2 white columns and 1 black; at x = 32 it covers 1 white and 2 black. The hard step from 255 to 0 has become the ramp 255, 185, 70, 0 — those middle 2 values, rounded, are the ones the inspector shows.
-
Sobel weights the left column by -1, -2, -1 and the right by +1, +2, +1, and the centre column by nothing at all. With all 3 rows equal those weights collapse to a single factor of 4, so the whole convolution is 4 times the difference between the columns either side.
-
The vertical gradient vanishes for the mirror-image reason: the row above the pixel and the row below it are the same 3 numbers, so the +1, +2, +1 sum cancels the -1, -2, -1 sum term by term. This edge is purely horizontal in gradient, which is what makes the next step easy.
-
Combine the two, and the magnitude is just the horizontal one.
-
Compare with what the same edge would give unblurred: a bare step of 255 across the same kernel. Smoothing has spent 280 counts, just over 27% of the available response, and that is the price of the noise immunity — not a rounding loss but a deliberate trade.
-
Now repeat one column to the right. At x = 32 the window reads 185, 70, 0, so the difference is again -185 and the magnitude is again 740. One column further out on either side the difference collapses to about -70 and the magnitude to 280.
Answer
740 — and the edge comes out 2 pixels wide. Non-maximum suppression keeps a pixel when its magnitude is ≥ both neighbours along the gradient. Here the gradient points along x, so pixel 31 is compared with 280 on its left and 740 on its right, pixel 32 with 740 and 280. Each ties with the other, and a tie passes ≥, so both survive; at 740 both are more than 9 times Thi = 80, so both come out white. No pair of thresholds can separate them, because thresholds are not the cause. The real boundary lies at x = 31.5, exactly halfway between the last white pixel and the first black one, and a symmetric blur leaves the gradient symmetric about that half-integer — there is no single maximum to find. That is worth knowing before you tune anything: a doubled line in an edge map is sometimes a thresholding failure and sometimes arithmetic, and here it is 740 = 740 on an image whose squares happen to be a whole number of pixels wide.
-
References (1)
- Insight block 3 — the three criteria, and the trade-off between two of them: J. Canny, "A Computational Approach to Edge Detection." IEEE Transactions on Pattern Analysis and Machine Intelligence PAMI-8(6), 679–698, 1986.