Make Matx generic
MODIFY
src/manual/core.rs
src/manual/core.rs
@@ -8,6 +8,7 @@ pub use point::*;
pub use point3::*;
pub use rect::*;
pub use size::*;
+pub use sized::*;
pub use vec::*;
macro_rules! valid_types {
@@ -34,6 +35,7 @@ mod point3;
mod point;
mod rect;
mod size;
+mod sized;
mod vec;
#[inline(always)]

MODIFY
src/manual/core/matx.rs
src/manual/core/matx.rs
+use std::{
+ ffi::c_void,
+ fmt,
+};
+
use num::{One, Zero};
-use crate::{core, Error, Result};
+use crate::{
+ core::{self, ToInputArray, ToInputOutputArray, ToOutputArray},
+ Error,
+ manual::core::sized::*,
+ Result,
+ sys::Result as SysResult,
+};
+
+fn index_check(idx: (usize, usize), rows: usize, cols: usize) -> Result<()> {
+ if idx.0 >= rows {
+ Err(Error::new(core::StsOutOfRange, format!("Index: {} along dimension: rows out of bounds 0..{}", idx.0, rows)))
+ } else if idx.1 >= cols {
+ Err(Error::new(core::StsOutOfRange, format!("Index: {} along dimension: cols out of bounds 0..{}", idx.1, cols)))
+ } else {
+ Ok(())
+ }
+}
valid_types!(ValidMatxType, f32, f64);
-macro_rules! matx_impl {
- ($type: ident, $rows: expr, $cols: expr, $type_trait: ident) => {
+pub trait MatxTrait: Sized {
+ type ElemType: ValidMatxType;
+
+ fn rows(&self) -> usize;
+ fn cols(&self) -> usize;
+ fn val(&self) -> &[Self::ElemType];
+ fn val_mut(&mut self) -> &mut [Self::ElemType];
+
+ fn all(alpha: Self::ElemType) -> Self;
+
+ fn channels(&self) -> usize {
+ self.rows() * self.cols()
+ }
+
+ fn shortdim(&self) -> usize {
+ self.rows().min(self.cols())
+ }
+
+ fn zeros() -> Self {
+ Self::all(Self::ElemType::zero())
+ }
+
+ fn ones() -> Self {
+ Self::all(Self::ElemType::one())
+ }
+
+ fn get(&self, idx: (usize, usize)) -> Option<&Self::ElemType> {
+ index_check(idx, self.rows(), self.cols())
+ .ok()
+ .map(|_| unsafe { self.get_unchecked(idx) })
+ }
+
+ unsafe fn get_unchecked(&self, idx: (usize, usize)) -> &Self::ElemType {
+ self.val().get_unchecked(idx.0 * self.cols() + idx.1)
+ }
+
+ fn get_mut(&mut self, idx: (usize, usize)) -> Option<&mut Self::ElemType> {
+ index_check(idx, self.rows(), self.cols())
+ .ok()?;
+ Some(unsafe { self.get_unchecked_mut(idx) })
+ }
+
+ unsafe fn get_unchecked_mut(&mut self, idx: (usize, usize)) -> &mut Self::ElemType {
+ let cols = self.cols();
+ self.val_mut().get_unchecked_mut(idx.0 * cols + idx.1)
+ }
+
+ fn eye() -> Self {
+ let mut out = Self::zeros();
+ (0..out.shortdim()).for_each(|i| {
+ unsafe { out.get_unchecked_mut((i, i)) }.set_one();
+ });
+ out
+ }
+}
+
/// [docs.opencv.org](https://docs.opencv.org/master/de/de1/classcv_1_1Matx.html)
#[repr(C)]
#[derive(Copy, Clone)]
- pub struct $type<T: $type_trait> {
- pub val: [T; $rows * $cols],
+pub struct Matx<T: ValidMatxType, A: SizedArray<T>> {
+ pub val: A::Storage,
}
- impl<T: $type_trait> $type<T> {
- pub const ROWS: usize = $rows;
- pub const COLS: usize = $cols;
- pub const CHANNELS: usize = $rows * $cols;
+impl<T: ValidMatxType, A: SizedArray<T>> Matx<T, A> {
+ pub fn from(s: A::Storage) -> Self {
+ Self { val: s }
+ }
}
- impl<T: $type_trait> $crate::core::MatxTrait for $type<T> {
+impl<T: ValidMatxType, A: SizedArray<T>> MatxTrait for Matx<T, A> {
type ElemType = T;
- #[inline(always)] fn val(&self) -> &[Self::ElemType] { &self.val }
- #[inline(always)] fn val_mut(&mut self) -> &mut [Self::ElemType] { &mut self.val }
- #[inline(always)] fn rows(&self) -> usize { Self::ROWS }
- #[inline(always)] fn cols(&self) -> usize { Self::COLS }
- #[inline(always)] fn channels(&self) -> usize { Self::CHANNELS }
+ fn rows(&self) -> usize {
+ A::ROWS
+ }
- fn all(alpha: Self::ElemType) -> Self {
- Self::from([alpha; $rows * $cols])
+ fn cols(&self) -> usize {
+ A::COLS
}
+
+ fn val(&self) -> &[Self::ElemType] {
+ self.val.as_ref()
}
- impl<T: $type_trait> From<[T; $rows * $cols]> for $type<T> {
- fn from(s: [T; $rows * $cols]) -> Self {
- Self { val: s }
+ fn val_mut(&mut self) -> &mut [Self::ElemType] {
+ self.val.as_mut()
+ }
+
+ fn all(alpha: Self::ElemType) -> Self where Self: Sized {
+ Self { val: A::all(alpha) }
+ }
+
+ fn channels(&self) -> usize {
+ A::ROWS * A::COLS
}
}
- impl<T: $type_trait> std::default::Default for $type<T> {
+impl<T: ValidMatxType, A: SizedArray<T>> Default for Matx<T, A> {
fn default() -> Self {
Self::all(T::default())
}
}
- impl<T: $type_trait> std::ops::Index<(usize, usize)> for $type<T> {
+impl<T: ValidMatxType, A: SizedArray<T>> std::ops::Index<(usize, usize)> for Matx<T, A> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
@@ -53,21 +136,21 @@ macro_rules! matx_impl {
}
}
- impl<T: $type_trait> std::ops::IndexMut<(usize, usize)> for $type<T> {
+impl<T: ValidMatxType, A: SizedArray<T>> std::ops::IndexMut<(usize, usize)> for Matx<T, A> {
fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
self.get_mut(index).expect("Index out of range")
}
}
- impl<T: $type_trait> std::cmp::PartialEq for $type<T> {
- fn eq(&self, other: &$type<T>) -> bool {
- &self.val[..] == &other.val[..]
+impl<T: ValidMatxType, A: SizedArray<T>> std::cmp::PartialEq for Matx<T, A> {
+ fn eq(&self, other: &Matx<T, A>) -> bool {
+ &self.val() == &other.val()
}
}
- impl<T: $type_trait> std::fmt::Debug for $type<T> {
- fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
- f.debug_struct(stringify!($type))
+impl<T: ValidMatxType, A: SizedArray<T>> fmt::Debug for Matx<T, A> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.debug_struct("Matx")
.field("rows", &self.rows())
.field("cols", &self.cols())
.field("channels", &self.channels())
@@ -75,180 +158,127 @@ macro_rules! matx_impl {
.finish()
}
}
- };
-}
-macro_rules! matx_input_output_array_impl {
- ($type: ty, $extern_input: ident, $extern_output: ident, $extern_input_output: ident) => {
- impl $crate::core::ToInputArray for $type {
- fn input_array(&self) -> $crate::Result<$crate::core::_InputArray> {
- extern "C" { fn $extern_input(instance: *const $type) -> $crate::sys::Result<*mut std::ffi::c_void>; }
- unsafe { $extern_input(self) }
+impl<T: ValidMatxType, A: SizedArray<T>> ToInputArray for Matx<T, A> where Self: MatxExtern<T, A> {
+ fn input_array(&self) -> Result<core::_InputArray> {
+ unsafe { self.extern_input_array() }
.into_result()
- .map(|ptr| $crate::core::_InputArray { ptr })
+ .map(|ptr| core::_InputArray { ptr })
}
}
- impl $crate::core::ToInputArray for &$type {
- #[inline]
- fn input_array(&self) -> $crate::Result<$crate::core::_InputArray> {
+impl<T: ValidMatxType, A: SizedArray<T>> ToInputArray for &Matx<T, A> where Matx<T, A>: MatxExtern<T, A> {
+ fn input_array(&self) -> Result<core::_InputArray> {
(*self).input_array()
}
}
- impl $crate::core::ToOutputArray for $type {
- fn output_array(&mut self) -> $crate::Result<$crate::core::_OutputArray> {
- extern "C" { fn $extern_output(instance: *mut $type) -> $crate::sys::Result<*mut std::ffi::c_void>; }
- unsafe { $extern_output(self) }
+impl<T: ValidMatxType, A: SizedArray<T>> ToOutputArray for Matx<T, A> where Self: MatxExtern<T, A> {
+ fn output_array(&mut self) -> Result<core::_OutputArray> {
+ unsafe { self.extern_output_array() }
.into_result()
- .map(|ptr| $crate::core::_OutputArray { ptr })
+ .map(|ptr| core::_OutputArray { ptr })
}
}
- impl $crate::core::ToOutputArray for &mut $type {
- #[inline]
- fn output_array(&mut self) -> $crate::Result<$crate::core::_OutputArray> {
+impl<T: ValidMatxType, A: SizedArray<T>> ToOutputArray for &mut Matx<T, A> where Matx<T, A>: MatxExtern<T, A> {
+ fn output_array(&mut self) -> Result<core::_OutputArray> {
(*self).output_array()
}
}
- impl $crate::core::ToInputOutputArray for $type {
- fn input_output_array(&mut self) -> $crate::Result<$crate::core::_InputOutputArray> {
- extern "C" { fn $extern_input_output(instance: *mut $type) -> $crate::sys::Result<*mut std::ffi::c_void>; }
- unsafe { $extern_input_output(self) }
+impl<T: ValidMatxType, A: SizedArray<T>> ToInputOutputArray for Matx<T, A> where Self: MatxExtern<T, A> {
+ fn input_output_array(&mut self) -> Result<core::_InputOutputArray> {
+ unsafe { self.extern_input_output_array() }
.into_result()
- .map(|ptr| $crate::core::_InputOutputArray { ptr })
+ .map(|ptr| core::_InputOutputArray { ptr })
}
}
- impl $crate::core::ToInputOutputArray for &mut $type {
- #[inline]
- fn input_output_array(&mut self) -> $crate::Result<$crate::core::_InputOutputArray> {
+impl<T: ValidMatxType, A: SizedArray<T>> ToInputOutputArray for &mut Matx<T, A> where Matx<T, A>: MatxExtern<T, A> {
+ fn input_output_array(&mut self) -> Result<core::_InputOutputArray> {
(*self).input_output_array()
}
}
- }
-}
-
-matx_impl!(Matx12, 1, 2, ValidMatxType);
-matx_input_output_array_impl!(Matx12<f32>, cv_Matx12f_input_array, cv_Matx12f_output_array, cv_Matx12f_input_output_array);
-matx_input_output_array_impl!(Matx12<f64>, cv_Matx12d_input_array, cv_Matx12d_output_array, cv_Matx12d_input_output_array);
-matx_impl!(Matx13, 1, 3, ValidMatxType);
-matx_input_output_array_impl!(Matx13<f32>, cv_Matx13f_input_array, cv_Matx13f_output_array, cv_Matx13f_input_output_array);
-matx_input_output_array_impl!(Matx13<f64>, cv_Matx13d_input_array, cv_Matx13d_output_array, cv_Matx13d_input_output_array);
-matx_impl!(Matx14, 1, 4, ValidMatxType);
-matx_input_output_array_impl!(Matx14<f32>, cv_Matx14f_input_array, cv_Matx14f_output_array, cv_Matx14f_input_output_array);
-matx_input_output_array_impl!(Matx14<f64>, cv_Matx14d_input_array, cv_Matx14d_output_array, cv_Matx14d_input_output_array);
-matx_impl!(Matx16, 1, 6, ValidMatxType);
-matx_input_output_array_impl!(Matx16<f32>, cv_Matx16f_input_array, cv_Matx16f_output_array, cv_Matx16f_input_output_array);
-matx_input_output_array_impl!(Matx16<f64>, cv_Matx16d_input_array, cv_Matx16d_output_array, cv_Matx16d_input_output_array);
-
-matx_impl!(Matx21, 2, 1, ValidMatxType);
-matx_input_output_array_impl!(Matx21<f32>, cv_Matx21f_input_array, cv_Matx21f_output_array, cv_Matx21f_input_output_array);
-matx_input_output_array_impl!(Matx21<f64>, cv_Matx21d_input_array, cv_Matx21d_output_array, cv_Matx21d_input_output_array);
-matx_impl!(Matx31, 3, 1, ValidMatxType);
-matx_input_output_array_impl!(Matx31<f32>, cv_Matx31f_input_array, cv_Matx31f_output_array, cv_Matx31f_input_output_array);
-matx_input_output_array_impl!(Matx31<f64>, cv_Matx31d_input_array, cv_Matx31d_output_array, cv_Matx31d_input_output_array);
-matx_impl!(Matx41, 4, 1, ValidMatxType);
-matx_input_output_array_impl!(Matx41<f32>, cv_Matx41f_input_array, cv_Matx41f_output_array, cv_Matx41f_input_output_array);
-matx_input_output_array_impl!(Matx41<f64>, cv_Matx41d_input_array, cv_Matx41d_output_array, cv_Matx41d_input_output_array);
-matx_impl!(Matx61, 6, 1, ValidMatxType);
-matx_input_output_array_impl!(Matx61<f32>, cv_Matx61f_input_array, cv_Matx61f_output_array, cv_Matx61f_input_output_array);
-matx_input_output_array_impl!(Matx61<f64>, cv_Matx61d_input_array, cv_Matx61d_output_array, cv_Matx61d_input_output_array);
-
-matx_impl!(Matx22, 2, 2, ValidMatxType);
-matx_input_output_array_impl!(Matx22<f32>, cv_Matx22f_input_array, cv_Matx22f_output_array, cv_Matx22f_input_output_array);
-matx_input_output_array_impl!(Matx22<f64>, cv_Matx22d_input_array, cv_Matx22d_output_array, cv_Matx22d_input_output_array);
-matx_impl!(Matx23, 2, 3, ValidMatxType);
-matx_input_output_array_impl!(Matx23<f32>, cv_Matx23f_input_array, cv_Matx23f_output_array, cv_Matx23f_input_output_array);
-matx_input_output_array_impl!(Matx23<f64>, cv_Matx23d_input_array, cv_Matx23d_output_array, cv_Matx23d_input_output_array);
-matx_impl!(Matx32, 3, 2, ValidMatxType);
-matx_input_output_array_impl!(Matx32<f32>, cv_Matx32f_input_array, cv_Matx32f_output_array, cv_Matx32f_input_output_array);
-matx_input_output_array_impl!(Matx32<f64>, cv_Matx32d_input_array, cv_Matx32d_output_array, cv_Matx32d_input_output_array);
-
-matx_impl!(Matx33, 3, 3, ValidMatxType);
-matx_input_output_array_impl!(Matx33<f32>, cv_Matx33f_input_array, cv_Matx33f_output_array, cv_Matx33f_input_output_array);
-matx_input_output_array_impl!(Matx33<f64>, cv_Matx33d_input_array, cv_Matx33d_output_array, cv_Matx33d_input_output_array);
-
-matx_impl!(Matx34, 3, 4, ValidMatxType);
-matx_input_output_array_impl!(Matx34<f32>, cv_Matx34f_input_array, cv_Matx34f_output_array, cv_Matx34f_input_output_array);
-matx_input_output_array_impl!(Matx34<f64>, cv_Matx34d_input_array, cv_Matx34d_output_array, cv_Matx34d_input_output_array);
-matx_impl!(Matx43, 4, 3, ValidMatxType);
-matx_input_output_array_impl!(Matx43<f32>, cv_Matx43f_input_array, cv_Matx43f_output_array, cv_Matx43f_input_output_array);
-matx_input_output_array_impl!(Matx43<f64>, cv_Matx43d_input_array, cv_Matx43d_output_array, cv_Matx43d_input_output_array);
-
-matx_impl!(Matx44, 4, 4, ValidMatxType);
-matx_input_output_array_impl!(Matx44<f32>, cv_Matx44f_input_array, cv_Matx44f_output_array, cv_Matx44f_input_output_array);
-matx_input_output_array_impl!(Matx44<f64>, cv_Matx44d_input_array, cv_Matx44d_output_array, cv_Matx44d_input_output_array);
-matx_impl!(Matx66, 6, 6, ValidMatxType);
-matx_input_output_array_impl!(Matx66<f32>, cv_Matx66f_input_array, cv_Matx66f_output_array, cv_Matx66f_input_output_array);
-matx_input_output_array_impl!(Matx66<f64>, cv_Matx66d_input_array, cv_Matx66d_output_array, cv_Matx66d_input_output_array);
-
-#[inline(always)]
-fn index_check(idx: (usize, usize), rows: usize, cols: usize) -> Result<()> {
- if idx.0 >= rows {
- Err(Error::new(core::StsOutOfRange, format!("Index: {} along dimension: rows out of bounds 0..{}", idx.0, rows)))
- } else if idx.1 >= cols {
- Err(Error::new(core::StsOutOfRange, format!("Index: {} along dimension: cols out of bounds 0..{}", idx.1, cols)))
- } else {
- Ok(())
- }
-}
-
-pub trait MatxTrait {
- type ElemType: ValidMatxType;
-
- fn rows(&self) -> usize;
- fn cols(&self) -> usize;
- fn val(&self) -> &[Self::ElemType];
- fn val_mut(&mut self) -> &mut [Self::ElemType];
-
- fn all(alpha: Self::ElemType) -> Self where Self: Sized;
-
- #[inline(always)]
- fn channels(&self) -> usize {
- self.rows() * self.cols()
- }
-
- #[inline(always)]
- fn shortdim(&self) -> usize {
- self.rows().min(self.cols())
- }
- fn zeros() -> Self where Self: Sized {
- Self::all(Self::ElemType::zero())
- }
-
- fn ones() -> Self where Self: Sized {
- Self::all(Self::ElemType::one())
- }
-
- fn get(&self, idx: (usize, usize)) -> Option<&Self::ElemType> {
- index_check(idx, self.rows(), self.cols())
- .ok()
- .map(|_| unsafe { self.get_unchecked(idx) })
- }
-
- unsafe fn get_unchecked(&self, idx: (usize, usize)) -> &Self::ElemType {
- self.val().get_unchecked(idx.0 * self.cols() + idx.1)
- }
-
- fn get_mut(&mut self, idx: (usize, usize)) -> Option<&mut Self::ElemType> {
- index_check(idx, self.rows(), self.cols())
- .ok()?;
- Some(unsafe { self.get_unchecked_mut(idx) })
- }
-
- unsafe fn get_unchecked_mut(&mut self, idx: (usize, usize)) -> &mut Self::ElemType {
- let cols = self.cols();
- self.val_mut().get_unchecked_mut(idx.0 * cols + idx.1)
- }
-
- fn eye() -> Self where Self: Sized {
- let mut out = Self::zeros();
- (0..out.shortdim()).for_each(|i| {
- unsafe { out.get_unchecked_mut((i, i)) }.set_one();
- });
- out
- }
-}
+#[doc(hidden)]
+pub trait MatxExtern<T: ValidMatxType, A: SizedArray<T>> {
+ unsafe fn extern_input_array(&self) -> SysResult<*mut c_void>;
+ unsafe fn extern_output_array(&mut self) -> SysResult<*mut c_void>;
+ unsafe fn extern_input_output_array(&mut self) -> SysResult<*mut c_void>;
+}
+
+macro_rules! matx_extern {
+ ($type: ty, $array: ty, $extern_input_array: ident, $extern_ouput_array: ident, $extern_input_array_output: ident) => {
+ impl $crate::manual::core::MatxExtern<$type, $array> for $crate::manual::core::Matx<$type, $array> {
+ unsafe fn extern_input_array(&self) -> $crate::sys::Result<*mut c_void> {
+ extern "C" { fn $extern_input_array(instance: *const $crate::manual::core::Matx<$type, $array>) -> $crate::sys::Result<*mut c_void>; }
+ $extern_input_array(self)
+ }
+
+ unsafe fn extern_output_array(&mut self) -> $crate::sys::Result<*mut c_void> {
+ extern "C" { fn $extern_ouput_array(instance: *mut $crate::manual::core::Matx<$type, $array>) -> $crate::sys::Result<*mut c_void>; }
+ $extern_ouput_array(self)
+ }
+
+ unsafe fn extern_input_output_array(&mut self) -> $crate::sys::Result<*mut c_void> {
+ extern "C" { fn $extern_input_array_output(instance: *mut $crate::manual::core::Matx<$type, $array>) -> $crate::sys::Result<*mut c_void>; }
+ $extern_input_array_output(self)
+ }
+ }
+ }
+}
+
+pub type Matx12<T> = Matx<T, SizedArray12>;
+matx_extern!(f32, SizedArray12, cv_Matx12f_input_array, cv_Matx12f_output_array, cv_Matx12f_input_output_array);
+matx_extern!(f64, SizedArray12, cv_Matx12d_input_array, cv_Matx12d_output_array, cv_Matx12d_input_output_array);
+pub type Matx13<T> = Matx<T, SizedArray13>;
+matx_extern!(f32, SizedArray13, cv_Matx13f_input_array, cv_Matx13f_output_array, cv_Matx13f_input_output_array);
+matx_extern!(f64, SizedArray13, cv_Matx13d_input_array, cv_Matx13d_output_array, cv_Matx13d_input_output_array);
+pub type Matx14<T> = Matx<T, SizedArray14>;
+matx_extern!(f32, SizedArray14, cv_Matx14f_input_array, cv_Matx14f_output_array, cv_Matx14f_input_output_array);
+matx_extern!(f64, SizedArray14, cv_Matx14d_input_array, cv_Matx14d_output_array, cv_Matx14d_input_output_array);
+pub type Matx16<T> = Matx<T, SizedArray16>;
+matx_extern!(f32, SizedArray16, cv_Matx16f_input_array, cv_Matx16f_output_array, cv_Matx16f_input_output_array);
+matx_extern!(f64, SizedArray16, cv_Matx16d_input_array, cv_Matx16d_output_array, cv_Matx16d_input_output_array);
+
+pub type Matx21<T> = Matx<T, SizedArray21>;
+matx_extern!(f32, SizedArray21, cv_Matx21f_input_array, cv_Matx21f_output_array, cv_Matx21f_input_output_array);
+matx_extern!(f64, SizedArray21, cv_Matx21d_input_array, cv_Matx21d_output_array, cv_Matx21d_input_output_array);
+pub type Matx31<T> = Matx<T, SizedArray31>;
+matx_extern!(f32, SizedArray31, cv_Matx31f_input_array, cv_Matx31f_output_array, cv_Matx31f_input_output_array);
+matx_extern!(f64, SizedArray31, cv_Matx31d_input_array, cv_Matx31d_output_array, cv_Matx31d_input_output_array);
+pub type Matx41<T> = Matx<T, SizedArray41>;
+matx_extern!(f32, SizedArray41, cv_Matx41f_input_array, cv_Matx41f_output_array, cv_Matx41f_input_output_array);
+matx_extern!(f64, SizedArray41, cv_Matx41d_input_array, cv_Matx41d_output_array, cv_Matx41d_input_output_array);
+pub type Matx61<T> = Matx<T, SizedArray61>;
+matx_extern!(f32, SizedArray61, cv_Matx61f_input_array, cv_Matx61f_output_array, cv_Matx61f_input_output_array);
+matx_extern!(f64, SizedArray61, cv_Matx61d_input_array, cv_Matx61d_output_array, cv_Matx61d_input_output_array);
+
+pub type Matx22<T> = Matx<T, SizedArray22>;
+matx_extern!(f32, SizedArray22, cv_Matx22f_input_array, cv_Matx22f_output_array, cv_Matx22f_input_output_array);
+matx_extern!(f64, SizedArray22, cv_Matx22d_input_array, cv_Matx22d_output_array, cv_Matx22d_input_output_array);
+pub type Matx23<T> = Matx<T, SizedArray23>;
+matx_extern!(f32, SizedArray23, cv_Matx23f_input_array, cv_Matx23f_output_array, cv_Matx23f_input_output_array);
+matx_extern!(f64, SizedArray23, cv_Matx23d_input_array, cv_Matx23d_output_array, cv_Matx23d_input_output_array);
+pub type Matx32<T> = Matx<T, SizedArray32>;
+matx_extern!(f32, SizedArray32, cv_Matx32f_input_array, cv_Matx32f_output_array, cv_Matx32f_input_output_array);
+matx_extern!(f64, SizedArray32, cv_Matx32d_input_array, cv_Matx32d_output_array, cv_Matx32d_input_output_array);
+
+pub type Matx33<T> = Matx<T, SizedArray33>;
+matx_extern!(f32, SizedArray33, cv_Matx33f_input_array, cv_Matx33f_output_array, cv_Matx33f_input_output_array);
+matx_extern!(f64, SizedArray33, cv_Matx33d_input_array, cv_Matx33d_output_array, cv_Matx33d_input_output_array);
+
+pub type Matx34<T> = Matx<T, SizedArray34>;
+matx_extern!(f32, SizedArray34, cv_Matx34f_input_array, cv_Matx34f_output_array, cv_Matx34f_input_output_array);
+matx_extern!(f64, SizedArray34, cv_Matx34d_input_array, cv_Matx34d_output_array, cv_Matx34d_input_output_array);
+pub type Matx43<T> = Matx<T, SizedArray43>;
+matx_extern!(f32, SizedArray43, cv_Matx43f_input_array, cv_Matx43f_output_array, cv_Matx43f_input_output_array);
+matx_extern!(f64, SizedArray43, cv_Matx43d_input_array, cv_Matx43d_output_array, cv_Matx43d_input_output_array);
+
+pub type Matx44<T> = Matx<T, SizedArray44>;
+matx_extern!(f32, SizedArray44, cv_Matx44f_input_array, cv_Matx44f_output_array, cv_Matx44f_input_output_array);
+matx_extern!(f64, SizedArray44, cv_Matx44d_input_array, cv_Matx44d_output_array, cv_Matx44d_input_output_array);
+pub type Matx66<T> = Matx<T, SizedArray66>;
+matx_extern!(f32, SizedArray66, cv_Matx66f_input_array, cv_Matx66f_output_array, cv_Matx66f_input_output_array);
+matx_extern!(f64, SizedArray66, cv_Matx66d_input_array, cv_Matx66d_output_array, cv_Matx66d_input_output_array);

ADD
src/manual/core/sized.rs
+use std::ops::{Deref, DerefMut};
+
+pub trait SizedArray<T> {
+ type Storage: AsRef<[T]> + AsMut<[T]>;
+
+ const ROWS: usize;
+ const COLS: usize;
+ fn all(alpha: T) -> Self::Storage;
+}
+
+macro_rules! sized_array_impl {
+ ($type: ident, $rows: expr, $cols: expr) => {
+ #[derive(Copy, Clone)]
+ pub struct $type;
+
+ impl<T: Copy> $crate::core::SizedArray<T> for $type {
+ type Storage = [T; $rows * $cols];
+
+ const ROWS: usize = $rows;
+ const COLS: usize = $cols;
+
+ fn all(alpha: T) -> Self::Storage {
+ [alpha; $rows * $cols]
+ }
+ }
+ };
+}
+
+sized_array_impl!(SizedArray12, 1, 2);
+sized_array_impl!(SizedArray13, 1, 3);
+sized_array_impl!(SizedArray14, 1, 4);
+sized_array_impl!(SizedArray16, 1, 6);
+
+sized_array_impl!(SizedArray21, 2, 1);
+sized_array_impl!(SizedArray31, 3, 1);
+sized_array_impl!(SizedArray41, 4, 1);
+sized_array_impl!(SizedArray61, 6, 1);
+
+sized_array_impl!(SizedArray22, 2, 2);
+sized_array_impl!(SizedArray23, 2, 3);
+sized_array_impl!(SizedArray32, 3, 2);
+
+sized_array_impl!(SizedArray33, 3, 3);
+
+sized_array_impl!(SizedArray34, 3, 4);
+sized_array_impl!(SizedArray43, 4, 3);
+
+sized_array_impl!(SizedArray44, 4, 4);
+
+// fixme workaround for missing standard derives in stdlib for arrays with len > 32
+#[derive(Clone, Copy)]
+#[repr(C)]
+pub struct Array66<T>([T; 6 * 6]);
+
+impl<T> AsRef<[T]> for Array66<T> {
+ fn as_ref(&self) -> &[T] {
+ self.0.as_ref()
+ }
+}
+
+impl<T> AsMut<[T]> for Array66<T> {
+ fn as_mut(&mut self) -> &mut [T] {
+ self.0.as_mut()
+ }
+}
+
+impl<T> Deref for Array66<T> {
+ type Target = [T];
+
+ fn deref(&self) -> &Self::Target {
+ self.as_ref()
+ }
+}
+
+impl<T> DerefMut for Array66<T> {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ self.as_mut()
+ }
+}
+
+#[derive(Copy, Clone)]
+pub struct SizedArray66;
+
+impl<T: Copy> SizedArray<T> for SizedArray66 {
+ type Storage = Array66<T>;
+
+ const ROWS: usize = 6;
+ const COLS: usize = 6;
+
+ fn all(alpha: T) -> Self::Storage {
+ Array66([alpha; 6 * 6])
+ }
+}

MODIFY
tests/matx.rs
tests/matx.rs
use matches::assert_matches;
use opencv::{
- core::{self, Matx23f, Matx32f, Matx33d, Matx44d, Point2f, Scalar},
+ core::{self, Matx22d, Matx23f, Matx32f, Matx33d, Matx44d, Matx66f, Point2f, Scalar},
imgproc,
prelude::*,
Result,
@@ -19,6 +19,24 @@ fn matx_get() {
assert_matches!(a.get((3, 3)), None);
}
+#[test]
+fn matx_set() {
+ let mut a = Matx33d::eye();
+ *a.get_mut((0, 1)).unwrap() = 2.;
+ a[(1, 2)] = 3.;
+ assert_eq!(a[(0, 1)], 2.);
+ assert_eq!(a[(1, 2)], 3.);
+ assert_eq!(a[(0, 0)], 1.);
+ assert_eq!(a[(1, 0)], 0.);
+ let mut a = Matx66f::eye();
+ *a.get_mut((0, 1)).unwrap() = 2.;
+ a[(1, 2)] = 3.;
+ assert_eq!(a[(0, 1)], 2.);
+ assert_eq!(a[(1, 2)], 3.);
+ assert_eq!(a[(0, 0)], 1.);
+ assert_eq!(a[(1, 0)], 0.);
+}
+
#[cfg(all(feature = "opencv-4", not(target_env = "msvc")))]
#[test]
fn matx_return() -> Result<()> {
@@ -65,3 +83,21 @@ fn matx_input_output_array() -> Result<()> {
assert_eq!(expected, mat);
Ok(())
}
+
+#[test]
+fn matx_default() -> Result<()> {
+ let mat = Matx22d::default();
+ assert_eq!(mat[(1, 1)], f64::default());
+ let mat = Matx66f::default();
+ assert_eq!(mat[(1, 1)], f32::default());
+ Ok(())
+}
+
+#[test]
+fn matx_all() -> Result<()> {
+ let mat = Matx22d::all(9.);
+ assert_eq!(mat[(0, 1)], 9.);
+ let mat = Matx66f::all(81.);
+ assert_eq!(mat[(3, 4)], 81.);
+ Ok(())
+}

Make Matx generic