enero 28, 2022 10:00 am

Jesús

Un tiempo atrás hablamos sobre template matching, si se quiere uno de los detectores de objetos más rudimentarios que existen.

Aunque un repaso completo de esta técnica escapa al alcance de este artículo (eso sí, ¡te recomiendo que lo leas!), estos son los puntos clave que debes considerar:
  • Empezamos con dos imágenes A y T, siendo A la imagen objetivo y T la plantilla.
  • La idea es ir deslizando T sobre A de arriba a abajo, y de izquierda a derecha hasta cubrirla toda.
  • En cada ubicación calcularemos una métrica de similitud y T.
  • Si dicha similitud es mayor a cierto valor, asumimos que encontramos un “match” y, por tanto, hemos detectado un objeto.

Uno de los problemas de la solución que desarrollamos en ese artículo, es que se limitaba a encontrar un solo “match”, el primero.

Es decir, si la plantilla coincidía más de una vez, sólo nos quedábamos con el primer resultado, lo cual es desafortunado.

La buena noticia es que en el artículo de hoy abordaré esta falencia; como pronto descubrirás, es más sencillo de lo que piensas.

Al final de este artículo sabrás:

  • Cómo detectar múltiples objetos en una imagen utilizando plantillas.
  • Cómo reducir la cantidad de detecciones duplicadas a través de supresión no máxima (Non-Maxima Suppression, NMS, en inglés).

Pongámonos manos a la obra de inmediato.

Creación del Entorno de Desarrollo con Anaconda

Esta es la estructura del proyecto:

El archivo de mayor relevancia se halla dentro de la carpeta datasmarts, y se llama template_match.py. Es allí donde implementaremos nuestro sencillo detector de objetos.

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

Cambia tu ubicación a la raíz del proyecto, y desde ahí ejecuta este comando para crear el ambiente de Anaconda:

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

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

Para activar el ambiente, ejecuta:

conda activate opencv-multi-template-matching

Sigamos en la siguiente sección.

Detección Múltiple de Objetos con Plantillas con OpenCV

Abre el archivo datasmarts/template_match.py e inserta estas líneas para importar las dependencias del proyecto:

Para poder filtrar las detecciones débiles, nos desharemos de todas aquellas cuyo puntaje no supere el threshold de 0.8 definido abajo:

Cargamos la imagen de entrada y la mostramos en pantalla:

También cargamos la plantilla y la mostramos en pantalla después de extraer sus dimensiones:

En la detección de objetos, específicamente mediante el uso de plantillas, la información cromática de una imagen es un factor que podemos obviar, por lo que en las siguientes líneas convertimos ambas imágenes a escala de grises:

La función de OpenCV que nos permite la aplicación de template matching es cv2.matchTemplate(). Esta recibe los siguientes parámetros:

  • La imagen objetivo.
  • La plantilla.
  • El método o algoritmo de aplicación de template matching. Típicamente usaremos cv2.TM_CCOEFF_NORMED.

Fíjate que en el extracto de arriba imprimimos el número de detecciones antes de aplicar NMS. Esto nos servirá para ver el efecto positivo que tendrá la supresión no máxima en la eliminación de duplicados.

Como no todas las detecciones son de alta calidad, nos quedaremos sólo con aquellas cuyo “score” sea mayor que threshold:

Iteramos sobre las coordenadas de cada detección, y las usamos para dibujar un rectángulo alrededor de cada objeto detectado en una copia de la imagen original:

Dibujamos el resultado:

Para notar la diferencia que NMS hace, empezaremos por recopilar los rectángulos asociados a cada detección:

Ahora sí, aplicamos supresión no máxima e imprimimos el número de rectángulos que sobrevivieron a este proceso:

Dibujamos las detecciones que pasaron el proceso de NMS:

Mostramos el resultado:

¡ATENTO!

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

Para ejecutar el código correctamente, debes estar en la raíz del proyecto. Una vez allí, corre este comando:

python datasmarts/template_match.py

Veremos la imagen objetivo en pantalla:

Luego, la plantilla:

A continuación, veremos las detecciones antes de la supresión no máxima:

Al parecer sólo hay 5 detecciones válidas, que es lo que esperaríamos, ¿no?

¡Pero no! Mira lo que nos dice la consola:

Número de resultados ANTES de aplicar NMS: 205

¡205! Es decir, tenemos 200 detecciones redundantes. ¿Qué pasará después de aplicar NMS?

Veamos:

Aparentemente tenemos sólo 5 detecciones otra vez. ¿Qué nos dice la terminal?

Número de resultados DESPUÉS de aplicar NMS: 5

Excelente. NMS se deshizo de todas las detecciones repetidas correspondientes a los mismos objetos. 

Resumen

El día de hoy aprendimos a aplicar template matching para detectar múltiples objetos en una imagen con la ayuda de OpenCV.

A diferencia de la versión que habíamos estudiado aquí, esta vez nuestro detector no se detiene a la primera coincidencia, sino que continúa buscando hasta cubrir toda la imagen.

Desafortunadamente, esto conduce a un número importante de duplicados.

La buena noticia es que apalancados en otra herramienta estudiada previamente, conocida como Supresión No Máxima (NMS por sus siglas en inglés), redujimos drásticamente las detecciones redundantes, hasta quedarnos con una sola por objeto.

Debemos recordar que aunque este método puede lidiar con detecciones múltiples de objetos, aún sufre de las mismas carencias del template matching que conocíamos: si la escala, rotación o ángulo de los objetos varía, aunque sea ligeramente, el detector fallará.

Esto es lo que debes recordar:

  • Para aplicar template matching, necesitamos una imagen objetivo y una plantilla.
  • Debemos convertir ambas imágenes a escala de grises, ya que su color no influye en la eficacia del detector.
  • Aplicamos la función cv2.matchTemplate().
  • Nos quedamos únicamente con las detecciones que superen el threshold preestablecido.
  • Extraemos dichas regiones de la imagen original.
  • Aplicamos NMS.

¿Por qué no pruebas el programa con tus propias imágenes y plantillas? Descárgalo a continuación:

¡Adiós!

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.