1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! ChESS detector configuration types surfaced by the workspace's own API.
//!
//! Re-exports only the two `chess-corners` facade types the workspace's
//! public API legitimately exposes: [`DetectorConfig`], the high-level ChESS
//! config object callers construct (strategy + threshold + multiscale +
//! upscale), and [`OrientationMethod`], the documented orientation knob.
//!
//! Advanced ChESS tuning types (`ChessConfig`, `RadonConfig`, `RefinerKind`,
//! …) are intentionally *not* re-exported here — re-exporting the whole
//! upstream surface would freeze `chess-corners`'s API into this crate's
//! semver contract. Callers needing those types depend on the
//! `chess-corners` crate directly, where they belong.
//!
//! This module also owns [`default_chess_config`], the single definition of
//! the workspace's corner front-end settings. It lives here rather than on
//! the facade because every detector's params struct carries a
//! `DetectorConfig` and must be able to default it without depending on the
//! facade (which would be a dependency cycle).
//!
//! Workspace-only preprocessing (the optional same-size Gaussian pre-blur)
//! is exposed as a standalone helper at the facade level
//! (`calib_targets::preprocess`); detection entry points operate on the
//! image as supplied so the library no longer conflates preprocessing
//! with detection.
pub use ;
/// The workspace's ChESS acceptance threshold.
///
/// Kept as a named constant so the value has exactly one definition and the
/// test that guards it against upstream drift can name it.
const WORKSPACE_CHESS_THRESHOLD: f32 = 15.0;
/// Reasonable default settings for the `chess-corners` ChESS detector.
///
/// Built on top of [`DetectorConfig::chess`] but overrides the acceptance
/// threshold to `15.0`. Since `chess-corners` 1.0 the threshold is a single
/// `f32` that the ChESS strategy reads as an absolute floor on the raw
/// response; the paper-faithful contract is `0.0`, which is correct in
/// principle (any strictly positive ChESS response is a corner candidate) but
/// produces hundreds of weak responses on real-world images. The
/// topological grid pipeline is sensitive to that noise floor: on
/// `testdata/puzzleboard_reference/example3.png`, threshold `0.0` produces
/// zero labelled corners while `15.0` recovers the full 30-corner component;
/// on `testdata/small0.png` the labelled count rises from 78 to 129; and on
/// the `02-topo-grid/` synthetic suite the topological pipeline only clears
/// every recall gate at `≥ 15.0`. The cutoff was chosen by sweeping the
/// public testdata regression set; see
/// `crates/calib-targets/examples/threshold_sweep.rs`.
///
/// Note this is *lower* than upstream's own 1.0 default of `30.0`. That is
/// deliberate and unchanged in substance: the workspace has always overridden
/// the upstream default, and the ChESS response scale did not change in 1.0,
/// so `15.0` keeps producing exactly the corner set it did under 0.11.
///
/// This is the default value of the `chess` field carried by the
/// compound-target params structs — `CharucoParams`, `PuzzleBoardParams`, and
/// `MarkerBoardParams` — whose facade image entry points own their corner pass;
/// override the front-end by replacing `params.chess`. The plain chessboard
/// path is the deliberate exception: `detect_chessboard(img, &chess_cfg,
/// ¶ms)` takes the corner config as an explicit argument alongside
/// `ChessboardParams`, because the chessboard detector is a reusable
/// corner-cloud consumer rather than a whole-image pipeline. Either way, a
/// coarse-to-fine pyramid via `MultiscaleConfig::Pyramid` or a pre-pipeline
/// `UpscaleConfig::Fixed` for low-resolution boards is a matter of replacing
/// this config where the entry point reads it.
///
/// Callers wanting the raw upstream behaviour can construct
/// [`DetectorConfig::chess`] directly.