use std::ffi::c_void;
use matches::assert_matches;
use opencv::core::{MatConstIterator, Point, Point2d, Rect, Scalar, Size, Vec2b, Vec3d, Vec3f, Vec4w};
use opencv::prelude::*;
use opencv::types::{VectorOfMat, VectorOfi32};
use opencv::{core, Error, Result};
const PIXEL: &[u8] = include_bytes!("pixel.png");
#[test]
fn mat_default() -> Result<()> {
let mat = Mat::default();
assert_eq!(u8::typ(), mat.typ());
assert_eq!(u8::depth(), mat.depth());
assert_eq!(u8::channels(), mat.channels());
assert_eq!(Size::new(0, 0), mat.size()?);
assert_eq!(0, mat.dims());
assert!(!mat.is_allocated());
assert!(mat.data().is_null());
Ok(())
}
#[test]
fn mat_create() -> Result<()> {
let mut mat = Mat::default();
unsafe { mat.create_rows_cols(10, 10, u16::typ())? };
assert!(mat.is_allocated());
assert!(!mat.data().is_null());
mat.set(Scalar::from(7.))?;
assert_eq!(7, *mat.at_2d::<u16>(0, 0)?);
assert_eq!(7, *mat.at_2d::<u16>(3, 3)?);
assert_eq!(7, *mat.at_2d::<u16>(9, 9)?);
mat.release()?;
assert!(!mat.is_allocated());
assert!(mat.data().is_null());
assert_eq!(Size::new(0, 0), mat.size()?);
Ok(())
}
#[test]
fn mat_from_iter() -> Result<()> {
{
let mut vec = VectorOfi32::new();
vec.push(1);
vec.push(2);
vec.push(3);
let mat = Mat::from_exact_iter(vec.into_iter())?;
assert_eq!(3, mat.rows());
assert_eq!(1, mat.cols());
assert_eq!(i32::typ(), mat.typ());
assert_eq!(1, *mat.at_2d::<i32>(0, 0)?);
assert_eq!(2, *mat.at_2d::<i32>(1, 0)?);
assert_eq!(3, *mat.at_2d::<i32>(2, 0)?);
}
{
let vec: Vec<i32> = vec![1, 2, 3];
let mat = Mat::from_exact_iter(vec.into_iter())?;
assert_eq!(3, mat.rows());
assert_eq!(1, mat.cols());
assert_eq!(i32::typ(), mat.typ());
assert_eq!(1, *mat.at_2d::<i32>(0, 0)?);
assert_eq!(2, *mat.at_2d::<i32>(1, 0)?);
assert_eq!(3, *mat.at_2d::<i32>(2, 0)?);
}
Ok(())
}
#[test]
fn mat_for_rows_and_cols() -> Result<()> {
let mat = unsafe { Mat::new_rows_cols(400, 300, Vec3d::typ()) }?;
assert_eq!(Vec3d::typ(), mat.typ());
assert_eq!(Vec3d::depth(), mat.depth());
assert_eq!(Vec3d::channels(), mat.channels());
assert!(mat.is_continuous());
assert!(!mat.is_submatrix());
assert_eq!(Size::new(300, 400), mat.size()?);
assert_eq!(400, mat.rows());
assert_eq!(300, mat.cols());
assert_eq!(2, mat.mat_size().len());
assert_eq!(400, mat.mat_size()[0]);
assert_eq!(300, mat.mat_size()[1]);
assert_eq!(2, mat.dims());
assert_eq!(2, mat.mat_step().len());
assert_eq!(7200, mat.mat_step()[0]);
assert_eq!(24, mat.mat_step()[1]);
assert_eq!(24, mat.elem_size()?);
assert_eq!(8, mat.elem_size1());
assert_eq!(900, mat.step1(0)?);
assert_eq!(3, mat.step1(1)?);
assert_eq!(120000, mat.total());
Ok(())
}
#[test]
fn mat_nd() -> Result<()> {
{
let mut mat = Mat::new_nd_with_default(&[3, 3, 3], Vec4w::typ(), Scalar::default())?;
assert_matches!(
mat.at::<Vec4w>(0),
Err(Error {
code: core::StsUnmatchedSizes,
..
})
);
assert_eq!(0, mat.at_3d::<Vec4w>(1, 1, 1)?[0]);
*mat.at_3d_mut::<Vec4w>(1, 1, 1)? = Vec4w::all(10);
assert_eq!(10, mat.at_3d::<Vec4w>(1, 1, 1)?[0]);
assert_eq!(0, mat.at_3d::<Vec4w>(1, 1, 2)?[2]);
assert_eq!(3, mat.dims());
assert_eq!([3, 3, 3], *mat.mat_size());
}
{
let dims = VectorOfi32::from_iter(vec![2, 3, 4, 5, 6, 7]);
let mut mat = Mat::new_nd_vec_with_default(&dims, Vec4w::typ(), Scalar::default())?;
assert_eq!(-1, mat.rows());
assert_eq!(-1, mat.cols());
assert_matches!(
mat.at_nd::<Vec4w>(&[1, 1, 1]),
Err(Error {
code: core::StsUnmatchedSizes,
..
})
);
assert_matches!(
mat.at_nd::<Vec4w>(&[1, 1, 1, 1, 1, 1, 1]),
Err(Error {
code: core::StsUnmatchedSizes,
..
})
);
assert_matches!(
mat.at_nd::<Vec4w>(&[10, 10, 10, 10, 10, 10]),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_nd::<Vec4w>(&[-1, 10, 10, 10, 10, 10]),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_nd::<Vec4w>(&[2, 3, 4, 5, 10, 10]),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_nd::<Vec4w>(&[2, 3, 4, 5, 6, 10]),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_eq!(Vec4w::default(), *mat.at_nd::<Vec4w>(&[1, 2, 3, 4, 5, 6])?);
*mat.at_nd_mut::<Vec4w>(&[1, 2, 3, 4, 5, 6])? = Vec4w::from([5, 6, 7, 8]);
assert_eq!(Vec4w::from([5, 6, 7, 8]), *mat.at_nd::<Vec4w>(&[1, 2, 3, 4, 5, 6])?);
}
Ok(())
}
#[test]
fn mat_at_1d() -> Result<()> {
let s: Vec<Vec<f32>> = vec![vec![1., 2., 3.], vec![4., 5., 6.], vec![7., 8., 9.]];
{
let mat = Mat::from_slice_2d(&s)?;
let mut mat = mat.reshape(1, 1)?;
assert_eq!(1, mat.rows());
assert_eq!(9, mat.cols());
assert_matches!(
mat.at::<f32>(-1),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at::<f32>(10),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_mut::<f32>(-1),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_mut::<f32>(10),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_eq!(*mat.at::<f32>(0)?, 1.);
assert_eq!(*mat.at::<f32>(5)?, 6.);
assert_eq!(*mat.at::<f32>(8)?, 9.);
*mat.at_mut::<f32>(4)? = 2.;
assert_eq!(*mat.at::<f32>(4)?, 2.);
}
{
let mat = Mat::from_slice_2d(&s)?;
let mut mat = mat.reshape(1, 9)?;
assert_eq!(9, mat.rows());
assert_eq!(1, mat.cols());
assert_matches!(
mat.at::<f32>(-1),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at::<f32>(10),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_mut::<f32>(-1),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_mut::<f32>(10),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_eq!(*mat.at::<f32>(0)?, 1.);
assert_eq!(*mat.at::<f32>(4)?, 5.);
assert_eq!(*mat.at::<f32>(8)?, 9.);
*mat.at_mut::<f32>(4)? = 2.;
assert_eq!(*mat.at::<f32>(4)?, 2.);
}
{
let mut mat = Mat::from_slice_2d(&s)?;
assert_matches!(
mat.at::<f32>(-1),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at::<f32>(10),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_mut::<f32>(-1),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_mut::<f32>(10),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_eq!(*mat.at::<f32>(0)?, 1.);
assert_eq!(*mat.at::<f32>(6)?, 7.);
assert_eq!(*mat.at::<f32>(8)?, 9.);
*mat.at_mut::<f32>(4)? = 2.;
assert_eq!(*mat.at::<f32>(4)?, 2.);
}
Ok(())
}
#[test]
fn mat_2d_i0_is_rows_i1_is_cols() -> Result<()> {
let mat = Mat::new_size_with_default(Size::new(6, 5), f32::typ(), Scalar::from(1.23))?;
let size = mat.size()?;
assert_eq!(size.width, 6);
assert_eq!(size.height, 5);
Ok(())
}
#[test]
fn mat_at_2d() -> Result<()> {
let mut mat = Mat::new_rows_cols_with_default(100, 100, f32::typ(), Scalar::from(1.23))?;
assert_eq!(*mat.at_2d::<f32>(0, 0)?, 1.23);
*mat.at_2d_mut::<f32>(0, 0)? = 1.;
assert_eq!(*mat.at_2d::<f32>(0, 0)?, 1.);
assert_matches!(
mat.at::<i32>(0),
Err(Error {
code: core::StsUnmatchedFormats,
..
})
);
assert_matches!(
mat.at::<f32>(10000),
Err(Error {
code: core::StsOutOfRange,
..
})
);
Ok(())
}
#[test]
fn mat_at_2d_multichannel() -> Result<()> {
let mut mat = Mat::new_rows_cols_with_default(100, 100, Vec3f::typ(), Scalar::all(1.23))?;
let pix = *mat.at_2d::<Vec3f>(0, 0)?;
assert_eq!(pix[0], 1.23);
assert_eq!(pix[1], 1.23);
assert_eq!(pix[2], 1.23);
*mat.at_2d_mut::<Vec3f>(0, 0)? = Vec3f::from([1.1, 2.2, 3.3]);
let pix = *mat.at_2d::<Vec3f>(0, 0)?;
assert_eq!(pix[0], 1.1);
assert_eq!(pix[1], 2.2);
assert_eq!(pix[2], 3.3);
assert_matches!(
mat.at_2d::<i32>(0, 0),
Err(Error {
code: core::StsUnmatchedFormats,
..
})
);
assert_matches!(
mat.at_2d::<Vec3f>(100, 1),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_2d::<Vec3f>(1, 100),
Err(Error {
code: core::StsOutOfRange,
..
})
);
Ok(())
}
#[test]
fn mat_at_row() -> Result<()> {
let mut mat = Mat::new_rows_cols_with_default(100, 100, f32::typ(), Scalar::from(1.23))?;
let row = mat.at_row::<f32>(0)?;
assert_eq!(row.len(), 100);
assert_eq!(row[0], 1.23);
let row = mat.at_row_mut::<f32>(1)?;
row[0..4].copy_from_slice(&[10., 20., 30., 40.]);
let data = mat.data_typed::<f32>()?;
assert_eq!(data[0], 1.23);
assert_eq!(data[100], 10.);
assert_eq!(data[101], 20.);
assert_eq!(data[102], 30.);
assert_eq!(data[103], 40.);
assert_matches!(
mat.at_row::<i32>(0),
Err(Error {
code: core::StsUnmatchedFormats,
..
})
);
assert_matches!(
mat.at_row::<f32>(100),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
mat.at_row_mut::<i32>(0),
Err(Error {
code: core::StsUnmatchedFormats,
..
})
);
assert_matches!(
mat.at_row_mut::<f32>(100),
Err(Error {
code: core::StsOutOfRange,
..
})
);
Ok(())
}
#[test]
fn mat_at_pt() -> Result<()> {
let s: Vec<Vec<f32>> = vec![vec![1., 2., 3.], vec![4., 5., 6.], vec![7., 8., 9.]];
let mut m = Mat::from_slice_2d(&s)?;
assert_eq!(5., *m.at_pt::<f32>(Point::new(1, 1))?);
assert_eq!(4., *m.at_pt_mut::<f32>(Point::new(0, 1))?);
assert_eq!(3., unsafe { *m.at_pt_unchecked::<f32>(Point::new(2, 0))? });
assert_eq!(9., unsafe { *m.at_pt_unchecked_mut::<f32>(Point::new(2, 2))? });
assert_matches!(
m.at_pt::<f32>(Point::new(-1, -3)),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_matches!(
m.at_pt::<f32>(Point::new(3, -3)),
Err(Error {
code: core::StsOutOfRange,
..
})
);
Ok(())
}
#[test]
fn mat_vec() -> Result<()> {
{
let s: Vec<Vec<f32>> = vec![vec![1., 2., 3.], vec![4., 5., 6.], vec![7., 8., 9.]];
let mat = Mat::from_slice_2d(&s)?;
assert_eq!(mat.size()?, core::Size { width: 3, height: 3 });
assert_eq!(*mat.at_2d::<f32>(1, 1)?, 5.);
let v = mat.to_vec_2d::<f32>()?;
assert_eq!(s, v);
}
{
let mut dims = VectorOfi32::new();
dims.push(3);
dims.push(3);
dims.push(3);
let mut mat = Mat::new_nd_vec_with_default(&dims, f64::typ(), Scalar::from(2.))?;
*mat.at_3d_mut::<f64>(1, 1, 1)? = 10.;
assert_eq!(3, mat.dims());
if mat.to_vec_2d::<f64>().is_ok() {
panic!("dims too high");
}
}
Ok(())
}
#[test]
fn mat_continuous() -> Result<()> {
let s: Vec<Vec<f32>> = vec![vec![1., 2., 3.], vec![4., 5., 6.], vec![7., 8., 9.]];
let mat = Mat::from_slice_2d(&s)?;
{
let sub_mat_non_cont = Mat::roi(&mat, Rect::new(1, 1, 2, 2))?;
assert_eq!(mat.typ(), sub_mat_non_cont.typ());
assert_eq!(2, sub_mat_non_cont.rows());
assert_eq!(2, sub_mat_non_cont.cols());
assert!(sub_mat_non_cont.is_submatrix());
assert!(!sub_mat_non_cont.is_continuous());
assert_eq!(5., *sub_mat_non_cont.at_2d::<f32>(0, 0)?);
assert_eq!(6., *sub_mat_non_cont.at_2d::<f32>(0, 1)?);
assert_eq!(8., *sub_mat_non_cont.at_2d::<f32>(1, 0)?);
assert_eq!(9., *sub_mat_non_cont.at_2d::<f32>(1, 1)?);
let vec = sub_mat_non_cont.to_vec_2d::<f32>()?;
assert_eq!(5., vec[0][0]);
assert_eq!(6., vec[0][1]);
assert_eq!(8., vec[1][0]);
assert_eq!(9., vec[1][1]);
let mat_clone = sub_mat_non_cont.try_clone()?;
assert_eq!(mat.typ(), mat_clone.typ());
assert_eq!(2, mat_clone.rows());
assert_eq!(2, mat_clone.cols());
assert!(!mat_clone.is_submatrix());
assert!(mat_clone.is_continuous());
assert_eq!(5., *mat_clone.at_2d::<f32>(0, 0)?);
assert_eq!(6., *mat_clone.at_2d::<f32>(0, 1)?);
assert_eq!(8., *mat_clone.at_2d::<f32>(1, 0)?);
assert_eq!(9., *mat_clone.at_2d::<f32>(1, 1)?);
}
{
let sub_mat_cont = Mat::roi(&mat, Rect::new(0, 1, 3, 2))?;
assert_eq!(mat.typ(), sub_mat_cont.typ());
assert_eq!(2, sub_mat_cont.rows());
assert_eq!(3, sub_mat_cont.cols());
assert!(sub_mat_cont.is_submatrix());
assert!(sub_mat_cont.is_continuous());
assert_eq!(4., *sub_mat_cont.at_2d::<f32>(0, 0)?);
assert_eq!(6., *sub_mat_cont.at_2d::<f32>(0, 2)?);
assert_eq!(7., *sub_mat_cont.at_2d::<f32>(1, 0)?);
assert_eq!(9., *sub_mat_cont.at_2d::<f32>(1, 2)?);
let vec = sub_mat_cont.to_vec_2d::<f32>()?;
assert_eq!(4., vec[0][0]);
assert_eq!(6., vec[0][2]);
assert_eq!(7., vec[1][0]);
assert_eq!(9., vec[1][2]);
}
{
let mut sub_mat_non_cont = Mat::roi(&mat, Rect::new(1, 1, 1, 2))?;
assert!(!sub_mat_non_cont.is_continuous());
assert_matches!(
sub_mat_non_cont.data_typed::<f32>(),
Err(Error {
code: core::StsUnmatchedSizes,
..
})
);
assert_matches!(
sub_mat_non_cont.data_typed_mut::<f32>(),
Err(Error {
code: core::StsUnmatchedSizes,
..
})
);
}
Ok(())
}
#[test]
fn mat_operations() -> Result<()> {
let mut src = VectorOfMat::new();
src.push(Mat::new_rows_cols_with_default(1, 3, u8::typ(), Scalar::from(1.))?);
src.push(Mat::new_rows_cols_with_default(1, 3, u8::typ(), Scalar::from(2.))?);
let mut merged = Mat::default();
core::merge(&src, &mut merged)?;
assert_eq!(merged.typ(), Vec2b::typ());
assert_eq!(merged.at_2d::<Vec2b>(0, 1)?[0], 1);
assert_eq!(merged.at_2d::<Vec2b>(0, 2)?[1], 2);
let mut split = VectorOfMat::new();
core::split(&merged, &mut split)?;
assert_eq!(2, split.len());
let mat = split.get(0)?;
assert_eq!(u8::typ(), mat.typ());
assert_eq!(1, mat.channels());
assert_eq!(1, *mat.at_2d::<u8>(0, 2)?);
let mat = split.get(1)?;
assert_eq!(u8::typ(), mat.typ());
assert_eq!(1, mat.channels());
assert_eq!(2, *mat.at_2d::<u8>(0, 0)?);
Ok(())
}
#[test]
fn mat_from_data() -> Result<()> {
let mut bytes = PIXEL.to_vec();
assert_eq!(90, bytes.len());
{
let src = unsafe {
Mat::new_rows_cols_with_data(
1,
PIXEL.len() as _,
u8::typ(),
bytes.as_mut_ptr() as *mut c_void,
core::Mat_AUTO_STEP,
)?
};
assert_eq!(Size::new(PIXEL.len() as _, 1), src.size()?);
assert_eq!(PIXEL.len(), src.total());
let row = src.at_row::<u8>(0)?;
assert_eq!(0x89, row[0]);
assert_eq!(0x50, row[1]);
assert_eq!(0x1A, row[6]);
assert_eq!(0x0D, row[11]);
assert_eq!(0x82, row[89]);
}
{
let src = unsafe { Mat::new_nd_with_data(&[3, 5, 6], u8::typ(), bytes.as_mut_ptr() as *mut c_void, None)? };
assert_eq!(Size::new(5, 3), src.size()?);
assert_eq!(PIXEL.len(), src.total());
assert_eq!(0x89, *src.at_3d::<u8>(0, 0, 0)?);
assert_eq!(0x50, *src.at_3d::<u8>(0, 0, 1)?);
assert_eq!(0x1A, *src.at_3d::<u8>(0, 1, 0)?);
assert_eq!(0x0D, *src.at_3d::<u8>(0, 1, 5)?);
assert_eq!(0x82, *src.at_3d::<u8>(2, 4, 5)?);
}
{
let mut bytes = bytes.clone();
let mut mat = unsafe {
Mat::new_rows_cols_with_data(
1,
bytes.len() as i32,
u8::typ(),
bytes.as_mut_ptr() as *mut c_void,
core::Mat_AUTO_STEP,
)?
};
assert_eq!(mat.data(), bytes.as_ptr());
bytes[0] = 0xFF;
assert_eq!(0xFF, *mat.at::<u8>(0)?);
mat.resize_with_default(100, Scalar::all(0.))?;
assert_ne!(mat.data(), bytes.as_ptr());
bytes[0] = 0xAA;
let row = mat.at_row::<u8>(0)?;
assert_eq!(0xFF, row[0]);
assert_eq!(0x50, row[1]);
assert_eq!(0x1A, row[6]);
assert_eq!(0x0D, row[11]);
assert_eq!(0x82, row[89]);
let row = mat.at_row::<u8>(1)?;
assert_eq!(0, row[1]);
assert_eq!(0, row[6]);
assert_eq!(0, row[89]);
}
Ok(())
}
#[test]
fn mat_from_matexpr() -> Result<()> {
{
let mat = Mat::zeros(3, 4, f32::typ())?.to_mat()?;
assert_eq!(4, mat.cols());
assert_eq!(3, mat.rows());
assert_eq!(0., *mat.at_2d::<f32>(0, 0)?);
assert_eq!(0., *mat.at_2d::<f32>(1, 1)?);
assert_eq!(0., *mat.at_2d::<f32>(2, 3)?);
}
{
let mat = Mat::ones_nd(&[6, 5], f32::typ())?.to_mat()?;
assert_eq!(5, mat.cols());
assert_eq!(6, mat.rows());
assert_eq!(1., *mat.at_2d::<f32>(0, 0)?);
assert_eq!(1., *mat.at_2d::<f32>(1, 1)?);
assert_eq!(1., *mat.at_2d::<f32>(5, 4)?);
}
Ok(())
}
#[test]
fn mat_iterator() -> Result<()> {
{
let mat = Mat::from_slice(&[1, 2, 3, 4])?;
let mut iter = MatConstIterator::over(&mat)?;
assert_eq!(iter.typ(), mat.typ());
assert_eq!(1, *iter.current::<i32>()?);
assert_eq!(Point::new(0, 0), iter.pos()?);
assert!(iter.has_elements());
iter.seek(1, true)?;
assert_eq!(2, *iter.current::<i32>()?);
assert_eq!(Point::new(1, 0), iter.pos()?);
assert!(iter.has_elements());
iter.seek(1, true)?;
assert_eq!(3, *iter.current::<i32>()?);
assert_eq!(Point::new(2, 0), iter.pos()?);
assert!(iter.has_elements());
iter.seek(1, true)?;
assert_eq!(4, *iter.current::<i32>()?);
assert_eq!(Point::new(3, 0), iter.pos()?);
assert!(iter.has_elements());
iter.seek(1, true)?;
assert_matches!(
iter.current::<i32>(),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_eq!(Point::new(0, 1), iter.pos()?);
assert!(!iter.has_elements());
iter.seek(1, true)?;
assert_matches!(
iter.current::<i32>(),
Err(Error {
code: core::StsOutOfRange,
..
})
);
assert_eq!(Point::new(0, 1), iter.pos()?);
assert!(!iter.has_elements());
}
{
let mat = Mat::from_slice_2d(&[[1, 2], [3, 4]])?;
for (pos, x) in mat.iter::<i32>()? {
match pos {
Point { x: 0, y: 0 } => assert_eq!(x, 1),
Point { x: 1, y: 0 } => assert_eq!(x, 2),
Point { x: 0, y: 1 } => assert_eq!(x, 3),
Point { x: 1, y: 1 } => assert_eq!(x, 4),
_ => panic!("Too many elements"),
}
}
}
Ok(())
}
#[test]
fn mat_locate_roi() -> Result<()> {
let mat = Mat::from_slice(&[1, 2, 3, 4])?;
let roi = Mat::roi(&mat, Rect::new(1, 0, 2, 1))?;
let mut sz = Size::default();
let mut ofs = Point::default();
roi.locate_roi(&mut sz, &mut ofs)?;
assert_eq!(sz, Size::new(4, 1));
assert_eq!(ofs, Point::new(1, 0));
Ok(())
}
#[test]
fn mat_convert() -> Result<()> {
let mat = Mat::from_slice(&[1, 2, 3, 4])?;
let mut mat_ = mat.try_clone()?.try_into_typed::<i32>()?;
assert_eq!(3, *mat_.at(2)?);
*mat_.at_mut(3)? = 8;
assert_eq!(8, *mat_.at(3)?);
assert_eq!(mat.typ(), mat_.typ());
assert_eq!(mat.size()?, mat_.size()?);
let mat_back = mat_.into_untyped();
assert_eq!(mat.size()?, mat_back.size()?);
Ok(())
}
#[test]
fn mat_mul() -> Result<()> {
{
let expr = Mat::ones(1, 5, f64::typ())?;
let res = core::mul_matexpr_f64(&expr, 4.)?.to_mat()?;
assert_eq!(res.typ(), f64::typ());
assert_eq!(res.data_typed::<f64>()?, &[4., 4., 4., 4., 4.]);
}
{
let expr = Mat::new_rows_cols_with_default(2, 3, i32::typ(), Scalar::from(9.))?;
let res = core::sub_mat_scalar(&expr, Scalar::from(5.))?.to_mat()?;
assert_eq!(res.typ(), i32::typ());
assert_eq!(res.data_typed::<i32>()?, &[4, 4, 4, 4, 4, 4]);
}
{
let mat1 = Mat::from_slice_2d(&[[1f32, 2., 3.], [4., 5., 6.]])?;
let mat2 = Mat::from_slice_2d(&[[7f32, 8.], [9., 10.], [11., 12.]])?;
let res = core::mul_mat_mat(&mat1, &mat2)?.to_mat()?;
assert_eq!(res.typ(), f32::typ());
assert_eq!(res.size()?, Size::new(2, 2));
assert_eq!(res.data_typed::<f32>()?, &[58., 64., 139., 154.]);
}
{
let mat = Mat::from_slice(&[1u8, 2, 3, 4, 5, 6])?;
let res = core::div_mat_f64(&mat, 2.)?.to_mat()?;
assert_eq!(res.typ(), u8::typ());
assert_eq!(res.data_typed::<u8>()?, &[0, 1, 2, 2, 2, 3]);
}
Ok(())
}
#[test]
fn mat_data() -> Result<()> {
{
let mat = Mat::from_slice(&[8, 13, 21, 39u8])?;
assert_eq!(&[8, 13, 21, 39], mat.data_bytes()?);
let roi = Mat::roi(&mat, Rect::new(1, 0, 2, 1))?;
assert_eq!(&[13, 21], roi.data_bytes()?);
}
{
let mat = Mat::from_slice_2d(&[[6, 7], [16, 17u8]])?;
assert_eq!(&[6, 7, 16, 17], mat.data_bytes()?);
let roi = Mat::roi(&mat, Rect::new(0, 0, 1, 2))?;
assert_matches!(
roi.data_bytes(),
Err(Error {
code: core::StsUnmatchedSizes,
..
})
);
}
{
let mut mat = Mat::from_slice(&[Vec2b::from([5, 8]), Vec2b::from([13, 21])])?;
assert_eq!(&[5, 8, 13, 21], mat.data_bytes()?);
let bytes = mat.data_bytes_mut()?;
bytes[1] = 90;
assert_eq!(&[5, 90, 13, 21], mat.data_bytes()?);
}
Ok(())
}
#[test]
fn mat_equals() -> Result<()> {
let mat1 = Mat::new_rows_cols_with_default(3, 3, i32::typ(), Scalar::all(0.))?;
let mat2 = Mat::new_rows_cols_with_default(3, 3, i32::typ(), Scalar::all(0.))?;
let mat3 = Mat::new_rows_cols_with_default(3, 3, i32::typ(), Scalar::all(1.))?;
let res = core::equals_mat_mat(&mat1, &mat2)?.to_mat()?;
assert!(res.data_typed::<u8>()?.iter().all(|&e| e != 0));
let res = core::equals_mat_mat(&mat1, &mat3)?.to_mat()?;
assert!(res.data_typed::<u8>()?.iter().all(|&e| e == 0));
Ok(())
}
#[test]
fn mat_rgb() -> Result<()> {
#![cfg(feature = "rgb")]
let m = Mat::new_rows_cols_with_default(3, 3, rgb::RGBA8::typ(), Scalar::all(1.))?;
assert_eq!(rgb::RGBA::new(1, 1, 1, 1), *m.at_2d(1, 1)?);
assert_matches!(
m.at_2d::<rgb::RGB8>(1, 1),
Err(Error {
code: core::StsUnmatchedFormats,
..
})
);
Ok(())
}
#[test]
fn mat_from_slice() -> Result<()> {
let src_u8 = [0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let src_point = [
Point2d::new(10.1, 20.2),
Point2d::new(30.3, 40.4),
Point2d::new(50.5, 60.6),
Point2d::new(70.7, 80.8),
];
{
let mat = Mat::from_slice(&src_u8)?;
assert_eq!(10, mat.total());
assert_eq!(5u8, *mat.at(5)?);
let mat = Mat::from_slice(&src_point)?;
assert_eq!(4, mat.total());
assert_eq!(Point2d::new(30.3, 40.4), *mat.at(1)?);
}
{
let mat = Mat::from_slice_rows_cols(&src_u8, 2, 5)?;
assert_eq!(10, mat.total());
assert_eq!(2, mat.rows());
assert_eq!(5, mat.cols());
assert_eq!(6u8, *mat.at_2d(1, 1)?);
let mat_res = Mat::from_slice_rows_cols(&src_u8, 3, 3);
assert_matches!(
mat_res,
Err(Error {
code: core::StsUnmatchedSizes,
..
})
);
let mat = Mat::from_slice_rows_cols(&src_point, 2, 2)?;
assert_eq!(4, mat.total());
assert_eq!(2, mat.rows());
assert_eq!(2, mat.cols());
assert_eq!(Point2d::new(50.5, 60.6), *mat.at_2d(1, 0)?);
}
Ok(())
}