Skip to main content

calib_targets_chessboard/
lib.rs

1//! Invariant-first chessboard detector.
2//!
3//! Takes a slice of [ChESS](https://www.cl.cam.ac.uk/research/rainbow/projects/chess/)
4//! X-junction corners and returns an integer-labelled chessboard grid. The
5//! crate's only output contract is: *every labelled corner has been proven
6//! to sit at a real grid intersection.* Missing corners are acceptable;
7//! wrong corners are not.
8//!
9//! **High detection rate on our private regression set with zero wrong
10//! `(i, j)` labels** (non-negligible lens distortion and motion blur).
11//!
12//! Algorithm reference: see `book/src/chessboard.md`.
13//!
14//! # Pipeline
15//!
16//! 1. Pre-filter (strength + fit-quality + axes validity).
17//! 2. Global grid-direction centers `{Θ₀, Θ₁}` via axes-histogram + 2-means.
18//! 3. Per-corner cluster label (canonical vs swapped axis assignment).
19//! 4. Global cell-size `s` (cross-cluster nearest-neighbor mode).
20//! 5. Seed: pick a 2×2 quad passing every geometric invariant; cell size
21//!    comes OUT of the seed.
22//! 6. Grow: BFS over `(i, j)` boundary with the full invariant stack
23//!    enforced at every attachment.
24//! 7. Validate: line collinearity + local-H residual; blacklist outliers;
25//!    restart Stages 5–7 with the blacklist excluded.
26//! 8. Recall boosters: line extrapolation, interior gap fill, component
27//!    merge, weak-cluster rescue.
28//!
29//! Each stage is its own module; see the submodules.
30//!
31//! # Quickstart
32//!
33//! ```rust,ignore
34//! use calib_targets_chessboard::{Detector, DetectorParams};
35//! use calib_targets_core::Corner;
36//!
37//! fn detect(corners: &[Corner]) {
38//!     let det = Detector::new(DetectorParams::default());
39//!     if let Some(d) = det.detect(corners) {
40//!         println!("labelled {} corners", d.target.corners.len());
41//!     }
42//! }
43//! ```
44//!
45//! # Rectification helpers
46//!
47//! Two pattern-agnostic rectifiers are exposed under [`mesh_warp`] and
48//! [`rectified_view`]: they take a `&[LabeledCorner]` plus an inlier index
49//! list (typically `Detection::strong_indices`) and produce a rectified
50//! view. They are independent of the detector pipeline and can be used
51//! with any consistent `(i, j)` labelling.
52
53pub mod boosters;
54pub mod cell_size;
55pub mod cluster;
56pub mod corner;
57pub mod detector;
58pub mod grow;
59pub mod mesh_warp;
60pub mod params;
61pub mod rectified_view;
62pub mod seed;
63pub mod topological;
64pub mod validate;
65
66pub use boosters::{apply_boosters, BoosterResult};
67pub use cell_size::estimate_cell_size;
68pub use cluster::{cluster_axes, cluster_axes_debug, AxisCluster, ClusterCenters, ClusterDebug};
69pub use corner::{ClusterLabel, CornerAug, CornerStage};
70pub use detector::{
71    build_detection_from_grow, DebugFrame, Detection, Detector, InstrumentedResult, IterationTrace,
72    StageCounts, DEBUG_FRAME_SCHEMA,
73};
74pub use grow::{grow_from_seed, GrowResult};
75pub use mesh_warp::{rectify_mesh_from_grid, MeshWarpError, RectifiedMeshView};
76pub use params::{DetectorParams, GraphBuildAlgorithm};
77pub use rectified_view::{rectify_from_chessboard_result, RectifiedBoardView, RectifyError};
78pub use seed::{find_seed, Seed, SeedOutput};
79pub use topological::detect_all_topological;
80pub use validate::{validate, ValidationResult};