En este tutorial, vamos a ver cómo realizar la coincidencia de múltiples plantillas con OpenCV .
Lo guiaremos a través de todo el proceso de coincidencia de múltiples plantillas usando OpenCV. Para este tutorial, necesitará una comprensión básica de la visión por computadora con OpenCV y tendrá todas las dependencias instaladas en su entorno de trabajo.
¿Qué es la coincidencia de plantillas?
Podría pensar en ello como la forma más primitiva/simple de detección de objetos. Básicamente, tratamos de encontrar la plantilla dada en la imagen de entrada que se nos proporciona.
¿En qué se diferencia de la coincidencia de una sola plantilla?
En la coincidencia de una sola plantilla, usa el método cv2.matchTemplate y luego usa minMaxLoc para obtener la coordenada del punto más probable que coincida con nuestra plantilla y el cuadro delimitador de creación en la imagen, pero en la coincidencia de varias plantillas, después de usar el cv2.matchTemplate filtraremos todos los puntos que son mayores que un umbral (pasarlo como entrada o definirlo manualmente) y luego usaremos la supresión n on-maxima (NMS) para suavizar múltiples detecciones y crear cuadros delimitadores alrededor del imagen.
Sin NMS:
Obtendríamos que se detectaran varias cajas, como:
Con NMS:
Implementación paso a paso
Paso 1: Cargue la entrada y la imagen de la plantilla
Usaremos la función cv2.imread() para cargar primero la imagen y también la plantilla a comparar. Hemos tomado las siguientes imágenes:
Modelo:
Coincidencia de imágenes:
Python3
# Reading the image and the template img = cv2.imread('Assets/img3.png') temp = cv2.imread('Assets/logo_2.png')
Paso 2: Conviértelos a escala de grises
Convertiremos ambas imágenes a escala de grises porque facilita el cálculo y los algoritmos son mucho más precisos en imágenes en escala de grises.
Python3
# Converting them to grayscale img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) temp_gray = cv2.cvtColor(temp,cv2.COLOR_BGR2GRAY)
Paso 3: usa el método cv2.matchTemplate
Usaremos cv2.matchTemplate(), como se mencionó anteriormente, para hacer coincidir la plantilla con la imagen.
cv2.matchTemplate():
Pasamos la imagen y la plantilla y también el método que usaremos. Hay diferentes métodos disponibles para la coincidencia de plantillas.
Python3
# Passing the image to matchTemplate method match = cv2.matchTemplate(image=img_gray, templ=temp_gray, method=cv2.TM_CCOEFF_NORMED)
Paso 4: filtrar los puntos más probables mediante el uso de un valor de umbral
Plantilla de coincidencia, devolveremos todos los cuadros delimitadores incluso con poca precisión, por lo que tendremos que filtrarlos. Además, debe recordar que el archivo cv2 . El método matchTemplate nos devuelve las coordenadas como una lista de tuplas, por lo que las almacenaremos por separado en una lista y luego recorreremos cada una para crear una nueva tupla con los cuatro puntos necesarios para el cuadro delimitador, como se muestra a continuación,
Python3
# Select rectangles with # confidence greater than threshold (y_points, x_points) = np.where(match >= thresh) # initialize our list of bounding boxes boxes = list() # store co-ordinates of each bounding box # we'll create a new list by looping # through each pair of points for (x, y) in zip(x_points, y_points): # update our list of boxes boxes.append((x, y, x + W, y + H))
Paso 5: use la supresión no máxima -> esto se usa para suprimir múltiples cuadros delimitadores para el mismo objeto
Ahora aplicaremos NMS en los cuadros delimitadores para suavizar todas las predicciones y darnos un cuadro delimitador definido para cada objeto.
Python3
# apply non-maxima suppression to the rectangles # this will create a single bounding box # for each object boxes = non_max_suppression(np.array(boxes))
Paso 6: Mostrar las detecciones en la imagen
Finalmente, muestre nuestras predicciones en la imagen dibujando el cuadro delimitador.
Python3
# loop over the final bounding boxes for (x1, y1, x2, y2) in boxes: # draw the bounding box on the image cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0),3) # Show the template and the final output cv2.imshow("Template" ,temp) cv2.imshow("After NMS", img) cv2.waitKey(0)
A continuación se muestra la implementación completa:
Python3
import cv2 import numpy as np from imutils.object_detection import non_max_suppression # Reading the image and the template img = cv2.imread('Assets/img3.png') temp = cv2.imread('Assets/logo_2.png') # save the image dimensions W, H = temp.shape[:2] # Define a minimum threshold thresh = 0.4 # Converting them to grayscale img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) temp_gray = cv2.cvtColor(temp, cv2.COLOR_BGR2GRAY) # Passing the image to matchTemplate method match = cv2.matchTemplate( image=img_gray, templ=temp_gray, method=cv2.TM_CCOEFF_NORMED) # Select rectangles with # confidence greater than threshold (y_points, x_points) = np.where(match >= thresh) # initialize our list of rectangles boxes = list() # loop over the starting (x, y)-coordinates again for (x, y) in zip(x_points, y_points): # update our list of rectangles boxes.append((x, y, x + W, y + H)) # apply non-maxima suppression to the rectangles # this will create a single bounding box boxes = non_max_suppression(np.array(boxes)) # loop over the final bounding boxes for (x1, y1, x2, y2) in boxes: # draw the bounding box on the image cv2.rectangle(img, (x1, y1), (x2, y2), (255, 0, 0), 3) # Show the template and the final output cv2.imshow("Template", temp) cv2.imshow("After NMS", img) cv2.waitKey(0) # destroy all the windows # manually to be on the safe side cv2.destroyAllWindows()
Producción:
Sin imagen de plantilla coincidente:
Nota: Recuerde usar una imagen pequeña para la plantilla ~ 15-20 Kb (alrededor de 50K-60K píxeles) porque de lo contrario, el algoritmo no podrá resolverlo, porque entonces el cálculo aumentará exponencialmente, como lo hace nuestro programa. t destinado a, lo que a su vez hace que nuestro programa sea cada vez menos preciso.
Publicación traducida automáticamente
Artículo escrito por bobde_yagyesh y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA