cv_convert/
with_opencv.rs

1use crate::opencv::{core as core_cv, prelude::*};
2use crate::{common::*, TryFromCv};
3use half::f16;
4
5pub use element_type::*;
6mod element_type {
7    use super::*;
8
9    pub trait OpenCvElement {
10        const DEPTH: i32;
11    }
12
13    impl OpenCvElement for u8 {
14        const DEPTH: i32 = core_cv::CV_8U;
15    }
16
17    impl OpenCvElement for i8 {
18        const DEPTH: i32 = core_cv::CV_8S;
19    }
20
21    impl OpenCvElement for u16 {
22        const DEPTH: i32 = core_cv::CV_16U;
23    }
24
25    impl OpenCvElement for i16 {
26        const DEPTH: i32 = core_cv::CV_16S;
27    }
28
29    impl OpenCvElement for i32 {
30        const DEPTH: i32 = core_cv::CV_32S;
31    }
32
33    impl OpenCvElement for f16 {
34        const DEPTH: i32 = core_cv::CV_16F;
35    }
36
37    impl OpenCvElement for f32 {
38        const DEPTH: i32 = core_cv::CV_32F;
39    }
40
41    impl OpenCvElement for f64 {
42        const DEPTH: i32 = core_cv::CV_64F;
43    }
44}
45
46pub(crate) use mat_ext::*;
47mod mat_ext {
48    use super::*;
49
50    pub trait MatExt {
51        fn size_with_depth(&self) -> Vec<usize>;
52
53        fn numel(&self) -> usize {
54            self.size_with_depth().iter().product()
55        }
56
57        fn as_slice<T>(&self) -> Result<&[T]>
58        where
59            T: OpenCvElement;
60
61        fn type_name(&self) -> String;
62
63        #[cfg(test)]
64        fn new_randn_2d(rows: i32, cols: i32, typ: i32) -> Result<Self>
65        where
66            Self: Sized;
67
68        #[cfg(test)]
69        fn new_randn_nd<T>(shape: &[usize]) -> Result<Self>
70        where
71            Self: Sized,
72            T: OpenCvElement;
73    }
74
75    impl MatExt for core_cv::Mat {
76        fn size_with_depth(&self) -> Vec<usize> {
77            let size = self.mat_size();
78            let size = size.iter().map(|&dim| dim as usize);
79            let channels = self.channels() as usize;
80            size.chain([channels]).collect()
81        }
82
83        fn as_slice<T>(&self) -> Result<&[T]>
84        where
85            T: OpenCvElement,
86        {
87            ensure!(self.depth() == T::DEPTH, "element type mismatch");
88            ensure!(self.is_continuous(), "Mat data must be continuous");
89
90            let numel = self.numel();
91            let ptr = self.ptr(0)? as *const T;
92
93            let slice = unsafe { slice::from_raw_parts(ptr, numel) };
94            Ok(slice)
95        }
96
97        fn type_name(&self) -> String {
98            core_cv::type_to_string(self.typ()).unwrap()
99        }
100
101        #[cfg(test)]
102        fn new_randn_2d(rows: i32, cols: i32, typ: i32) -> Result<Self>
103        where
104            Self: Sized,
105        {
106            let mut mat = Self::zeros(rows, cols, typ)?.to_mat()?;
107            core_cv::randn(&mut mat, &0.0, &1.0)?;
108            Ok(mat)
109        }
110
111        #[cfg(test)]
112        fn new_randn_nd<T>(shape: &[usize]) -> Result<Self>
113        where
114            T: OpenCvElement,
115        {
116            let shape: Vec<_> = shape.iter().map(|&val| val as i32).collect();
117            let mut mat = Self::zeros_nd(&shape, T::DEPTH)?.to_mat()?;
118            core_cv::randn(&mut mat, &0.0, &1.0)?;
119            Ok(mat)
120        }
121    }
122}
123
124impl<T> TryFromCv<&core_cv::Mat> for core_cv::Point_<T>
125where
126    T: core_cv::DataType,
127{
128    type Error = Error;
129
130    fn try_from_cv(from: &core_cv::Mat) -> Result<Self> {
131        let slice = from.data_typed::<T>()?;
132        ensure!(slice.len() == 2, "invalid length");
133        let point = Self {
134            x: slice[0],
135            y: slice[1],
136        };
137        Ok(point)
138    }
139}
140
141impl<T> TryFromCv<core_cv::Mat> for core_cv::Point_<T>
142where
143    T: core_cv::DataType,
144{
145    type Error = Error;
146
147    fn try_from_cv(from: core_cv::Mat) -> Result<Self> {
148        TryFromCv::try_from_cv(&from)
149    }
150}
151
152impl<T> TryFromCv<&core_cv::Mat> for core_cv::Point3_<T>
153where
154    T: core_cv::DataType,
155{
156    type Error = Error;
157
158    fn try_from_cv(from: &core_cv::Mat) -> Result<Self> {
159        let slice = from.data_typed::<T>()?;
160        ensure!(slice.len() == 3, "invalid length");
161        let point = Self {
162            x: slice[0],
163            y: slice[1],
164            z: slice[2],
165        };
166        Ok(point)
167    }
168}
169
170impl<T> TryFromCv<core_cv::Mat> for core_cv::Point3_<T>
171where
172    T: core_cv::DataType,
173{
174    type Error = Error;
175
176    fn try_from_cv(from: core_cv::Mat) -> Result<Self> {
177        TryFromCv::try_from_cv(&from)
178    }
179}
180
181impl<T> TryFromCv<&core_cv::Point_<T>> for core_cv::Mat
182where
183    T: core_cv::DataType,
184{
185    type Error = Error;
186
187    fn try_from_cv(from: &core_cv::Point_<T>) -> Result<Self> {
188        let core_cv::Point_ { x, y, .. } = *from;
189        let mat = core_cv::Mat::from_slice(&[x, y])?;
190        Ok(mat)
191    }
192}
193
194impl<T> TryFromCv<core_cv::Point_<T>> for core_cv::Mat
195where
196    T: core_cv::DataType,
197{
198    type Error = Error;
199
200    fn try_from_cv(from: core_cv::Point_<T>) -> Result<Self> {
201        TryFromCv::try_from_cv(&from)
202    }
203}
204
205impl<T> TryFromCv<&core_cv::Point3_<T>> for core_cv::Mat
206where
207    T: core_cv::DataType,
208{
209    type Error = Error;
210
211    fn try_from_cv(from: &core_cv::Point3_<T>) -> Result<Self> {
212        let core_cv::Point3_ { x, y, z, .. } = *from;
213        let mat = core_cv::Mat::from_slice(&[x, y, z])?;
214        Ok(mat)
215    }
216}
217
218impl<T> TryFromCv<core_cv::Point3_<T>> for core_cv::Mat
219where
220    T: core_cv::DataType,
221{
222    type Error = Error;
223
224    fn try_from_cv(from: core_cv::Point3_<T>) -> Result<Self> {
225        TryFromCv::try_from_cv(&from)
226    }
227}