Hysteresis Thresholding
You are given an edge magnitude image (after NMS) and need to apply hysteresis thresholding to produce final binary edges.
Hysteresis uses two thresholds:
- Strong edges: magnitude > high_threshold β definitely edges
- Weak edges: low_threshold < magnitude β€ high_threshold β edges only if connected to strong edges
- Non-edges: magnitude β€ low_threshold β not edges
The algorithm:
- Mark all strong edge pixels
- Starting from each strong edge, propagate to connected weak edges using 8-connectivity
- Output: 1 for edges, 0 for non-edges
This two-threshold approach reduces noise while preserving edge continuity.
Example:
edges = [[0, 10, 0],
[0, 50, 0],
[0, 10, 0]]
low_thresh = 5
high_thresh = 30[[0, 1, 0], [0, 1, 0], [0, 1, 0]]
-
Classify pixels:
- (0,1)=10: 5 < 10 β€ 30 β weak
- (1,1)=50: 50 > 30 β strong
- (2,1)=10: 5 < 10 β€ 30 β weak
- All others = 0: β€ 5 β non-edge
-
Mark strong edges:
- (1,1) is strong β set to 1
-
Propagate to connected weak edges:
- (0,1) is adjacent to (1,1) β set to 1
- (2,1) is adjacent to (1,1) β set to 1
-
Final result: column 1 is all edges
Constraints:
- edges is the NMS edge magnitude image
- low_thresh and high_thresh define the hysteresis thresholds
- Return binary edge map (0 or 1)
- Use 8-connectivity for edge linking
More from CV: Feature Detection and Matching
Youβre implementing the hysteresis thresholding step that typically comes after non-maximum suppression (NMS) in Canny edge detection.
1. Background Knowledge (concepts & theory)
After you compute the gradient magnitude of an image and perform non-maximum suppression, you get a thin edge magnitude map: large values at likely edge locations, small values elsewhere. However, this map is still noisy: many weak responses may be due to noise, texture, or small fluctuations, not true object boundaries.
A single global threshold (e.g., βkeep all pixels with magnitude > Tβ) is often too crude:
- If T is high β you lose real but weak edges (breaks in contours).
- If T is low β you keep a lot of noise and speckles.
Hysteresis thresholding uses two thresholds to fix this. Pixels with magnitude above a high threshold are considered strong edges (reliable). Pixels between low and high thresholds are weak edges: they are kept only if they are connected (via an 8-connected path) to at least one strong edge. Everything at or below the low threshold is discarded. This preserves continuous edges while suppressing isolated noise.
2. Algorithm / Approach Pattern
At a high level, the pattern is:
- Classify pixels into:
- Strong edge
- Weak edge
- Non-edge
- Graph traversal from strong edges:
- Treat each strong edge pixel as a seed.
- From each seed, perform a search (DFS/BFS) over neighbors.
- Whenever you encounter a weak edge that is connected via 8-connectivity, promote it to a final edge and continue from there.
- Output binary edge map:
- All visited strong + connected weak pixels β 1
- Everything else β 0
Conceptually, youβre doing connected-component growing starting from strong edges, but you are allowed to grow only through pixels labeled as weak.
3. Step-by-Step Strategy to Implement
Assume you are given:
- mag β 2D array of edge magnitudes after NMS
- low β low threshold
- high β high threshold
Target: output edges β 2D binary array (0/1 or False/True).
Step 1: Initial classification
Create a label map (same size as mag):
- Strong: mag > high
- Weak: low < mag <= high
- Non-edge: mag <= low
For example:
import numpy as np
strong = mag > high
weak = (mag > low) & (mag <= high)
# Optional: a working label map
# 0 = non-edge, 1 = weak, 2 = strong
labels = np.zeros_like(mag, dtype=np.uint8)
labels[weak] = 1
labels[strong] = 2
Step 2: Initialize output and a queue/stack
- Create edges initialized to 0.
- For each strong pixel:
- Mark it as edge in edges.
- Push its coordinates into a queue (for BFS) or stack (for DFS).
from collections import deque
Continue the full explanation
You're reading the free preview. Unlock the complete walkthrough, the code editor, test runner and reference solution with Premium.
Editor locked
The code editor is locked for Pro problems. It is only available for free problems. Please upgrade to gain access to the code editor for all problems.