5.30. Coincidencia de plantillas¶
Los detectores tratados hasta ahora responden preguntas sobre el contenido de un solo fotograma: dónde están las manchas (blobs), por dónde van las líneas, qué dice un código impreso. Una clase de pregunta distinta compara una imagen con otra. ¿Esta región del fotograma capturado se parece al parche de referencia que almacené en el momento de la calibración? Los métodos de coincidencia responden esa pregunta.
El análisis tonal y estadístico introdujo get_similarity() para la pregunta relacionada – ¿cuán parecidas son estas dos imágenes del mismo tamaño en conjunto? – con SSIM como métrica subyacente. La pregunta de coincidencia restante es la de la localización: no «cuán parecidas son estas dos imágenes» sino «¿en qué lugar dentro de esta imagen más grande aparece ese parche más pequeño?» La herramienta adecuada para la pregunta de localización es la coincidencia de plantillas.
5.30.1. La llamada básica¶
find_template() busca el primer lugar donde una pequeña imagen de plantilla aparece dentro del fotograma capturado. La implementación usa correlación cruzada normalizada (NCC): la plantilla se desliza por el fotograma, la puntuación de coincidencia por posición se calcula a partir de la correlación entre los píxeles de la plantilla y los píxeles subyacentes del fotograma (normalizada respecto a las medias y varianzas locales para que los cambios de ganancia no engañen a la coincidencia), y se devuelve como cuadro delimitador la primera posición cuya puntuación supera threshold:
template = image.Image("/sdcard/template.bmp", copy_to_fb=False)
template.to_grayscale()
match = img.find_template(template, threshold=0.7,
search=image.SEARCH_DS)
if match is not None:
img.draw_rectangle(match, color=(255, 0, 0))
El método solo funciona con imágenes en escala de grises. Captura en escala de grises (la opción natural para cualquier cámara sin sensor de color), o convierte en el sitio mediante to_grayscale() antes de la llamada. Lo mismo aplica a la plantilla cargada desde el disco: una plantilla en color se convierte con el mismo método, y el resultado es lo que el comparador espera.
threshold es un valor de coma flotante de 0.0 a 1.0. Un valor de 1.0 exige una coincidencia perfecta píxel a píxel (lo cual nunca ocurre con imágenes capturadas reales), 0.0 acepta cualquier cosa, y los valores entre 0.6 y 0.8 cubren el caso habitual en el que la plantilla se capturó bajo una iluminación similar y la escena no ha cambiado drásticamente. Aumenta el umbral para suprimir falsos positivos; redúcelo para aceptar coincidencias con más ruido a costa de más aciertos espurios.
5.30.2. Estrategia de búsqueda¶
search elige entre dos estrategias. image.SEARCH_EX es la búsqueda exhaustiva: la plantilla se desliza por cada posición de step píxeles en el fotograma y devuelve el primer acierto por encima del umbral. image.SEARCH_DS es la búsqueda en diamante: el comparador muestrea primero de forma gruesa y luego refina alrededor de la mejor puntuación, lo cual es drásticamente más rápido pero puede pasar por alto una coincidencia verdadera si la pasada gruesa cayó cerca de un máximo local que supera al global. Para una canalización en tiempo real donde la plantilla está bien definida y es poco probable que se confunda, SEARCH_DS es el valor predeterminado adecuado; para una calibración de un solo disparo donde el coste de un fallo es mayor que el coste de un escaneo más lento, SEARCH_EX es más seguro.
step controla el salto de píxeles durante la pasada exhaustiva (la búsqueda en diamante gestiona su propio paso). Valores de step más grandes aceleran el escaneo a costa de la precisión subpíxel. roi restringe la búsqueda a una región del fotograma, tanto acotando lo que el comparador considera como reduciendo el trabajo.
El valor devuelto es una tupla de cuadro delimitador (x, y, w, h) que identifica la mejor coincidencia, o None si ninguna posición superó el umbral. El cuadro delimitador encaja directamente en draw_rectangle() o crop() para la siguiente etapa de procesamiento.
5.30.3. La trampa de la escala y la rotación¶
El escollo clásico de la coincidencia de plantillas es la sensibilidad a la escala y la rotación. El comparador compara la plantilla con el fotograma píxel a píxel; una plantilla capturada a una distancia no coincide con el mismo objeto capturado a una distancia diferente, y una plantilla capturada de frente no coincide con el mismo objeto visto fuera de eje. El umbral cae silenciosamente por debajo del nivel de coincidencia incluso cuando el objeto es claramente visible para el ojo humano, y el método devuelve None.
Existen algunas soluciones alternativas para los casos simples. La aplicación puede capturar varias plantillas a diferentes escalas y ejecutar find_template() para cada una en secuencia, aceptando la primera que supere el umbral; el coste escala con el número de plantillas. La aplicación puede preprocesar el fotograma con rotation_corr() o la transformada polar (Transformaciones geométricas) para eliminar la rotación problemática antes de que se ejecute la coincidencia; la plantilla coincidente aún tiene que coincidir con la geometría corregida.
Un modismo útil para las canalizaciones de inspección de control de calidad combina el comparador de plantillas con el evaluador de similitud que introdujo el análisis tonal y estadístico: find_template() localiza la pieza en el fotograma capturado y el cuadro delimitador devuelto se recorta y se pasa a get_similarity() contra el parche de referencia. El paso de coincidencia de plantilla decide dónde está la pieza; el paso de puntuación de similitud decide si la pieza es aceptable. Los dos pasos se ejecutan en cada fotograma, el umbral sobre mean es la puerta de aprobado/reprobado, y el cuadro delimitador coincidente dibujado de nuevo en el fotograma es la vista previa del IDE que observa el operador.