From 5e6a6c62bf96e67227248fa7357d3cfa8e9e714d Mon Sep 17 00:00:00 2001 From: Mark Hoekveen Date: Mon, 17 Jun 2024 21:54:13 +0200 Subject: [PATCH] stat calculation updates --- src/bin/mutate.rs | 2 +- src/main.rs | 26 +++++++++++++++++++------- src/mutators/mod.rs | 2 +- src/store.rs | 29 +++++++++++++++++++---------- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/src/bin/mutate.rs b/src/bin/mutate.rs index 650e47a..350c971 100644 --- a/src/bin/mutate.rs +++ b/src/bin/mutate.rs @@ -28,7 +28,7 @@ fn main() { }; for mutator in mutators { let mutated = mutator.mutate(&img); - let filename = "mut".to_string() + &mutator.tag() + &"jpg".to_string(); + let filename = "mut".to_string() + &mutator.tag() + &"png".to_string(); println!("Saving to {}", filename); mutated.save(filename).expect("Saving image failed"); if cfg.show_images { diff --git a/src/main.rs b/src/main.rs index 67cfef0..f14a840 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,10 +76,10 @@ fn main() { } // Create PR-curve graphs from stores + let max_threshold = 8; for store in &stores { - println!("Store for {}: ", store.descriptor.info()); - //store.print_stats(); - let stats = store.get_stats(16); + println!("Stats for {}", store.descriptor.info()); + let stats = store.get_stats(max_threshold); let filename = format!("{}-pr.png", store.descriptor.info()); let root = BitMapBackend::new(&filename, (1024, 768)).into_drawing_area(); root.fill(&WHITE).unwrap(); @@ -104,17 +104,29 @@ fn main() { let mut i = 0; for mutator_stats in stats { // And we can draw something in the drawing area - let pr_curve = mutator_stats.pr_curve(); + let pr_curve = mutator_stats.pr_curve(max_threshold); + println!("{}:", mutator_stats.name); + for (x, y) in pr_curve.clone() { + println!("{}, {}", x, y); + } let color = colors[i % n]; chart.draw_series(LineSeries::new( pr_curve, - color, - )).unwrap() + color.filled(), + ).point_size(2)).unwrap() .label(mutator_stats.name) .legend(move |(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], color)); i += 1; } - chart.configure_series_labels().border_style(BLACK).draw().unwrap(); + //chart.configure_series_labels().border_style(BLACK).draw().unwrap(); + chart.configure_series_labels() + .position(SeriesLabelPosition::MiddleLeft) + //.legend_area_size(5) + .border_style(BLACK) + //.background_style(BLUE.mix(0.1)) + //.label_font(("Calibri", 20)) + .draw() + .unwrap(); //println!("{}", store); } } diff --git a/src/mutators/mod.rs b/src/mutators/mod.rs index 0aebd3c..d51ba37 100644 --- a/src/mutators/mod.rs +++ b/src/mutators/mod.rs @@ -53,7 +53,7 @@ impl Mutator for Sharp { ".sharp.".to_string() } fn mutate(&self, img: &image::DynamicImage) -> image::DynamicImage { - img.unsharpen(1.2, 50) + img.unsharpen(1.5, 20) } } diff --git a/src/store.rs b/src/store.rs index 8cfd2dc..87a1197 100644 --- a/src/store.rs +++ b/src/store.rs @@ -59,9 +59,9 @@ impl PRStats { let r = tpos / (tpos + fneg); (r, p) } - pub fn pr_curve(&self) -> Vec<(f64, f64)> { + pub fn pr_curve(&self, threshold: usize) -> Vec<(f64, f64)> { let mut curve = Vec::new(); - for i in 0..64 { + for i in 0..threshold { curve.push(self.pr(i)); } curve @@ -340,6 +340,7 @@ impl DescriptorStore { ); } + // Seen should only contain a list of base images let set = self.seen.clone().unwrap(); for image in set.iter() { let phash = self.get(image).unwrap(); @@ -349,25 +350,33 @@ impl DescriptorStore { //Assume miss, therefore a false negative //Undo the miss when there is a true positive for mutator in &mut mutator_stats { - mutator.false_negatives[threshold as usize] += 1; + mutator.false_negatives[threshold] += 1; } for found in self.nn_flat_results(phash, threshold) { - if found.eq(image) || found.ends_with(&format!(".{}", image)) { // True positive + if found.ends_with(&format!(".{}", image)) { // True positive for mutator in &mut mutator_stats { if found.starts_with(&mutator.tag) { debug!("{} is hit for {}", found, mutator.name); - mutator.true_positives[threshold as usize] += 1; - mutator.false_negatives[threshold as usize] -= 1; + mutator.true_positives[threshold] += 1; + mutator.false_negatives[threshold] -= 1; } } + } else if found.eq(image) { + continue; } else { // False positive! // Mutated misses only count for the mutator // Unmutated misses count for everyone - for mutator in &mut mutator_stats { - if found.starts_with(&mutator.tag) || !found.starts_with("mut") { - debug!("{} is false positive for {}", found, mutator.name); - mutator.false_positives[threshold as usize] += 1; + if found.starts_with("mut") { + for mutator in &mut mutator_stats { + if found.starts_with(&mutator.tag) { + debug!("{} is false positive for {}", found, mutator.name); + mutator.false_positives[threshold] += 1; + } + } + } else { + for mutator in &mut mutator_stats { + mutator.false_positives[threshold] += 1; } } }