1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use crate::ndarray as nd;
use crate::opencv::core as cv;
use crate::with_opencv::MatExt as _;
use crate::with_opencv::OpenCvElement;
use crate::{common::*, TryFromCv};
impl<'a, A, D> TryFromCv<&'a cv::Mat> for nd::ArrayView<'a, A, D>
where
A: OpenCvElement,
D: nd::Dimension,
{
type Error = anyhow::Error;
fn try_from_cv(from: &'a cv::Mat) -> Result<Self, Self::Error> {
let src_shape = from.shape();
let array = nd::ArrayViewD::from_shape(src_shape, from.as_slice()?)?;
let array = array.into_dimensionality()?;
Ok(array)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::opencv::prelude::*;
use crate::TryIntoCv as _;
use itertools::chain;
use itertools::Itertools as _;
use rand::prelude::*;
#[test]
fn mat_ref_to_array_view_conversion() -> Result<()> {
let mut rng = rand::thread_rng();
for _ in 0..5 {
let ndim: usize = rng.gen_range(2..=4);
let shape: Vec<usize> = (0..ndim).map(|_| rng.gen_range(1..=32)).collect();
let mat = cv::Mat::new_randn::<f32>(&shape)?;
let array: nd::ArrayViewD<f32> = (&mat).try_into_cv()?;
shape
.iter()
.map(|&size| 0..size)
.multi_cartesian_product()
.try_for_each(|index| {
let index_cv: Vec<_> = index.iter().map(|&size| size as i32).collect();
let lhs: f32 = *mat.at_nd(&index_cv)?;
let index_nd: Vec<_> = chain!(index, [0]).collect();
let rhs = array[index_nd.as_slice()];
ensure!(lhs == rhs);
anyhow::Ok(())
})?;
}
Ok(())
}
}