Utilisation basique de matchTemplate cv2
FerméPaya200 Messages postés 2 Date d'inscription lundi 5 décembre 2022 Statut Membre Dernière intervention 5 décembre 2022 - 5 déc. 2022 à 12:42
2 réponses
Modifié le 5 déc. 2022 à 13:38
Bonjour,
Si tu lis la documentation de matchTemplate, tu verras que la fonction permet de retrouver la région avec MinMaxLoc, qui elle même est utilisée dans l'exemple que tu as partagé. C'est le résultat de cette fonction qui permet de déterminer la position et la taille du rectangle dessiné sur l'image de droite (detected point).
Selon la méthode de reconnaissance d'image utilisée, le rectangle optimal est le min, soit le max.
# If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]: top_left = min_loc else: top_left = max_loc
Cependant, j'ai l'impression que peu importe la méthode de reconnaissance d'image utilisée, matchTemplate retourne toujours un rectangle, même s'il est très mauvais. Je suppose donc qu'il faut regarder si la valeur retournée (min_val pour cv.TM_SQDIFF et cv.TM_SQNORMED) ne dépasse pas une valeur seuil (que tu devras choisir) pour déterminer si le résultat est acceptable ou non.
Je n'ai pas regardé les valeurs retournées par ces méthodes, mais d'après leur noms, je suspecte que les méthodes cv2.*NORMED retournent une valeur entre 0 et 1. Tu peux alors définir pour ces méthodes un seuil, par exemple, min_val < 0.1 pour cv.TM_SQDIFF_NORMED et max_loc > 0.9 pour les autres.
Je n'ai pas testé, mais voici à quoi ça pourrait peut-être ressembler :
import cv2 as cv import numpy as np from matplotlib import pyplot as plt img = cv.imread('messi5.jpg',0) img2 = img.copy() template = cv.imread('template.jpg',0) (w, h) = template.shape[::-1] methods = ['cv.TM_CCOEFF_NORMED', 'cv.TM_CCORR_NORMED', 'cv.TM_SQDIFF_NORMED'] for meth in methods: img = img2.copy() method = eval(meth) # Apply template Matching res = cv.matchTemplate(img, template, method) (min_val, max_val, min_loc, max_loc) = cv.minMaxLoc(res) # If the method is TM_SQDIFF or TM_SQDIFF_NORMED, take minimum print(min_val, max_val, min_loc, max_loc) if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]: top_left = min_loc found = min_val < 0.1 else: top_left = max_loc found = max_val > 0.9 bottom_right = (top_left[0] + w, top_left[1] + h) cv.rectangle(img,top_left, bottom_right, 255, 2) plt.subplot(121),plt.imshow(res,cmap = 'gray') plt.title('Matching Result'), plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(img,cmap = 'gray') plt.title('Detected Point'), plt.xticks([]), plt.yticks([]) plt.suptitle(meth) plt.show() if found: print("FOUND") else: print("NOT FOUND")
Bonne chance
5 déc. 2022 à 12:42
merci beaucoup pour cette réponse rapide mamiemando ! je vais tester ça rapidement !