agent_image_diff/
denoise.rs1use crate::cluster;
2
3pub fn denoise(mask: &mut Vec<bool>, width: u32, height: u32, min_size: u32) {
9 if min_size <= 1 {
10 return;
11 }
12
13 let labels = cluster::label_components(mask, width, height, 8);
15
16 let max_label = labels.iter().copied().max().unwrap_or(0) as usize;
18 let mut counts = vec![0u32; max_label + 1];
19 for &label in &labels {
20 if label > 0 {
21 counts[label as usize] += 1;
22 }
23 }
24
25 for (i, &label) in labels.iter().enumerate() {
27 if label > 0 && counts[label as usize] < min_size {
28 mask[i] = false;
29 }
30 }
31}
32
33#[cfg(test)]
34mod tests {
35 use super::*;
36
37 #[test]
38 fn removes_small_clusters() {
39 #[rustfmt::skip]
41 let mut mask = vec![
42 true, true, false, false, false,
43 true, true, false, false, false,
44 false, false, false, false, false,
45 false, false, false, false, true,
46 false, false, false, false, false,
47 ];
48 denoise(&mut mask, 5, 5, 3);
49 assert!(mask[0]); assert!(!mask[19]); }
53
54 #[test]
55 fn noop_when_disabled() {
56 let mut mask = vec![true, false, true, false];
57 let original = mask.clone();
58 denoise(&mut mask, 2, 2, 1);
59 assert_eq!(mask, original);
60 }
61}