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