Goal
Detect every chessboard corner visible in a grayscale image, assign each corner an integer pattern coordinate, and refine the corner to subpixel accuracy — without requiring the full pattern to be present. Input: a grayscale image . Output: a set of subpixel points together with integer pattern coordinates . Corner legality is decided topologically on a Delaunay mesh over the candidate set rather than by a response threshold.
Algorithm
Let denote the grayscale image. For a pixel , let denote its -pixel Bresenham circle neighbourhood, traversed in order around the circumference, with circular indexing . Let denote the mean intensity over and a fixed contrast offset. Define the two thresholds
Let denote the candidate x-corners surviving non-maximum suppression. Let denote a binarization of used to label triangle interiors. Let denote the Delaunay triangulation of — the unique triangulation in which every triangle's circumcircle contains no other point of .
The number of sign transitions of around the Bresenham ring against the two thresholds:
A true X-junction produces exactly four transitions — two from dark to light and two from light to dark — around a circle centred on it.
is declared an x-corner when the alternation count is and its own intensity lies strictly between the thresholds:
Within a local window of x-corner candidates, the kept corner is the one that maximises the larger one-sided energy against the ring mean:
with and partitioning the ring samples.
Each triangle inherits a single binary colour from , read over the shrunk interior of so that edge ambiguity from binarization does not corrupt the label.
A triangle is legal iff all three hold: (i) is uniform on the shrunk interior of ; (ii) has at least one edge-neighbour with the same colour; (iii) has at most two edge-neighbours with the same colour. Under the chessboard pattern, each tile splits into exactly two legal triangles that share an interior edge.
At a valid x-corner, the Hessian of the local intensity has determinant
is negative at saddle-shaped X-junctions; the subpixel offset from the pixel centre is the critical point of the local quadratic Taylor expansion, i.e. the solution of .
Procedure
- For every pixel at distance from the border, sample the ring , compute , , and , and apply the x-corner classification. Collect candidates .
- Assign each candidate the NMS cost . Suppress non-maxima in a local window; keep the argmax. Call the result .
- Compute the Bradley-Roth integral-image adaptive binarization of .
- Compute .
- For each , set by reading on the shrunk interior of .
- Iterate: remove every that fails topological legality; rebuild the adjacency; repeat until no removals occur. Discard vertices that no longer belong to any surviving triangle.
- Pick a seed legal triangle adjacent through a same-colour edge to a second legal triangle . Fix the origin at the vertex of opposite to ; assign the two remaining vertices coordinates and along the pattern axes.
- Flood-fill integer grid coordinates across the legal mesh: the coordinate of the unlabelled opposite vertex of a neighbour triangle is the reflection of the already-labelled opposite vertex through the shared edge. Each triangle is visited once.
- At every surviving vertex, compute on a small window. Reject if . Otherwise solve and return with the propagated .
flowchart TB
A["Image I"] --> B["X-corner<br/>N_alt = 4"]
B --> C["NMS<br/>argmax R"]
C --> D["Delaunay<br/>T = Del(C)"]
A --> E["Adaptive<br/>binarize B"]
E --> F["Triangle<br/>colour c(t)"]
D --> F
F --> G["Topological<br/>filter"]
G --> H["Coord<br/>propagation"]
H --> I["Hessian<br/>subpixel"]
Implementation
The per-pixel alternation count is the detector's hot kernel. One pass over the ring yields the alternation count, the two one-sided energies for the NMS cost, and the ring mean.
fn x_corner_response(ring: &[u8], gate: u8) -> Option<u32> {
let n = ring.len();
let sum: u32 = ring.iter().map(|&v| v as u32).sum();
let m = (sum / n as u32) as u8;
let t_lo = m.saturating_sub(gate);
let t_hi = m.saturating_add(gate);
let mut alt = 0u32;
let mut dark_energy = 0u32;
let mut light_energy = 0u32;
for i in 0..n {
let cur = ring[i];
let prev = ring[(i + n - 1) % n];
let up = cur > t_hi && prev < t_lo;
let down = cur < t_lo && prev > t_hi;
if up || down { alt += 1; }
let delta = (cur as i16 - m as i16).unsigned_abs() as u32;
if cur < t_lo { dark_energy += delta; }
if cur > t_hi { light_energy += delta; }
}
if alt == 4 {
Some(dark_energy.max(light_energy))
} else {
None
}
}
The caller further enforces on the centre pixel before admitting the corner; non-maximum suppression then retains the pixel with the largest returned response in a local window.
Remarks
- Complexity: the x-corner scan is linear in image area with a fixed -sample ring; Delaunay triangulation is ; topological filtering runs a bounded number of fixed-point sweeps, each linear in the mesh; coordinate propagation visits each triangle once; subpixel refinement is invoked only at surviving vertices, not image-wide.
- The detection threshold is set empirically to on a blurred input. The classification is dominated by the alternation count: any remaining false positives are discarded downstream by the topology, so results are weakly sensitive to .
- Binarization is integral-image adaptive (Bradley-Roth) — linear time, window-size independent, and tolerant of slow illumination gradients across the pattern.
- The filter requires only that a sufficient subset of the pattern be visible; it does not demand the full grid. Partial occlusion, missing border tiles, and background clutter all reduce to discarded Delaunay triangles.
- Scope: the method emits ordered integer-coordinate corner lists; it does not solve for camera intrinsics or extrinsics. Those are the downstream calibration problem (e.g. Zhang's method).
- Failure modes: steep viewing angles defocus the X-junctions and push Delaunay edges across tile corners simultaneously; both detection and topology degrade at the same time rather than catching each other. Low-contrast images starve at the first stage.
- Compared with Shu: see When to choose Shu over Laureano on the Shu page, which hosts the comparison per the older-paper-hosts rule.
References
- G. T. Laureano, M. S. V. de Paiva, A. S. da Silva. Topological Detection of Chessboard Pattern for Camera Calibration. IPCV (WorldComp), 2013. PDF
- C. Shu, A. Brunton, M. A. Fiala. A topological approach to finding grids in calibration patterns. Machine Vision and Applications, 2009. DOI: 10.1007/s00138-009-0202-2
- E. Rosten, T. Drummond. Machine Learning for High-Speed Corner Detection. ECCV, 2006. PDF