Task 4 of 6

Strong, Weak, Gone

One threshold forces a bad choice. Set it high and long edges break into dashes wherever the contrast dips; set it low and the picture fills with noise. Canny's answer is to refuse to choose: use two thresholds and admit that the middle band is undecided.

Above high a pixel is strong — it is an edge, no argument. Below low it is gone. Between them it is weak: it might be the faint continuation of a real edge, or it might be nothing, and this stage deliberately does not decide. It just labels. The next stage decides, and it decides by asking who the pixel's neighbours are.

The labels are numbers, because a kernel returns a number: 1 for strong, 0.5 for weak, 0 for gone. Order matters — test high first. Written the other way round, low catches everything and the strong branch is the only one that ever fires, which turns three classes back into one.

Goal: classify every cell of thin into 1 (at or above this.constants.high), 0.5 (at or above this.constants.low) or 0.

Requirements

Hint 1 — three lines
const m = thin[this.thread.y][this.thread.x];
if (m >= this.constants.high) {
  return 1;
}

…then the same shape for low returning 0.5, and a bare return 0; at the end.

Hint 2 — why 0.5 and not 2

The value has to survive a float texture and a > comparison in the next kernel, so the three labels want to be far apart and exactly representable. 0, 0.5 and 1 are all exact in binary floating point, and the propagation kernel can then test > 0.75 for "strong" and < 0.25 for "gone" without ever comparing floats for equality.

Same idea elsewhere

This stage is the most boring kernel in the module and the most universally fast one: a pure elementwise map, one read and one write per thread, no neighbours, no coordination — the shape a GPU is happiest with. In CUDA it is a thrust::transform, in WebGPU a one-line compute shader, and in a fused production Canny it does not exist as a separate pass at all: the comparison gets folded into the tail of the suppression kernel, because the memory traffic of a whole extra pass costs more than the arithmetic it saves.

All tasks in The Canny Edge Pipeline

  1. Blur First: a Separable Gaussian
  2. Magnitude, and the Angle Nobody Mentions
  3. Non-Maximum Suppression
  4. Strong, Weak, Gone
  5. Hysteresis: Run It Until Nothing Changes
  6. Payoff: Five Stages, Zero Round Trips

This page is an interactive exercise — the editor, the GPU runner and your saved progress need JavaScript. The text above is the full brief.