rusttemplate-matchingarrayfire

How can I have the pixel coordinate X,Y after ArrayFire match_template?


I'm trying to use the matching_template function from the ArrayFire library But I don't know how to find the X and Y coordinates of the best matching value. I was using the imageproc library to perform this function and there it has the find_extremes function that returns the coordinates to me. How would you do the same using ArrayFire lib?

My example using imageproc

    let template = image::open("connect.png").unwrap().to_luma8();
    let screenshot = image::open("screenshot.png").unwrap().to_luma8();

   let matching_probability= imageproc::template_matching::match_template(&screenshot, &template, MatchTemplateMethod::CrossCorrelationNormalized);
   let positions = find_extremes(&matching_probability);

 println!("{:?}", positions);

Extremes { max_value: 0.9998113, min_value: 0.42247093, max_value_location: (843, 696), min_value_location: (657, 832) }

My example using ArrayFire

   let template: Array<u8> = arrayfire::load_image(String::from("connect.png"), true);
   let screenshot: Array<u8> = arrayfire::load_image(String::from("screenshot.png"), true);

   let template_gray = rgb2gray(&template, 0.2126, 0.7152, 0.0722);
   let screen_gray =  rgb2gray(&screenshot, 0.2126, 0.7152, 0.0722);
   let matching_probability = arrayfire::match_template(&screen_gray, &template_gray, arrayfire::MatchType::LSAD);

af_print!("{:?}", matching_probability);

139569.0469 140099.2500 139869.8594 140015.7969 140680.9844 141952.5781 142602.7344 142870.7188...

from here I don't havy any idea how to get the best matching pixel coordinates.


Solution

  • Arrayfire doesn't provide "extremum" function, but separate min and max families of functions.

    The one that provides index informations are prefixed with i.

    imin_all and imax_all returns the min and max value indexes respectively wrapped in a tupple.

    You can derive pixel position from value indexes and array dimensions, knowing that arrayfire is column major.

    let template: Array<u8> = arrayfire::load_image(String::from("connect.png"), true);
    let screenshot: Array<u8> = arrayfire::load_image(String::from("screenshot.png"), true);
    
    let template_gray = rgb2gray(&template, 0.2126, 0.7152, 0.0722);
    let screen_gray = rgb2gray(&screenshot, 0.2126, 0.7152, 0.0722);
    let matching_probability = arrayfire::match_template(&screen_gray, &template_gray, arrayfire::MatchType::LSAD);
    
    let (min, _, min_idx) = imin_all(&matching_probability);
    let (max, _, max_idx) = imax_all(&matching_probability);
    
    let dims = matching_probability.dims();
    let [_, height, _, _] = dims.get();
    
    let px_x_min = min_idx as u64 / height;
    let px_y_min = min_idx as u64 % height;
    
    let px_x_max = max_idx as u64 / height;
    let px_y_max = max_idx as u64 % height;
    
    af_print!("{:?}", matching_probability);
    println!("Minimum value: {} is at pixel ({},{}).",min, px_x_min, px_y_min);
    println!("Maximum value: {} is at pixel ({},{}).", max, px_x_max, px_y_max);