opencv-rust
opencv-rust copied to clipboard
HELP | How to use imgproc::match_template
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.
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):
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;
...