Skip to main content

apple_vision/
recognized_points.rs

1//! Generic recognized-point wrappers shared by pose observations.
2
3use std::collections::HashMap;
4
5use crate::{
6    geometry::{Transform3D, VisionPoint, VisionPoint3D},
7    request_base::NormalizedRect,
8};
9
10/// A dedicated `VNDetectedPoint` wrapper.
11#[derive(Debug, Clone, Copy, PartialEq)]
12pub struct VisionDetectedPoint {
13    pub location: VisionPoint,
14    pub confidence: f32,
15}
16
17impl VisionDetectedPoint {
18    #[must_use]
19    pub const fn new(location: VisionPoint, confidence: f32) -> Self {
20        Self {
21            location,
22            confidence,
23        }
24    }
25
26    #[must_use]
27    pub const fn x(&self) -> f64 {
28        self.location.x
29    }
30
31    #[must_use]
32    pub const fn y(&self) -> f64 {
33        self.location.y
34    }
35}
36
37/// A single normalized `VNRecognizedPoint`.
38#[derive(Debug, Clone, Copy, PartialEq)]
39pub struct RecognizedPoint {
40    pub x: f64,
41    pub y: f64,
42    pub confidence: f32,
43}
44
45impl RecognizedPoint {
46    #[must_use]
47    pub const fn detected_point(self) -> VisionDetectedPoint {
48        VisionDetectedPoint::new(VisionPoint::new(self.x, self.y), self.confidence)
49    }
50}
51
52/// A dedicated `VNRecognizedPoint` wrapper.
53#[derive(Debug, Clone, PartialEq)]
54pub struct VisionRecognizedPoint {
55    pub identifier: String,
56    pub point: VisionDetectedPoint,
57}
58
59impl VisionRecognizedPoint {
60    #[must_use]
61    pub fn new(identifier: impl Into<String>, point: VisionDetectedPoint) -> Self {
62        Self {
63            identifier: identifier.into(),
64            point,
65        }
66    }
67}
68
69/// A generic `VNRecognizedPointsObservation` wrapper.
70#[derive(Debug, Clone, PartialEq)]
71pub struct RecognizedPointsObservation {
72    pub bounding_box: NormalizedRect,
73    pub confidence: f32,
74    pub available_keys: Vec<String>,
75    pub available_group_keys: Vec<String>,
76    pub points: HashMap<String, RecognizedPoint>,
77}
78
79impl RecognizedPointsObservation {
80    #[must_use]
81    pub fn point(&self, key: &str) -> Option<&RecognizedPoint> {
82        self.points.get(key)
83    }
84
85    #[must_use]
86    pub fn recognized_point(&self, key: &str) -> Option<VisionRecognizedPoint> {
87        self.point(key)
88            .copied()
89            .map(|point| VisionRecognizedPoint::new(key, point.detected_point()))
90    }
91
92    #[must_use]
93    pub fn recognized_points(&self) -> Vec<VisionRecognizedPoint> {
94        let mut keys = self.points.keys().cloned().collect::<Vec<_>>();
95        keys.sort();
96        keys.into_iter()
97            .filter_map(|key| self.recognized_point(&key))
98            .collect()
99    }
100}
101
102/// A single normalized `VNRecognizedPoint3D` / `VNHumanBodyRecognizedPoint3D`.
103#[derive(Debug, Clone, Copy, PartialEq)]
104pub struct RecognizedPoint3D {
105    pub x: f32,
106    pub y: f32,
107    pub z: f32,
108    pub confidence: f32,
109}
110
111impl RecognizedPoint3D {
112    #[must_use]
113    pub const fn point_3d(self) -> VisionPoint3D {
114        VisionPoint3D::from_xyz(self.x, self.y, self.z)
115    }
116}
117
118/// A dedicated `VNRecognizedPoint3D` wrapper.
119#[derive(Debug, Clone, PartialEq)]
120pub struct VisionRecognizedPoint3D {
121    pub identifier: String,
122    pub point: VisionPoint3D,
123    pub confidence: f32,
124}
125
126impl VisionRecognizedPoint3D {
127    #[must_use]
128    pub fn new(identifier: impl Into<String>, point: VisionPoint3D, confidence: f32) -> Self {
129        Self {
130            identifier: identifier.into(),
131            point,
132            confidence,
133        }
134    }
135}
136
137/// A dedicated `VNHumanBodyRecognizedPoint3D` wrapper.
138#[derive(Debug, Clone, PartialEq)]
139pub struct HumanBodyRecognizedPoint3D {
140    pub recognized_point: VisionRecognizedPoint3D,
141    pub local_position: Transform3D,
142    pub parent_joint: Option<String>,
143}
144
145impl HumanBodyRecognizedPoint3D {
146    #[must_use]
147    pub const fn new(
148        recognized_point: VisionRecognizedPoint3D,
149        local_position: Transform3D,
150        parent_joint: Option<String>,
151    ) -> Self {
152        Self {
153            recognized_point,
154            local_position,
155            parent_joint,
156        }
157    }
158}
159
160/// A generic `VNRecognizedPoints3DObservation` wrapper.
161#[derive(Debug, Clone, PartialEq)]
162pub struct RecognizedPoints3DObservation {
163    pub confidence: f32,
164    pub available_keys: Vec<String>,
165    pub available_group_keys: Vec<String>,
166    pub points: HashMap<String, RecognizedPoint3D>,
167}
168
169impl RecognizedPoints3DObservation {
170    #[must_use]
171    pub fn point(&self, key: &str) -> Option<&RecognizedPoint3D> {
172        self.points.get(key)
173    }
174
175    #[must_use]
176    pub fn recognized_point(&self, key: &str) -> Option<VisionRecognizedPoint3D> {
177        self.point(key)
178            .copied()
179            .map(|point| VisionRecognizedPoint3D::new(key, point.point_3d(), point.confidence))
180    }
181
182    #[must_use]
183    pub fn recognized_points(&self) -> Vec<VisionRecognizedPoint3D> {
184        let mut keys = self.points.keys().cloned().collect::<Vec<_>>();
185        keys.sort();
186        keys.into_iter()
187            .filter_map(|key| self.recognized_point(&key))
188            .collect()
189    }
190}