From d2728e0414e1f99e412b87d7675970bfff2791b2 Mon Sep 17 00:00:00 2001 From: Henry Schimke Date: Fri, 27 Jan 2023 15:12:49 -0600 Subject: [PATCH] bring in updates from maxicode detection --- src/common/bit_matrix.rs | 21 ++ src/maxicode/detector.rs | 220 +++++++++--------- .../blackbox/maxicode-1/MODE2-rotate-90.png | Bin 0 -> 8561 bytes .../blackbox/maxicode-1/MODE2-rotate-90.txt | 1 + tests/common/abstract_black_box_test_case.rs | 5 +- tests/maxicode_blackbox_tests.rs | 4 +- 6 files changed, 144 insertions(+), 107 deletions(-) create mode 100644 test_resources/blackbox/maxicode-1/MODE2-rotate-90.png create mode 100644 test_resources/blackbox/maxicode-1/MODE2-rotate-90.txt diff --git a/src/common/bit_matrix.rs b/src/common/bit_matrix.rs index bb190b3..9bfdfb2 100644 --- a/src/common/bit_matrix.rs +++ b/src/common/bit_matrix.rs @@ -226,6 +226,27 @@ impl BitMatrix { Some(((self.bits[offset] >> (x & 0x1f)) & 1) != 0) } + pub fn try_get_area(&self, x: u32, y: u32, box_size: u32) -> Option { + let mut matrix = Vec::with_capacity((box_size * box_size) as usize); + let start_x = x - box_size / 2; + let end_x = x + box_size / 2; + let start_y = y - box_size / 2; + let end_y = y+ box_size / 2; + + for get_x in start_x..=end_x { + for get_y in start_y..=end_y { + matrix.push(self.try_get(get_x, get_y)?); + } + } + + let total_set = matrix.iter().filter(|bit| **bit ).count(); + if (total_set as f32 / matrix.len() as f32) >=0.5 { + Some(true) + }else { + Some(false) + } + } + /// Confusingly returns true if the requested element is out of bounds pub fn check_in_bounds(&self, x: u32, y: u32) -> bool { (self.get_offset(y, x)) > self.bits.len() diff --git a/src/maxicode/detector.rs b/src/maxicode/detector.rs index 1362ea4..2b18599 100644 --- a/src/maxicode/detector.rs +++ b/src/maxicode/detector.rs @@ -2,7 +2,9 @@ use num::integer::Roots; use crate::{ - common::{BitMatrix, DefaultGridSampler, DetectorRXingResult, GridSampler}, + common::{ + detector::MathUtils, BitMatrix, DefaultGridSampler, DetectorRXingResult, GridSampler, + }, Exceptions, RXingResultPoint, }; @@ -338,13 +340,16 @@ pub fn detect(image: &BitMatrix, try_harder: bool) -> Result bool { let max_variance_even = estimated_module_size_even / 2.0; let max_variance_odd = estimated_module_size_odd / 2.0; - // let total_width = buckets.iter().sum::() as f32; - // let estimated_module_size = total_width / (buckets.len() -1 ) as f32; - - // let max_variance = estimated_module_size / 2.5; - let b1 = (estimated_module_size_even - buckets[0] as f32).abs(); let b2 = (estimated_module_size_odd - buckets[1] as f32).abs(); let b3 = (estimated_module_size_even - buckets[2] as f32).abs(); @@ -685,18 +685,18 @@ fn validate_bullseye_widths(buckets: &[u32; 11]) -> bool { /// returns the (center , radius) of the possible bullseye fn get_bullseye_metadata(buckets: &[u32; 11], column: u32) -> (u32, u32, [u32; 11]) { - let radius = ((buckets.iter().sum::() as f32) / 2.0).round() as u32; //buckets.iter().skip(6).sum::() + buckets[5] / 2; - let center = column - radius; //buckets.iter().take(5).sum::() - (buckets[5] / 2); + let radius = ((buckets.iter().sum::() as f32) / 2.0).round() as u32; + let center = column - radius; (center, radius, *buckets) } -const LEFT_SHIFT_PERCENT_ADJUST: f32 = 0.0; +const LEFT_SHIFT_PERCENT_ADJUST: f32 = 0.03; const RIGHT_SHIFT_PERCENT_ADJUST: f32 = 0.03; const ACCEPTED_SCALES: [f64; 5] = [0.065, 0.069, 0.07, 0.075, 0.08]; fn box_symbol(image: &BitMatrix, circle: &mut Circle) -> Result<[(f32, f32); 4], Exceptions> { let (left_boundary, right_boundary, top_boundary, bottom_boundary) = - calculate_simple_boundary(circle, Some(image), None); + calculate_simple_boundary(circle, Some(image), None, false); let naive_box = [ RXingResultPoint::new(left_boundary as f32, bottom_boundary as f32), @@ -717,7 +717,6 @@ fn box_symbol(image: &BitMatrix, circle: &mut Circle) -> Result<[(f32, f32); 4], return Err(Exceptions::NotFoundException(None)); } - #[cfg(feature = "experimental_features")] for scale in ACCEPTED_SCALES { if let Some(found_rotation) = attempt_rotation_box(image, circle, &naive_box, scale) { result_box = found_rotation; @@ -737,11 +736,12 @@ fn calculate_simple_boundary( circle: &Circle, image: Option<&BitMatrix>, center_scale: Option, + tight: bool, ) -> (u32, u32, u32, u32) { - let (symbol_width, symbol_height) = if image.is_some() { + let (symbol_width, symbol_height) = if !tight { guess_barcode_size(circle) } else if let Some(s) = center_scale { - guess_barcode_size_general(circle, 0.03, s, 0.97) + guess_barcode_size_general(circle, 0.05, s, 0.95) } else { guess_barcode_size_tighter(circle) }; @@ -763,12 +763,11 @@ fn calculate_simple_boundary( (circle.center.0 as i32 - left_shift).clamp(0, image_width as i32 - 33) as u32; let right_boundary = (circle.center.0 as i32 + right_shift).clamp(33, image_width as i32) as u32; - //symbol_width.clamp(30, image.getWidth()); let top_boundary = (circle.center.1 as i32 + up_down_shift).clamp(33, image_height as i32) as u32; - //symbol_height.clamp(33, image.getHeight()); let bottom_boundary = (circle.center.1 as i32 - up_down_shift).clamp(0, image_height as i32 - 30) as u32; + (left_boundary, right_boundary, top_boundary, bottom_boundary) } @@ -788,7 +787,9 @@ fn attempt_rotation_box( naive_box: &[RXingResultPoint; 4], center_scale: f64, ) -> Option<[RXingResultPoint; 4]> { + // update our circle with a more accurate center point circle.calculate_high_accuracy_center(); + // we know that the locator symbols should appear at 60 degree increments around the circle // top left @@ -816,96 +817,98 @@ fn attempt_rotation_box( let mut found = false; let mut final_rotation = 0.0; - for int_rotation in 0..355 { - let rotation = int_rotation as f32; - // look for top left - // * * - // * - let p1_rot = get_point(circle.center, topl_p1, rotation); - let p2_rot = get_point(circle.center, topl_p2, rotation); - let p3_rot = get_point(circle.center, topl_p3, rotation); - let found_tl = image.try_get(p1_rot.0 as u32, p1_rot.1 as u32)? - && image.try_get(p2_rot.0 as u32, p2_rot.1 as u32)? - && image.try_get(p3_rot.0 as u32, p3_rot.1 as u32)?; - if !found_tl { - continue; - } + for int_rotation in 0..175 { + let rotation = (int_rotation * 2) as f32; + // look for top left + // * * + // * + let p1_rot = get_point(circle.center, topl_p1, rotation); + let p2_rot = get_point(circle.center, topl_p2, rotation); + let p3_rot = get_point(circle.center, topl_p3, rotation); + let found_tl = image.try_get_area(p1_rot.0 as u32, p1_rot.1 as u32,3)? + && image.try_get_area(p2_rot.0 as u32, p2_rot.1 as u32,3)? + && image.try_get_area(p3_rot.0 as u32, p3_rot.1 as u32,3)?; + if !found_tl { + continue; + } - // look for top right - // /\ - // __ - let p1_rot = get_point(circle.center, topr_p1, rotation); - let p2_rot = get_point(circle.center, topr_p2, rotation); - let p3_rot = get_point(circle.center, topr_p3, rotation); - let found_tr = !image.try_get(p1_rot.0 as u32, p1_rot.1 as u32)? - && !image.try_get(p2_rot.0 as u32, p2_rot.1 as u32)? - && !image.try_get(p3_rot.0 as u32, p3_rot.1 as u32)?; - if !found_tr { - continue; - } + // look for top right + // /\ + // __ + let p1_rot = get_point(circle.center, topr_p1, rotation); + let p2_rot = get_point(circle.center, topr_p2, rotation); + let p3_rot = get_point(circle.center, topr_p3, rotation); + let found_tr = !image.try_get_area(p1_rot.0 as u32, p1_rot.1 as u32,3)? + && !image.try_get_area(p2_rot.0 as u32, p2_rot.1 as u32,3)? + && !image.try_get_area(p3_rot.0 as u32, p3_rot.1 as u32,3)?; + if !found_tr { + continue; + } - // look for left - // * - // * - let p1_rot = get_point(circle.center, l_p1, rotation); - let p2_rot = get_point(circle.center, l_p2, rotation); - let p3_rot = get_point(circle.center, l_p3, rotation); - let found_l = image.try_get(p1_rot.0 as u32, p1_rot.1 as u32)? - && !image.try_get(p2_rot.0 as u32, p2_rot.1 as u32)? - && image.try_get(p3_rot.0 as u32, p3_rot.1 as u32)?; - if !found_l { - continue; - } + // look for left + // * + // * + let p1_rot = get_point(circle.center, l_p1, rotation); + let p2_rot = get_point(circle.center, l_p2, rotation); + let p3_rot = get_point(circle.center, l_p3, rotation); + let found_l = image.try_get_area(p1_rot.0 as u32, p1_rot.1 as u32,3)? + && !image.try_get_area(p2_rot.0 as u32, p2_rot.1 as u32,3)? + && image.try_get_area(p3_rot.0 as u32, p3_rot.1 as u32,3)?; + if !found_l { + continue; + } - // look for right - // * - // * - let p1_rot = get_point(circle.center, r_p1, rotation); - let p2_rot = get_point(circle.center, r_p2, rotation); - let p3_rot = get_point(circle.center, r_p3, rotation); - let found_r = image.try_get(p1_rot.0 as u32, p1_rot.1 as u32)? - && !image.try_get(p2_rot.0 as u32, p2_rot.1 as u32)? - && image.try_get(p3_rot.0 as u32, p3_rot.1 as u32)?; - if !found_r { - continue; - } + // look for right + // * + // * + let p1_rot = get_point(circle.center, r_p1, rotation); + let p2_rot = get_point(circle.center, r_p2, rotation); + let p3_rot = get_point(circle.center, r_p3, rotation); + let found_r = image.try_get_area(p1_rot.0 as u32, p1_rot.1 as u32,3)? + && !image.try_get_area(p2_rot.0 as u32, p2_rot.1 as u32,3)? + && image.try_get_area(p3_rot.0 as u32, p3_rot.1 as u32,3)?; + if !found_r { + continue; + } - // look for bottom left - // * - // * - let p1_rot = get_point(circle.center, bottoml_p1, rotation); - let p2_rot = get_point(circle.center, bottoml_p2, rotation); - let p3_rot = get_point(circle.center, bottoml_p3, rotation); - let found_bl = image.try_get(p1_rot.0 as u32, p1_rot.1 as u32)? - && !image.try_get(p2_rot.0 as u32, p2_rot.1 as u32)? - && image.try_get(p3_rot.0 as u32, p3_rot.1 as u32)?; - if !found_bl { - continue; - } + // look for bottom left + // * + // * + let p1_rot = get_point(circle.center, bottoml_p1, rotation); + let p2_rot = get_point(circle.center, bottoml_p2, rotation); + let p3_rot = get_point(circle.center, bottoml_p3, rotation); + let found_bl = image.try_get_area(p1_rot.0 as u32, p1_rot.1 as u32,3)? + && !image.try_get_area(p2_rot.0 as u32, p2_rot.1 as u32,3)? + && image.try_get_area(p3_rot.0 as u32, p3_rot.1 as u32,3)?; + if !found_bl { + continue; + } - // look for bottom right - // * - // * - let p1_rot = get_point(circle.center, bottomr_p1, rotation); - let p2_rot = get_point(circle.center, bottomr_p2, rotation); - let p3_rot = get_point(circle.center, bottomr_p3, rotation); - let found_br = image.try_get(p1_rot.0 as u32, p1_rot.1 as u32)? - && !image.try_get(p2_rot.0 as u32, p2_rot.1 as u32)? - && image.try_get(p3_rot.0 as u32, p3_rot.1 as u32)?; - if !found_br { - continue; - } + // look for bottom right + // * + // * + let p1_rot = get_point(circle.center, bottomr_p1, rotation); + let p2_rot = get_point(circle.center, bottomr_p2, rotation); + let p3_rot = get_point(circle.center, bottomr_p3, rotation); + let found_br = image.try_get_area(p1_rot.0 as u32, p1_rot.1 as u32,3)? + && !image.try_get_area(p2_rot.0 as u32, p2_rot.1 as u32,3)? + && image.try_get_area(p3_rot.0 as u32, p3_rot.1 as u32,3)?; + if !found_br { + continue; + } - // did we find it? - found = found_tl && found_tr && found_l && found_r && found_bl && found_br; + // did we find it? + found = found_tl && found_tr && found_l && found_r && found_bl && found_br; - if found { - final_rotation = rotation; - break; - } + if found { + final_rotation = rotation; + break; + } } if found { + // if final_rotation > 180.0 { final_rotation = final_rotation + 0.0 } + let new_1 = get_point( circle.center, (naive_box[0].x as u32, naive_box[0].y as u32), @@ -926,6 +929,7 @@ fn attempt_rotation_box( (naive_box[3].x as u32, naive_box[3].y as u32), final_rotation, ); + Some([ RXingResultPoint::new(new_1.0, new_1.1), RXingResultPoint::new(new_2.0, new_2.1), @@ -959,12 +963,12 @@ fn get_point(center: (u32, u32), original: (u32, u32), angle: f32) -> (f32, f32) + radians.cos() * (original.1 as f32 - center.1 as f32) + center.1 as f32; - (x, y) + (x.abs(), y.abs()) } fn adjust_point_alternate(point: (u32, u32), circle: &Circle, center_scale: f64) -> (u32, u32) { let (left_boundary, right_boundary, top_boundary, bottom_boundary) = - calculate_simple_boundary(circle, None, Some(center_scale)); + calculate_simple_boundary(circle, Some(circle.image), Some(center_scale), true); let top = bottom_boundary; let height = top_boundary - bottom_boundary; @@ -989,7 +993,7 @@ fn guess_barcode_size(circle: &Circle) -> (u32, u32) { } fn guess_barcode_size_tighter(circle: &Circle) -> (u32, u32) { - guess_barcode_size_general(circle, 0.03, 0.0695, 0.97) + guess_barcode_size_general(circle, 0.025, 0.0695, 0.97) } fn guess_barcode_size_general( @@ -1003,8 +1007,8 @@ fn guess_barcode_size_general( let ideal_symbol_side = ideal_symbol_area.sqrt(); ( - ideal_symbol_side.round() as u32, - (ideal_symbol_side * height_final_adjust_percent).round() as u32, + ideal_symbol_side.floor() as u32, + (ideal_symbol_side * height_final_adjust_percent).floor() as u32, ) } @@ -1072,6 +1076,14 @@ mod detector_test { ) } + #[test] + fn mode_2_rot90() { + finder_test( + "test_resources/blackbox/maxicode-1/MODE2-rotate-90.png", + "test_resources/blackbox/maxicode-1/MODE2-rotate-90.txt", + ) + } + #[test] fn mode3() { finder_test( diff --git a/test_resources/blackbox/maxicode-1/MODE2-rotate-90.png b/test_resources/blackbox/maxicode-1/MODE2-rotate-90.png new file mode 100644 index 0000000000000000000000000000000000000000..69e49ddb23e457f0b379af5b39e2d2bce7c7329d GIT binary patch literal 8561 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 DdG+CL literal 0 HcmV?d00001 diff --git a/test_resources/blackbox/maxicode-1/MODE2-rotate-90.txt b/test_resources/blackbox/maxicode-1/MODE2-rotate-90.txt new file mode 100644 index 0000000..ad5f7f6 --- /dev/null +++ b/test_resources/blackbox/maxicode-1/MODE2-rotate-90.txt @@ -0,0 +1 @@ +[)>0196123450000222111MODE2 \ No newline at end of file diff --git a/tests/common/abstract_black_box_test_case.rs b/tests/common/abstract_black_box_test_case.rs index c8cc837..1ed84ee 100644 --- a/tests/common/abstract_black_box_test_case.rs +++ b/tests/common/abstract_black_box_test_case.rs @@ -32,6 +32,8 @@ use rxing::{ use super::TestRXingResult; +const POSSIBLE_EXTENSIONS: &str = "jpg,jpeg,gif,png,JPG,JPEG,GIF,PNG"; + /** * @author Sean Owen * @author dswitkin@google.com (Daniel Switkin) @@ -115,7 +117,6 @@ impl AbstractBlackBoxTestCase { ); // let paths = Vec::new(); let path_search = read_dir(&self.test_base); - const POSSIBLE_EXTENSIONS: &str = "jpg,jpeg,gif,png,JPG,JPEG,GIF,PNG"; let mut paths = path_search .unwrap() @@ -123,7 +124,7 @@ impl AbstractBlackBoxTestCase { .filter(|r| r.is_ok()) // Get rid of Err variants for Result .map(|r| r.unwrap().path()) // This is safe, since we only have the Ok variants .filter(|r| r.is_file()) // Filter out non-folders - .filter(|r| POSSIBLE_EXTENSIONS.contains(r.extension().unwrap().to_str().unwrap())) + .filter(|r| r.extension().is_some() && POSSIBLE_EXTENSIONS.contains(r.extension().unwrap().to_str().unwrap())) // .map(|r| r.into_boxed_path()) .collect::>(); diff --git a/tests/maxicode_blackbox_tests.rs b/tests/maxicode_blackbox_tests.rs index 424e2f5..fe2bbe0 100644 --- a/tests/maxicode_blackbox_tests.rs +++ b/tests/maxicode_blackbox_tests.rs @@ -29,7 +29,9 @@ fn maxicode1_test_case() { BarcodeFormat::MAXICODE, ); // super("src/test/resources/blackbox/maxicode-1", new MultiFormatReader(), BarcodeFormat.MAXICODE); - tester.add_test(7, 7, 0.0); + tester.add_test(7, 8, 0.0); + tester.add_test(0, 4, 90.0); + tester.add_test(0, 3, 180.0); tester.test_black_box(); }