Add Rust-friendly Mat iterator
MODIFY
src/manual/core/mat.rs
src/manual/core/mat.rs
@@ -2,6 +2,7 @@ use std::{
convert::TryInto,
ffi::c_void,
fmt,
+ marker::PhantomData,
ops::Deref,
slice,
};
@@ -9,7 +10,7 @@ use std::{
pub use mat_::*;
use crate::{
- core::{self, MatExpr, MatSize, MatStep, Point, Scalar, UMat},
+ core::{self, MatConstIterator, MatExpr, MatSize, MatStep, Point, Scalar, UMat},
Error,
input_output_array,
platform_types::size_t,
@@ -141,6 +142,36 @@ impl Mat {
pub fn try_into_typed<T: DataType>(self) -> Result<Mat_<T>> where Self: Sized {
self.try_into()
}
+
+ /// Returns iterator over Mat elements and their positions
+ #[inline]
+ pub fn iter<T: DataType>(&self) -> Result<MatIter<T>> {
+ match_format::<T>(self.typ())?;
+ Ok(MatIter {
+ iter: MatConstIterator::over(self)?,
+ _d: PhantomData,
+ })
+ }
+}
+
+pub struct MatIter<'m, T> {
+ iter: MatConstIterator,
+ _d: PhantomData<&'m T>,
+}
+
+impl<T: DataType> Iterator for MatIter<'_, T> {
+ type Item = (Point, T);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ if self.iter.has_elements() {
+ let cur = self.iter.current().ok()?;
+ let out = (self.iter.pos().ok()?, *cur);
+ self.iter.seek(1, true).ok()?;
+ Some(out)
+ } else {
+ None
+ }
+ }
}
pub(crate) mod mat_forward {

MODIFY
tests/mat.rs
tests/mat.rs
@@ -493,6 +493,7 @@ fn mat_from_matexpr() -> Result<()> {
#[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());
@@ -519,6 +520,23 @@ fn mat_iterator() -> Result<()> {
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(())
}

Add Rust-friendly Mat iterator