scirs2_ndimage/documentation/
modules.rs1use crate::documentation::types::{DocumentationSite, FunctionDoc, ModuleDoc, Parameter, Result};
7
8impl DocumentationSite {
9 pub fn build_module_documentation(&mut self) -> Result<()> {
11 self.modules = vec![
12 build_filters_documentation(),
13 build_morphology_documentation(),
14 build_interpolation_documentation(),
15 build_measurements_documentation(),
16 ];
17 Ok(())
18 }
19}
20
21pub fn build_filters_documentation() -> ModuleDoc {
23 let mut module = ModuleDoc::new(
24 "Filters",
25 "Image filtering operations including Gaussian, median, rank, and edge detection filters",
26 );
27
28 let mut gaussian_filter = FunctionDoc::new(
30 "gaussian_filter",
31 "pub fn gaussian_filter<T>(input: &ArrayD<T>, sigma: f64) -> ArrayD<T>",
32 "Apply Gaussian filter to n-dimensional array",
33 "ArrayD<T> - Filtered array",
34 );
35
36 gaussian_filter.add_parameter(Parameter::required(
37 "_input",
38 "&ArrayD<T>",
39 "Input n-dimensional array",
40 ));
41 gaussian_filter.add_parameter(Parameter::required(
42 "sigma",
43 "f64",
44 "Standard deviation for Gaussian kernel",
45 ));
46
47 gaussian_filter.add_example(
48 r#"use scirs2_ndimage::filters::gaussian_filter;
49use scirs2_core::ndarray::Array2;
50
51let image = Array2::from_elem((100, 100), 1.0f64);
52let filtered = gaussian_filter(&image, 2.0);
53assert_eq!(filtered.shape(), image.shape());"#,
54 );
55
56 gaussian_filter.add_note("Uses separable convolution for efficiency");
57 gaussian_filter.add_note("Supports all numeric types");
58
59 module.add_function(gaussian_filter);
60
61 let mut median_filter = FunctionDoc::new(
63 "median_filter",
64 "pub fn median_filter<T>(input: &ArrayD<T>, size: usize) -> ArrayD<T>",
65 "Apply median filter to remove noise while preserving edges",
66 "ArrayD<T> - Filtered array",
67 );
68
69 median_filter.add_parameter(Parameter::required(
70 "_input",
71 "&ArrayD<T>",
72 "Input n-dimensional array",
73 ));
74 median_filter.add_parameter(Parameter::required(
75 "size",
76 "usize",
77 "Size of the median filter window",
78 ));
79
80 median_filter.add_example(
81 r#"use scirs2_ndimage::filters::median_filter;
82use scirs2_core::ndarray::Array2;
83
84let noisyimage = Array2::from_elem((50, 50), 128.0f64);
85let filtered = median_filter(&noisyimage, 3);
86// Median filter removes salt-and-pepper noise"#,
87 );
88
89 median_filter.add_note("Excellent for removing salt-and-pepper noise");
90 median_filter.add_note("Preserves edges better than linear filters");
91
92 module.add_function(median_filter);
93
94 module.add_example("Basic filtering operations");
96 module.add_example("Edge detection pipeline");
97 module.add_example("Noise reduction techniques");
98
99 module
100}
101
102pub fn build_morphology_documentation() -> ModuleDoc {
104 let mut module = ModuleDoc::new(
105 "Morphology",
106 "Mathematical morphology operations for binary and grayscale images",
107 );
108
109 let mut binary_erosion = FunctionDoc::new(
111 "binary_erosion",
112 "pub fn binary_erosion(input: &ArrayD<bool>, structure: &ArrayD<bool>) -> ArrayD<bool>",
113 "Perform binary erosion operation",
114 "ArrayD<bool> - Eroded binary array",
115 );
116
117 binary_erosion.add_parameter(Parameter::required(
118 "_input",
119 "&ArrayD<bool>",
120 "Input binary array",
121 ));
122 binary_erosion.add_parameter(Parameter::required(
123 "structure",
124 "&ArrayD<bool>",
125 "Structuring element",
126 ));
127
128 binary_erosion.add_example(
129 r#"use scirs2_ndimage::morphology::binary_erosion;
130use scirs2_core::ndarray::Array2;
131
132let binary_image = Array2::from_elem((10, 10), true);
133let structure = Array2::from_elem((3, 3), true);
134let eroded = binary_erosion(&binary_image, &structure);"#,
135 );
136
137 binary_erosion.add_note("Shrinks white regions in binary images");
138 binary_erosion.add_note("Useful for separating connected objects");
139
140 module.add_function(binary_erosion);
141
142 let mut distance_transform = FunctionDoc::new(
144 "distance_transform_edt",
145 "pub fn distance_transform_edt(input: &ArrayD<bool>) -> ArrayD<f64>",
146 "Compute Euclidean distance transform using optimized algorithm",
147 "ArrayD<f64> - Distance transform",
148 );
149
150 distance_transform.add_parameter(Parameter::required(
151 "_input",
152 "&ArrayD<bool>",
153 "Input binary array",
154 ));
155
156 distance_transform.add_example(
157 r#"use scirs2_ndimage::morphology::distance_transform_edt;
158use scirs2_core::ndarray::Array2;
159
160let binary_image = Array2::from_elem((100, 100), false);
161let distances = distance_transform_edt(&binary_image);
162// Each pixel contains distance to nearest background pixel"#,
163 );
164
165 distance_transform
166 .add_note("Uses Felzenszwalb & Huttenlocher separable algorithm for O(n) performance");
167 distance_transform.add_note("Supports arbitrary dimensions");
168
169 module.add_function(distance_transform);
170
171 module.add_example("Object size analysis");
173 module.add_example("Shape decomposition");
174 module.add_example("Skeletonization");
175
176 module
177}
178
179pub fn build_interpolation_documentation() -> ModuleDoc {
181 let mut module = ModuleDoc::new(
182 "Interpolation",
183 "Geometric transformations and interpolation operations",
184 );
185
186 let mut affine_transform = FunctionDoc::new(
188 "affine_transform",
189 "pub fn affine_transform<T>(input: &ArrayD<T>, matrix: &Array2<f64>) -> ArrayD<T>",
190 "Apply affine transformation to n-dimensional array",
191 "ArrayD<T> - Transformed array",
192 );
193
194 affine_transform.add_parameter(Parameter::required(
195 "_input",
196 "&ArrayD<T>",
197 "Input array to transform",
198 ));
199 affine_transform.add_parameter(Parameter::required(
200 "matrix",
201 "&Array2<f64>",
202 "Affine transformation matrix",
203 ));
204
205 affine_transform.add_example(
206 r#"use scirs2_ndimage::interpolation::affine_transform;
207use scirs2_core::ndarray::{Array2, array};
208
209let image = Array2::from_elem((50, 50), 1.0f64);
210let rotation_matrix = array![[0.866, -0.5], [0.5, 0.866]]; // 30 degree rotation
211let rotated = affine_transform(&image, &rotation_matrix);"#,
212 );
213
214 affine_transform.add_note("Supports rotation, scaling, shearing, and translation");
215 affine_transform.add_note("Uses spline interpolation for high quality results");
216
217 module.add_function(affine_transform);
218
219 module.add_example("Image registration");
221 module.add_example("Geometric correction");
222 module.add_example("Multi-resolution analysis");
223
224 module
225}
226
227pub fn build_measurements_documentation() -> ModuleDoc {
229 let mut module = ModuleDoc::new(
230 "Measurements",
231 "Statistical measurements and region analysis",
232 );
233
234 let mut center_of_mass = FunctionDoc::new(
236 "center_of_mass",
237 "pub fn center_of_mass<T>(input: &ArrayD<T>) -> Vec<f64>",
238 "Calculate center of mass of n-dimensional array",
239 "Vec<f64> - Center of mass coordinates",
240 );
241
242 center_of_mass.add_parameter(Parameter::required("_input", "&ArrayD<T>", "Input array"));
243
244 center_of_mass.add_example(
245 r#"use scirs2_ndimage::measurements::center_of_mass;
246use scirs2_core::ndarray::Array2;
247
248let image = Array2::from_elem((100, 100), 1.0f64);
249let com = center_of_mass(&image);
250println!("Center of mass: {:?}", com);"#,
251 );
252
253 center_of_mass.add_note("Works with any numeric type");
254 center_of_mass.add_note("Returns coordinates in array index order");
255
256 module.add_function(center_of_mass);
257
258 module.add_example("Object property analysis");
260 module.add_example("Region statistics");
261 module.add_example("Feature extraction");
262
263 module
264}
265
266pub fn add_common_filter_functions(module: &mut ModuleDoc) {
268 let mut sobel_filter = FunctionDoc::new(
270 "sobel_filter",
271 "pub fn sobel_filter<T>(input: &ArrayD<T>) -> ArrayD<T>",
272 "Apply Sobel edge detection filter",
273 "ArrayD<T> - Edge-detected array",
274 );
275
276 sobel_filter.add_parameter(Parameter::required(
277 "_input",
278 "&ArrayD<T>",
279 "Input n-dimensional array",
280 ));
281
282 sobel_filter.add_example(
283 r#"use scirs2_ndimage::filters::sobel_filter;
284use scirs2_core::ndarray::Array2;
285
286let image = Array2::from_elem((100, 100), 1.0f64);
287let edges = sobel_filter(&image);"#,
288 );
289
290 sobel_filter.add_note("Detects edges using Sobel operators");
291 sobel_filter.add_note("Returns magnitude of gradient");
292
293 module.add_function(sobel_filter);
294
295 let mut laplacian_filter = FunctionDoc::new(
297 "laplacian_filter",
298 "pub fn laplacian_filter<T>(input: &ArrayD<T>) -> ArrayD<T>",
299 "Apply Laplacian edge detection filter",
300 "ArrayD<T> - Edge-detected array",
301 );
302
303 laplacian_filter.add_parameter(Parameter::required(
304 "_input",
305 "&ArrayD<T>",
306 "Input n-dimensional array",
307 ));
308
309 laplacian_filter.add_example(
310 r#"use scirs2_ndimage::filters::laplacian_filter;
311use scirs2_core::ndarray::Array2;
312
313let image = Array2::from_elem((100, 100), 1.0f64);
314let edges = laplacian_filter(&image);"#,
315 );
316
317 laplacian_filter.add_note("Uses second derivative for edge detection");
318 laplacian_filter.add_note("More sensitive to noise than Sobel");
319
320 module.add_function(laplacian_filter);
321}
322
323pub fn add_common_morphology_functions(module: &mut ModuleDoc) {
325 let mut binary_dilation = FunctionDoc::new(
327 "binary_dilation",
328 "pub fn binary_dilation(input: &ArrayD<bool>, structure: &ArrayD<bool>) -> ArrayD<bool>",
329 "Perform binary dilation operation",
330 "ArrayD<bool> - Dilated binary array",
331 );
332
333 binary_dilation.add_parameter(Parameter::required(
334 "_input",
335 "&ArrayD<bool>",
336 "Input binary array",
337 ));
338 binary_dilation.add_parameter(Parameter::required(
339 "structure",
340 "&ArrayD<bool>",
341 "Structuring element",
342 ));
343
344 binary_dilation.add_example(
345 r#"use scirs2_ndimage::morphology::binary_dilation;
346use scirs2_core::ndarray::Array2;
347
348let binary_image = Array2::from_elem((10, 10), true);
349let structure = Array2::from_elem((3, 3), true);
350let dilated = binary_dilation(&binary_image, &structure);"#,
351 );
352
353 binary_dilation.add_note("Expands white regions in binary images");
354 binary_dilation.add_note("Useful for connecting nearby objects");
355
356 module.add_function(binary_dilation);
357}
358
359#[cfg(test)]
360mod tests {
361 use super::*;
362
363 #[test]
364 fn test_filters_documentation() {
365 let filters_doc = build_filters_documentation();
366 assert_eq!(filters_doc.name, "Filters");
367 assert!(!filters_doc.functions.is_empty());
368 assert!(!filters_doc.examples.is_empty());
369
370 let gaussian = filters_doc
372 .functions
373 .iter()
374 .find(|f| f.name == "gaussian_filter");
375 assert!(gaussian.is_some());
376
377 let gaussian = gaussian.expect("Operation failed");
378 assert_eq!(gaussian.parameters.len(), 2);
379 assert!(!gaussian.examples.is_empty());
380 assert!(!gaussian.notes.is_empty());
381 }
382
383 #[test]
384 fn test_morphology_documentation() {
385 let morphology_doc = build_morphology_documentation();
386 assert_eq!(morphology_doc.name, "Morphology");
387 assert!(!morphology_doc.functions.is_empty());
388
389 let erosion = morphology_doc
391 .functions
392 .iter()
393 .find(|f| f.name == "binary_erosion");
394 assert!(erosion.is_some());
395
396 let erosion = erosion.expect("Operation failed");
397 assert_eq!(erosion.parameters.len(), 2);
398 }
399
400 #[test]
401 fn test_interpolation_documentation() {
402 let interpolation_doc = build_interpolation_documentation();
403 assert_eq!(interpolation_doc.name, "Interpolation");
404 assert!(!interpolation_doc.functions.is_empty());
405
406 let affine = interpolation_doc
408 .functions
409 .iter()
410 .find(|f| f.name == "affine_transform");
411 assert!(affine.is_some());
412 }
413
414 #[test]
415 fn test_measurements_documentation() {
416 let measurements_doc = build_measurements_documentation();
417 assert_eq!(measurements_doc.name, "Measurements");
418 assert!(!measurements_doc.functions.is_empty());
419
420 let com = measurements_doc
422 .functions
423 .iter()
424 .find(|f| f.name == "center_of_mass");
425 assert!(com.is_some());
426 }
427
428 #[test]
429 fn test_module_documentation_builder() {
430 let mut site = DocumentationSite::new();
431 let result = site.build_module_documentation();
432
433 assert!(result.is_ok());
434 assert_eq!(site.modules.len(), 4);
435
436 let module_names: Vec<_> = site.modules.iter().map(|m| &m.name).collect();
438 assert!(module_names.contains(&&"Filters".to_string()));
439 assert!(module_names.contains(&&"Morphology".to_string()));
440 assert!(module_names.contains(&&"Interpolation".to_string()));
441 assert!(module_names.contains(&&"Measurements".to_string()));
442 }
443}