calib_targets_core/
corner.rs

1use nalgebra::{Point2, Vector2};
2use serde::{Deserialize, Serialize};
3
4/// Canonical 2D corner used by all target detectors.
5///
6/// This is the thing you obtain by adapting the output of your ChESS crate.
7#[derive(Clone, Debug, Serialize, Deserialize)]
8pub struct Corner {
9    /// Corner position in pixel coordinates.
10    pub position: Point2<f32>,
11
12    /// Dominant grid orientation at the corner, in radians.
13    ///
14    /// Convention:
15    /// - Defined modulo π (pi), not 2π, because chessboard axes are undirected.
16    /// - Typically points along one local grid axis.
17    pub orientation: f32,
18
19    pub orientation_cluster: Option<usize>, // Some(0 or 1) if clustered, None if outlier
20
21    /// Strength / response of the corner detector.
22    pub strength: f32,
23}
24
25impl Corner {
26    /// Convenience accessor for (x, y) as a vector.
27    pub fn as_vec2(&self) -> Vector2<f32> {
28        Vector2::new(self.position.x, self.position.y)
29    }
30}
31
32/// Integer grid coordinates (i, j) in board space.
33#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
34pub struct GridCoords {
35    pub i: i32,
36    pub j: i32,
37}
38
39/// The kind of target that a detection corresponds to.
40#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
41#[serde(rename_all = "snake_case")]
42pub enum TargetKind {
43    Chessboard,
44    Charuco,
45    CheckerboardMarker,
46}
47
48/// A corner that is part of a detected target, with optional ID info.
49#[derive(Clone, Debug, Serialize, Deserialize)]
50pub struct LabeledCorner {
51    /// Pixel position.
52    pub position: Point2<f32>,
53
54    /// Optional integer grid coordinates (i, j).
55    pub grid: Option<GridCoords>,
56
57    /// Optional logical ID (e.g. ChArUco or marker-board ID).
58    pub id: Option<u32>,
59
60    /// Optional target-space position in millimeters (paired with `id`).
61    #[serde(default)]
62    pub target_position: Option<Point2<f32>>,
63
64    /// Detection score (higher is better).
65    ///
66    /// The meaning depends on the detector (it may be unnormalized).
67    #[serde(alias = "confidence")]
68    pub score: f32,
69}
70
71/// One detected target (board instance) in an image.
72#[derive(Clone, Debug, Serialize, Deserialize)]
73pub struct TargetDetection {
74    pub kind: TargetKind,
75    pub corners: Vec<LabeledCorner>,
76}