scirs2_ndimage/morphology/
utils.rs1use scirs2_core::ndarray::{Array, Dimension};
4use scirs2_core::numeric::{Float, FromPrimitive};
5use std::fmt::Debug;
6
7use super::MorphBorderMode;
8use crate::error::{NdimageError, NdimageResult};
9
10#[allow(dead_code)]
23pub fn pad_array<T, D>(
24 input: &Array<T, D>,
25 pad_width: &[(usize, usize)],
26 _mode: &MorphBorderMode,
27 value: T,
28) -> NdimageResult<Array<T, D>>
29where
30 T: Float + FromPrimitive + Debug + Clone + std::ops::AddAssign + std::ops::DivAssign + 'static,
31 D: Dimension + 'static,
32{
33 if input.ndim() == 0 {
35 return Err(NdimageError::InvalidInput(
36 "Input array cannot be 0-dimensional".into(),
37 ));
38 }
39
40 if pad_width.len() != input.ndim() {
41 return Err(NdimageError::DimensionError(format!(
42 "Pad _width must have same length as input dimensions (got {} expected {})",
43 pad_width.len(),
44 input.ndim()
45 )));
46 }
47
48 if pad_width.iter().all(|&(a, b)| a == 0 && b == 0) {
50 return Ok(input.to_owned());
51 }
52
53 Ok(input.to_owned())
56}
57
58#[allow(dead_code)]
68pub fn validate_structure<D>(structure: &Array<bool, D>) -> NdimageResult<()>
69where
70 D: Dimension,
71{
72 if structure.ndim() == 0 {
74 return Err(NdimageError::InvalidInput(
75 "Structure cannot be 0-dimensional".into(),
76 ));
77 }
78
79 if !structure.iter().any(|&x| x) {
81 return Err(NdimageError::InvalidInput(
82 "Structure must have at least one True value".into(),
83 ));
84 }
85
86 Ok(())
91}
92
93#[allow(dead_code)]
104pub fn get_structure_center<D>(
105 structure: &Array<bool, D>,
106 origin: Option<&[isize]>,
107) -> NdimageResult<Vec<isize>>
108where
109 D: Dimension,
110{
111 if structure.ndim() == 0 {
113 return Err(NdimageError::InvalidInput(
114 "Structure cannot be 0-dimensional".into(),
115 ));
116 }
117
118 if let Some(orig) = origin {
120 if orig.len() != structure.ndim() {
121 return Err(NdimageError::DimensionError(format!(
122 "Origin must have same length as structure dimensions (got {} expected {})",
123 orig.len(),
124 structure.ndim()
125 )));
126 }
127
128 for (i, &o) in orig.iter().enumerate() {
130 let dim = structure.shape()[i] as isize;
131 if o < -(dim / 2) || o > dim / 2 {
132 return Err(NdimageError::InvalidInput(format!(
133 "Origin {} is out of bounds for dimension {} of size {}",
134 o, i, dim
135 )));
136 }
137 }
138
139 return Ok(orig.to_vec());
140 }
141
142 let mut center = Vec::with_capacity(structure.ndim());
144 for &dim in structure.shape() {
145 center.push((dim as isize) / 2);
146 }
147
148 Ok(center)
149}
150
151pub(crate) fn get_structure_center_dyn(
162 structure: &Array<bool, scirs2_core::ndarray::IxDyn>,
163 origin: Option<&[isize]>,
164) -> NdimageResult<Vec<isize>> {
165 get_structure_center(structure, origin)
166}
167
168#[cfg(test)]
169mod tests {
170 use super::*;
171 use scirs2_core::ndarray::Array2;
172
173 #[test]
174 fn test_validate_structure() {
175 let structure = Array2::from_elem((3, 3), true);
176 let result = validate_structure(&structure);
177 assert!(result.is_ok());
178
179 let empty_structure = Array2::from_elem((3, 3), false);
180 let result = validate_structure(&empty_structure);
181 assert!(result.is_err());
182 }
183
184 #[test]
185 fn test_get_structure_center() {
186 let structure = Array2::from_elem((3, 3), true);
187 let center = get_structure_center(&structure, None).expect("Operation failed");
188 assert_eq!(center, vec![1, 1]);
189
190 let structure = Array2::from_elem((5, 5), true);
191 let center = get_structure_center(&structure, None).expect("Operation failed");
192 assert_eq!(center, vec![2, 2]);
193 }
194}