Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

PuzzleBoard pipeline

Composes: the chessboard grid stack + PuzzleBoard edge-code decode. Source of truth: crates/calib-targets-puzzleboard/docs/PIPELINE.md. Crate reference: calib-targets-puzzleboard.

A PuzzleBoard is a self-identifying chessboard: every interior edge carries a midpoint dot, and the dot pattern uniquely identifies a fragment’s position on a 501×501 master code. The pipeline runs the full chessboard grid stack first, then samples the interior-edge dots and decodes them into absolute master positions — so a visible fragment still yields absolute corner IDs and object-space coordinates.

End-to-end stages

#StageIn → OutWhat it does
0chessboard grid detectChESS corners → Vec<ChessDetection>The full chessboard pipeline (multi-component). Wrong (i, j) labels here become wrong absolute master labels — same precision-unrecoverable property as ChArUco.
1edge samplinglabelled corners + image → observed edgesPer interior edge: sample a disk of radius sample_radius_rel × edge_len at the midpoint, derive bright/dark references from the adjacent cells, classify into bit ∈ {0,1} with a confidence ∈ [0,1].
2bit-confidence filterobserved edges → high-confidence edgesDrop bits below min_bit_confidence; low-confidence bits become unknown.
3minimum-window gatefiltered edges → pass / failRequire the fragment to span min_window corners on both axes (default 7). That span carries 30 distinct code bits — the same information the paper’s 4 × 4 fragment carries — and is unique at every master position under the rotations-only search.
3bperiod-3 consensusfiltered edges → voted code bitsBoth maps repeat every three rows or columns, so collapse the dots onto the distinct bits they read, by confidence-weighted majority vote. Origin- and orientation-invariant, so it runs before any hypothesis. Ties are erasures, never guesses; too few surviving bits → NotEnoughLogicalBits.
4origin decodefiltered edges + master maps → (D4, origin) + scoreRecover the (D4 transform, master origin) via the cyclic class tables — Full (whole master) or FixedBoard (declared board’s rectangle) scope, scored by HardWeighted (BER gate) or SoftLogLikelihood (margin gate, default). Both are re-gated for uniqueness. See the decode algorithm.
5best-component selectionper-component results → one decodeRank components by edges-matched, then BER, then soft score. Conflict detection: two well-supported components disagreeing on master origin → InconsistentPosition (refuse, don’t guess).
6emit detectionbest decode → resultRebase (i, j) to non-negative; sort by (j, i); assign absolute IDs (j·501 + i) and target_position (i·cell_size, j·cell_size).

What it inherits from the chessboard detector

The full chessboard topological pipeline runs on the input ChESS corners — prefilter, axis clustering, the topological grid walk, booster-driven component recovery, and the mandatory final geometry check. PuzzleBoard already defaulted to the topological builder, which is the only builder and has no selector field.

The partial-view guarantee

For a given printed board, any subset of its corners decodes to the same master IDs a full-view decode would produce — across single-camera captures that frame only part of a large board and across multi-camera rigs where each camera sees a different fragment. Overlapping corners share master IDs without further stitching. FixedBoard mode sidesteps the per-view master-origin drift by scoring against the declared board rather than the full master.

Failure modes

SymptomLikely stageWhat it means / knob to try
No grid componentsStage 0 (chessboard)Sparse / empty corner cloud — see the chessboard failure modes. Try --upscale on small boards.
NotEnoughEdgesStage 2–3Too few high-confidence edge bits survived. Lower decode.min_bit_confidence; check that interior dots are resolved at this image scale.
Every hypothesis over BERStage 4 (HardWeighted)Board too small or too noisy. Raise decode.max_bit_error_rate, or switch to SoftLogLikelihood (more robust on ambiguous fragments).
Small / ambiguous decode marginStage 4 (SoftLogLikelihood)Near-symmetric fragment or few high-confidence bits. Capture a larger fragment; the margin gate is correctly refusing a coin-flip.
InconsistentPositionStage 5Two sub-grids disagree on the master origin — an unrecoverable ambiguity. Crop to a single board, or use FixedBoard with the known spec.
Wrong absolute IDsneverA wrong chessboard (i, j) would cause this — file a bug at the chessboard layer; the decode itself is exhaustive and gated.

Tuning

The ChESS corner front-end is params.chess (a DetectorConfig, consumed by the facade’s whole-image entry points); the grid side is the standard chessboard ChessboardParams (under params.chessboard); the decode side is params.decode:

  • min_bit_confidence (default 0.5) — the confidence floor for an edge bit to count. Lower on blurry boards; too low admits noise bits.
  • max_bit_error_rate (default 0.3) — the BER gate.
  • min_window (default 7) — the uniqueness floor; rarely changed, and lowering it trades misses for the risk of a wrong absolute label.
  • search_modeFull (default) vs FixedBoard (cheaper, fixes per-view origin drift when the board is known).
  • scoring_modeSoftLogLikelihood (default) vs HardWeighted (robust on ambiguous fragments; adds the margin gate).
  • symmetry_modeRotations (default; the four 90° rotations, correct for an ordinary camera) vs RotationsAndReflections (all eight dihedral transforms; enable only when the optical path mirrors the image).
  • search_all_components (default true) — decode every grid component and pick the best, with conflict detection.

For threshold-sensitive images use PuzzleBoardParams::sweep_for_board(&spec) with detect_puzzleboard_best. The sweep tries the default soft scorer first, then a hard-weighted fallback at the paper’s 40% BER allowance for high-distortion fragments. The naive hard-bit decoder already clears the precision/recall contract at zero wrong labels; do not rewrite to a coherent-hypothesis matcher without a demonstrated precision gap.

Cross-references