Add basic Matx type
MODIFY
binding-generator/src/settings.rs
binding-generator/src/settings.rs
@@ -444,6 +444,9 @@ pub static FUNC_RENAME: Lazy<HashMap<&str, &str>> = Lazy::new(|| {
"cv_Stitcher_stitch_const__InputArrayX_const__InputArrayX_const__OutputArrayX" => "+_mask",
"cv_Stitcher_stitch_const__InputArrayX_const_vector_vector_Rect__X_const__OutputArrayX" => "+_rois", // 3.2 3.4
+ // ### surface_matching ###
+ "cv_ppf_match_3d_ICP_registerModelToScene_const_MatX_const_MatX_vector_Pose3DPtr_X" => "+_vec",
+
// ### videoio ###
"cv_VideoCapture_VideoCapture_String_int" => "from_file_with_backend", // 3.2
"cv_VideoCapture_VideoCapture_const_StringX" => "from_file_default", // 3.2
@@ -720,6 +723,7 @@ pub static DATA_TYPES: Lazy<BTreeSet<&str>> = Lazy::new(|| btreeset! {
pub static IMPLEMENTED_GENERICS: Lazy<HashSet<&str>> = Lazy::new(|| hashset! {
"cv::Mat_",
+ "cv::Matx",
"cv::Point3_",
"cv::Point_",
"cv::Rect_",

MODIFY
src/manual/core.rs
src/manual/core.rs
pub use CV_MAKETYPE as CV_MAKE_TYPE;
-pub use self::input_output_array::*;
-pub use self::mat::*;
-pub use self::point::*;
-pub use self::point3::*;
-pub use self::rect::*;
-pub use self::size::*;
-pub use self::vec::*;
+pub use input_output_array::*;
+pub use mat::*;
+pub use matx::*;
+pub use point::*;
+pub use point3::*;
+pub use rect::*;
+pub use size::*;
+pub use vec::*;
macro_rules! valid_types {
($trait: ident, $($rust_type: ty),+) => {
@@ -26,8 +27,9 @@ macro_rules! valid_types {
mod input_output_array;
mod mat;
-mod point;
+mod matx;
mod point3;
+mod point;
mod rect;
mod size;
mod vec;

ADD
src/manual/core/matx.rs
+use num::{One, Zero};
+
+use crate::{core, Error, Result};
+
+valid_types!(ValidMatxType, f32, f64);
+
+macro_rules! matx_impl {
+ ($type: ident, $rows: expr, $cols: expr, $type_trait: ident) => {
+ /// [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],
+ }
+
+ impl<T: $type_trait> From<[T; $rows * $cols]> for $type<T> {
+ fn from(s: [T; $rows * $cols]) -> Self {
+ Self { val: s }
+ }
+ }
+
+ impl<T: $type_trait> $type<T> {
+ #![allow(non_upper_case_globals)]
+ pub const rows: usize = $rows;
+ pub const cols: usize = $cols;
+ pub const channels: usize = $rows * $cols;
+ }
+
+ impl<T: $type_trait> $crate::core::MatxTrait for $type<T> {
+ 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() -> usize { Self::rows }
+ #[inline(always)] fn cols() -> usize { Self::cols }
+ #[inline(always)] fn channels() -> usize { Self::channels }
+
+ fn all(alpha: T) -> Self {
+ Self::from([alpha; $rows * $cols])
+ }
+ }
+
+ impl<T: $type_trait> std::default::Default for $type<T> {
+ fn default() -> Self {
+ Self::from([T::default(); $rows * $cols])
+ }
+ }
+
+ impl<T: $type_trait> std::ops::Index<(usize, usize)> for $type<T> {
+ type Output = T;
+
+ fn index(&self, index: (usize, usize)) -> &Self::Output {
+ self.get(index).expect("Index out of range")
+ }
+ }
+
+ impl<T: $type_trait> std::ops::IndexMut<(usize, usize)> for $type<T> {
+ fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
+ self.get_mut(index).expect("Index out of range")
+ }
+ }
+ };
+}
+
+matx_impl!(Matx12, 1, 2, ValidMatxType);
+matx_impl!(Matx13, 1, 3, ValidMatxType);
+matx_impl!(Matx14, 1, 4, ValidMatxType);
+matx_impl!(Matx16, 1, 6, ValidMatxType);
+
+matx_impl!(Matx21, 2, 1, ValidMatxType);
+matx_impl!(Matx31, 3, 1, ValidMatxType);
+matx_impl!(Matx41, 4, 1, ValidMatxType);
+matx_impl!(Matx61, 6, 1, ValidMatxType);
+
+matx_impl!(Matx22, 2, 2, ValidMatxType);
+matx_impl!(Matx23, 2, 3, ValidMatxType);
+matx_impl!(Matx32, 3, 2, ValidMatxType);
+
+matx_impl!(Matx33, 3, 3, ValidMatxType);
+
+matx_impl!(Matx34, 3, 4, ValidMatxType);
+matx_impl!(Matx43, 4, 3, ValidMatxType);
+
+matx_impl!(Matx44, 4, 4, ValidMatxType);
+matx_impl!(Matx66, 6, 6, ValidMatxType);
+
+#[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: Default {
+ type ElemType: ValidMatxType;
+
+ fn rows() -> usize;
+ fn cols() -> 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() -> usize {
+ Self::rows() * Self::cols()
+ }
+
+ #[inline(always)]
+ fn shortdim() -> usize {
+ Self::rows().min(Self::cols())
+ }
+
+ fn zeros() -> Self where Self: Sized, Self::ElemType: Zero {
+ Self::all(Zero::zero())
+ }
+
+ fn ones() -> Self where Self: Sized, Self::ElemType: One {
+ Self::all(One::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, Self::ElemType: One {
+ let mut out = Self::default();
+ (0..Self::shortdim()).for_each(|i| {
+ unsafe { out.get_unchecked_mut((i, i)) }.set_one();
+ });
+ out
+ }
+}
+

MODIFY
src/manual/core/vec.rs
src/manual/core/vec.rs
-use std::{
- ops::{Deref, DerefMut},
- os::raw::c_void,
-};
+use std::ffi::c_void;
use crate::{
core::{_InputArray, ToInputArray},
@@ -24,12 +21,12 @@ macro_rules! vec_impl {
($type: ident, $count: expr, $type_trait: ident) => {
/// [docs.opencv.org](https://docs.opencv.org/master/d6/dcf/classcv_1_1Vec.html)
#[repr(C)]
- #[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
+ #[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
pub struct $type<T: $type_trait>(pub [T; $count]);
impl<T: $type_trait> From<[T; $count]> for $type<T> {
- fn from(s: [T; $count]) -> $type<T> {
- $type::<T>(s)
+ fn from(s: [T; $count]) -> Self {
+ Self(s)
}
}
@@ -39,7 +36,7 @@ macro_rules! vec_impl {
}
}
- impl<T: $type_trait> Deref for $type<T> {
+ impl<T: $type_trait> std::ops::Deref for $type<T> {
type Target = [T; $count];
fn deref(&self) -> &Self::Target {
@@ -47,17 +44,11 @@ macro_rules! vec_impl {
}
}
- impl<T: $type_trait> DerefMut for $type<T> {
+ impl<T: $type_trait> std::ops::DerefMut for $type<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
-
- impl<T: $type_trait + Default> Default for $type<T> {
- fn default() -> Self {
- Self([Default::default(); $count])
- }
- }
};
}

MODIFY
src/manual/mod.rs
src/manual/mod.rs
@@ -6,7 +6,7 @@ pub mod sys;
pub mod types;
pub mod prelude {
- pub use super::core::{MatConstIteratorTraitManual, MatTraitManual, UMatTraitManual};
+ pub use super::core::{MatConstIteratorTraitManual, MatTraitManual, MatxTrait, UMatTraitManual};
#[cfg(feature = "opencv-32")]
pub use super::core::MatSizeTraitManual;
}

ADD
tests/matx.rs
+use opencv::{
+ core::Matx33d,
+ prelude::*,
+};
+
+#[test]
+fn matx() {
+ let mut a = Matx33d::eye();
+ assert_eq!(a[(0, 0)], 1.);
+ assert_eq!(a[(1, 0)], 0.);
+ assert_eq!(*a.get((0, 1)).unwrap(), 0.);
+ assert_eq!(*a.get_mut((1, 1)).unwrap(), 1.);
+}

Add basic Matx type