opencv-rust icon indicating copy to clipboard operation
opencv-rust copied to clipboard

HELP | How to use imgproc::match_template

Open exefer opened this issue 1 year ago • 1 comments

After I get the result Mat how do i determine if the template has matched with a threshold? I get an immense Vector of floats, how do I use it? I took a look at issues https://github.com/twistedfall/opencv-rust/issues/131 and https://github.com/twistedfall/opencv-rust/issues/168 but I couldn't determine how after they got the Mat they processed it.

MY REPO

  use opencv::{
      core::{ToInputArray, CV_32FC1},
      imgcodecs::{imread, IMREAD_GRAYSCALE},
      imgproc::{self, TM_CCORR_NORMED},
      prelude::*,
  };
  
fn detect_image(haystack: &Mat) -> Mat {
        let needle = imread("./src/needle_spawn_sign.png", IMREAD_GRAYSCALE)
            .expect("Failed to read needle image");

        let zero = Mat::zeros(
            haystack.rows() - needle.rows() + 1,
            haystack.cols() - needle.cols() + 1,
            CV_32FC1,
        )
        .unwrap();

        let mut result = zero.to_mat().unwrap();

        imgproc::match_template(
            &haystack.input_array().unwrap(),
            &needle.input_array().unwrap(),
            &mut result,
            TM_CCORR_NORMED,
            &Mat::default(),
        )
        .expect("Failed to match template");

        result
    }
     // ...
      let result = detect_image(&img);
      println!("{:?}", &result.data_typed::<f32>().unwrap());
     // ...

Results in(https://github.com/twistedfall/opencv-rust/issues/131): image

exefer avatar Dec 21 '24 10:12 exefer

It's probably to late but i use (i'm not expert in Rust and English lol) :

...
let rep_opencv = opencv::imgproc::match_template(
  &search_openv,
  &sub_openv,
  &mut out_mat,
  opencv::imgproc::TM_CCOEFF_NORMED,
  &opencv::core::no_array(),
 );

// Filter the result by threshold
let positions_buffer: Vec<(i32, i32, f32)> = Vec::New();
rep_opencv.is_ok() {
    rep_opencv.unwrap();
    for (opencv::core::Point_ { x, y }, val) in out_mat.iter().unwrap() {
        if val > 1.0 - threshold {
            positions_buffer.push((x, y, val));
        }
    }
}

// Remove results that are too close
positions_buffer.sort_unstable_by(|a, b| b.2.partial_cmp(&a.2).unwrap());
let mut i = 0;
let width_threshold = (subimage_width as f32 * 0.5f32) as i32;
let height_threshold = (subimage_height as f32 * 0.5f32) as i32;
while i < positions_buffer.len() {
    let a = positions_buffer[i];
    positions_buffer.retain(|b| {
        let dist = ((b.0 - a.0).abs(), (b.1 - a.1).abs());
        dist == (0, 0) || (dist.0 > width_threshold || dist.1 > height_threshold)
    });
    i += 1;
}
return positions_buffer;
...

IllusionPerdu avatar May 08 '25 14:05 IllusionPerdu