chess_corners/config/multiscale.rs
1use serde::{Deserialize, Serialize};
2
3/// Coarse-to-fine multiscale configuration.
4///
5/// JSON shape mirrors [`crate::UpscaleConfig`]:
6///
7/// - `"single_scale"` — run the detector once on the full image.
8/// - `{ "pyramid": { "levels": 3, "min_size": 128, "refinement_radius": 3 } }`
9/// — build an image pyramid, detect seeds on the coarsest level, and
10/// refine each seed into the base image. Honoured by both ChESS and
11/// Radon strategies.
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
13#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
14#[serde(rename_all = "snake_case")]
15#[non_exhaustive]
16pub enum MultiscaleConfig {
17 /// Single-scale detection (no pyramid).
18 #[default]
19 SingleScale,
20 /// Coarse-to-fine pyramid detection.
21 Pyramid {
22 /// Number of pyramid levels (integer `>= 1`, at most 255). Level 0
23 /// is the base image; each subsequent level is a 2× box-filter
24 /// downsample.
25 #[cfg_attr(feature = "schemars", schemars(range(min = 1)))]
26 levels: u8,
27 /// Minimum short-edge length of a pyramid level, in pixels. The
28 /// pyramid stops once the next level would fall below this size.
29 #[cfg_attr(feature = "schemars", schemars(extend("x-unit" = "px")))]
30 min_size: usize,
31 /// ROI half-radius at the coarse level used to refine each seed
32 /// into the base image, in coarse-level pixels (integer `>= 0`).
33 #[cfg_attr(feature = "schemars", schemars(extend("x-unit" = "px")))]
34 refinement_radius: u32,
35 },
36}
37
38impl MultiscaleConfig {
39 /// Three-level pyramid with library defaults (`min_size = 128`, `refinement_radius = 3`).
40 /// Equivalent to the multiscale preset used by [`crate::DetectorConfig::chess_multiscale`]
41 /// and [`crate::DetectorConfig::radon_multiscale`].
42 pub const fn pyramid_default() -> Self {
43 Self::Pyramid {
44 levels: 3,
45 min_size: 128,
46 refinement_radius: 3,
47 }
48 }
49 /// Pyramid with caller-supplied parameters.
50 pub const fn pyramid(levels: u8, min_size: usize, refinement_radius: u32) -> Self {
51 Self::Pyramid {
52 levels,
53 min_size,
54 refinement_radius,
55 }
56 }
57}