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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! Ergonomic ChESS detector facade over `chess-corners-core`.
//!
//! # Overview
//!
//! This crate is the high-level entry point for the ChESS
//! (Chess-board Extraction by Subtraction and Summation) corner
//! detector. It re-exports the main configuration/result types
//! from [`chess_corners_core`] and adds:
//!
//! - single-scale detection on raw grayscale buffers via
//! [`find_chess_corners`],
//! - optional `image::GrayImage` helpers (see
//! `find_chess_corners_image`) when the `image` feature is
//! enabled,
//! - a coarse-to-fine multiscale detector configured through
//! [`ChessConfig`] and [`CoarseToFineParams`].
//!
//! The detector returns subpixel [`CornerDescriptor`] values in
//! full-resolution image coordinates. In most applications you
//! construct a [`ChessConfig`], optionally tweak its fields, and call
//! [`find_chess_corners`] or `find_chess_corners_image`.
//!
//! # Quick start
//!
//! ## Using `image` (default)
//!
//! The default feature set includes integration with the `image`
//! crate:
//!
//! ```no_run
//! use chess_corners::{ChessConfig, ChessParams, find_chess_corners_image};
//! use image::io::Reader as ImageReader;
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Load a grayscale chessboard image.
//! let img = ImageReader::open("board.png")?
//! .decode()?
//! .to_luma8();
//!
//! // Start from the recommended defaults.
//! let mut cfg = ChessConfig::default();
//! cfg.params = ChessParams::default();
//!
//! // For a single chessboard in the frame, 2–3 pyramid levels
//! // are often enough. Setting `num_levels` to 1 forces
//! // single-scale detection.
//! cfg.multiscale.pyramid.num_levels = 3;
//!
//! let corners = find_chess_corners_image(&img, &cfg);
//! println!("found {} corners", corners.len());
//!
//! for c in &corners {
//! println!(
//! "corner at ({:.2}, {:.2}), response {:.1}, theta {:.2} rad, phase {}",
//! c.x, c.y, c.response, c.orientation, c.phase,
//! );
//! }
//! # Ok(()) }
//! ```
//!
//! ## Raw grayscale buffer
//!
//! If you already have an 8-bit grayscale buffer, you can call the
//! detector directly without depending on `image`:
//!
//! ```no_run
//! use chess_corners::{ChessConfig, ChessParams, find_chess_corners_u8};
//!
//! # fn detect(img: &[u8], width: u32, height: u32) {
//! // Single-scale convenience configuration.
//! let mut cfg = ChessConfig::single_scale();
//! cfg.params = ChessParams::default();
//!
//! let corners = find_chess_corners_u8(img, width, height, &cfg);
//! println!("found {} corners", corners.len());
//! # let _ = corners;
//! # }
//! ```
//!
//! For tight processing loops you can also reuse pyramid storage
//! explicitly via [`find_chess_corners_buff`] and the internal
//! `pyramid` module; this avoids reallocating intermediate pyramid
//! levels across frames. Most users should stick to
//! [`find_chess_corners`] / `find_chess_corners_image` unless they
//! need fine-grained control over allocations.
//!
//! # Configuration
//!
//! [`ChessConfig`] combines the low-level ChESS parameters with
//! multiscale tuning:
//!
//! - [`ChessParams`] (re-exported from `chess-corners-core`) controls
//! the response kernel and detector behavior: ring radius, relative
//! or absolute threshold, non-maximum suppression radius, and the
//! minimum cluster size for accepting a corner.
//! - [`CoarseToFineParams`] describes how the multiscale detector
//! behaves: number of pyramid levels, minimum level size, coarse
//! ROI radius (at the smallest level) and merge radius for
//! deduplicating refined corners.
//!
//! The shortcut [`ChessConfig::single_scale`] configures a
//! single-scale run by setting `multiscale.pyramid.num_levels = 1`.
//! Any `pyramid.num_levels > 1` triggers the coarse-to-fine path:
//! corners are first detected on the smallest pyramid level and then
//! refined inside base-image regions of interest.
//!
//! If you need raw response maps or more control, depend directly on
//! `chess-corners-core` and use its [`chess_corners_core::response`]
//! and [`chess_corners_core::detect`] modules alongside the
//! re-exported [`ResponseMap`] and [`CornerDescriptor`] types.
//!
//! # Features
//!
//! - `image` *(default)* – enables `find_chess_corners_image` and
//! `image::GrayImage` integration.
//! - `rayon` – parallelizes response computation and multiscale
//! refinement over image rows. Combine with `par_pyramid` to
//! parallelize pyramid downsampling as well.
//! - `simd` – enables portable-SIMD accelerated inner loops for the
//! response kernel (requires a nightly compiler). Combine with
//! `par_pyramid` to SIMD-accelerate pyramid downsampling.
//! - `par_pyramid` – opt-in gate for SIMD/`rayon` acceleration inside
//! the pyramid builder.
//! - `tracing` – emits structured spans for multiscale detection,
//! suitable for use with `tracing-subscriber` or JSON tracing from
//! the CLI.
//! - `cli` – builds the `chess-corners` binary shipped with this
//! crate; it is not required when using the library as a
//! dependency.
//!
//! The library API is stable across feature combinations; features
//! only affect performance and observability, not numerical results.
// Re-export a focused subset of core types for convenience. Consumers that
// need lower-level primitives (rings, raw response functions, etc.) are
// encouraged to depend on `chess-corners-core` directly.
pub use ;
// High-level helpers on `image::GrayImage`.
pub use find_chess_corners_image;
// Multiscale/coarse-to-fine API types.
pub use crate;
pub use crate;
/// Unified detector configuration combining response/detector params and
/// multiscale/pyramid tuning.
/// Detect chessboard corners from a raw grayscale image buffer.
///
/// The `img` slice must be `width * height` bytes in row-major order.