Skip to main content

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}