enero 31, 2022 10:00 am

Jesús

Otra de las debilidades de template matching, es que, al menos en su forma original, es incapaz de detectar objetos en diferentes escalas, incluso si coinciden a la perfección con la plantilla.

Por fortuna, podemos burlar esta limitación fácilmente, corriendo el algoritmo sobre muchas copias de la imagen, pero a diferentes escalas, hasta encontrar la que mejor se ajuste a la plantilla.

¿Suena familiar? 

Pues claro, ya que prácticamente lo que estamos haciendo es construir una pirámide de imágenes.

Al final de este post habrás aprendido:

¿Estás preparado? Comencemos, entonces.

Creación del Entorno de Desarrollo con Anaconda

En la siguiente imagen verás la estructura del proyecto, en la que destaca el archivo datasmarts/match.py, pues es ahí donde pondremos la implementación de nuestro detector:

Mete tus datos en este formulario para acceder al código:

Ubícate en la raíz del proyecto, y desde ahí ejecuta este comando para crear el ambiente de Anaconda:

conda env create -f opencv-multi-scale-template-matching

Esta es la configuración del ambiente recién creado (opencv-multi-scale-template-matching):

Para activar el ambiente, corre esto:

conda activate opencv-multi-scale-template-matching

Continuemos.

Detección de Objetos en Diferentes Escalas con Plantillas en OpenCV

Ve al archivo datasmarts/match.py, y escribe estas líneas para importar los paquetes de los que depende el programa:

En primer lugar, cargaremos la plantilla en memoria y la convertiremos en blanco y negro, pues como bien sabemos, en la detección de objetos la información cromática no suele ser de mucha utilidad:

Nota, además, que en el extracto anterior convertimos la imagen a un mapa de bordes utilizando el algoritmo de Canny; esto lo hacemos ya que aumenta considerablemente la efectividad de la plantilla.

También aprovechamos para mostrar la plantilla transformada en pantalla.

Luego cargamos la imagen original en escala de grises:

Declaramos la variable found la cual contendrá:

  • El score de la mejor detección.
  • La ubicación de la mejor detección.
  • El ratio de la mejor detección, el cual se calcula como el cociente entre el ancho de la imagen original y la imagen a escala en la que se halló la mejor detección

Iteramos sobre 20 escalas diferentes igualmente espaciadas, empezando por 1, lo que significa que inspeccionaremos la imagen en su tamaño original, y terminaremos en 0.2, es decir, una imagen que es 20% de la imagen original en términos de tamaño:

Si en algún momento la imagen escalada es más pequeña que la plantilla, rompemos el ciclo.

Si no, entonces la convertimos a un mapa de bordes usando Canny, y aplicamos cv2.matchTemplate() junto con cv2.minMaxLoc() para obtener la ubicación y el puntaje de una potencial detección:

Calculamos el ratio entre la imagen original y la escalada, y actualizamos found en caso de ser necesario:

Una vez terminado el ciclo, calculamos las coordenadas del rectángulo correspondiente a la mejor detección:

Por último, dibujamos la detección sobre la imagen en tamaño original y mostramos el resultado en pantalla:

¡ATENTO!

Antes de ejecutar el código, asegúrate de hallarte en la raíz del proyecto para que los comandos funcionen correctamente.

Cámbiate a la raíz del proyecto, y una vez allí, invoca el programa de la siguiente manera:

python datasmarts/match.py

Instantáneamente verás en pantalla el mapa de bordes de la plantilla:

Y justo después, observaremos un rectángulo rojo alrededor del logo de Adidas en la imagen objetivo:

Claramente, nuestro detector funciona a la perfección, especialmente si tenemos en cuenta que la plantilla tiene dimensiones considerablemente menores a las del logo en la imagen de ejemplo.

Genial, ¿no te parece?

Resumen

En este breve artículo aprendimos a remediar una de las principales fallas de template matching: su incapacidad de trabajar con objetos en diferentes escalas.

¿Cómo lo hicimos? Mediante la inspección iterativa de varias copias de la imagen, cada una más pequeña que la anterior.

El lado bueno de esta estrategia es que incrementamos la probabilidad de dar con el objeto deseado.

El lado malo, como habrás advertido, es que incurrimos en un costo muy alto, tanto en tiempo como en cómputo, lo que podría impedir el uso de template matching multi-escala en escenarios donde la velocidad sea un factor crucial.

Esto es lo que debes recordar:

  • Template matching no funciona originalmente con objetos de diferentes tamaños.
  • Podemos hacerlo funcionar usando una pirámide de imágenes.
  • Esta estrategia aumenta su efectividad, pero también su consumo de tiempo y recursos.
  • Podemos usar el algoritmo de Canny para convertir las imágenes a un mapa de bordes, con el fin de incrementar la eficacia de template matching.

Puedes descargar el código a continuación, donde encontrarás otras imágenes con las cuales correr tus propios experimentos:

¡Nos vemos pronto!

Sobre el Autor

Jesús Martínez es el creador de DataSmarts, un lugar para los apasionados por computer vision y machine learning. Cuando no se encuentra bloggeando, jugando con algún algoritmo o trabajando en un proyecto (muy) cool, disfruta escuchar a The Beatles, leer o viajar por carretera.