Coincidencia y transparencia de plantillas OpenCV


¿Cuál es la forma en que OpenCV maneja la transparencia en la imagen durante la coincidencia de plantillas?

El problema es que la imagen de la plantilla necesita tener partes transparentes, porque en la imagen original podría haber cualquier cosa en esos lugares.

Probé todos los métodos, y ninguno de ellos dio resultados positivos (por ejemplo, la posición de la plantilla en la imagen original no se detectó correctamente).

Edit: OK, veo que es necesario proporcionar ejemplos.

Original imagen

Imagen de plantilla

Como puedes ver, es casi imposible hacer coincidir tal plantilla con una imagen como esa. El" fondo " alrededor del objeto podría tener cualquier color (como este, o blanco, marrón...)

Sobel en imagen y plantilla en escala de grises + Cvconvertsscaleabs

Imagen original adicional

Editar 2: la solución de misha funciona incluso con un poco de obstáculos alrededor (la "transparencia" funciona). Ejemplo:

Plantilla match sucessful

Editar 3-ocurrencias múltiples:

He hecho una solución rápida y sucia de encontrar múltiples ocurrencias de una plantilla, sin embargo, cuando la plantilla no se encuentra, obtengo un "montón" de falsos positivos. Principalmente debido a mi implementación:

  • iterar sobre los datos de la imagen
  • si (ImageData [y, x,0] >= MaxValue * 0.95 f) entonces cuenta [x, y] como una coincidencia (MaxValue es de cvMinMaxLoc)

It funcionapara las imágenes, cuando hay al menos una coincidencia positiva, sin embargo, resulta en una situación horrible para las imágenes, en las que no hay tal plantilla.

Author: mnn, 2011-01-21

7 answers

No parece que OpenCV maneje alpha de la manera que usted quiere.

Tienes dos opciones:

  1. Escriba su propio método de correlación cruzada que utilizará el canal alfa
  2. Transforma tus imágenes para que tu canal alfa se vuelva irrelevante

Dado que la primera opción es sencilla, exploraré la segunda opción aquí. Voy a reutilizar el código de ejemplo que le proporcioné a una pregunta similar antes. Si aplica correlación cruzada directamente a sus imágenes, el fondo interfiere con la coincidencia de la plantilla (en particular, las partes de fondo claro). Si juega con los canales de color, encontrará que la coincidencia en el canal azul da el resultado correcto. Esto depende del contenido de la imagen y no es una forma consistente de resolver el problema.

Otra opción es realizar detección de bordes (por ejemplo, Sobel) en la imagen y la plantilla, y luego realizar una correlación cruzada. Aquí están las imágenes detectadas edge (I usó el detector Sobel edge en el canal de Luma en GIMP, y luego un poco de estiramiento de intensidad).

asignar

edificio

Como puede ver, el canal alfa aquí se ha vuelto irrelevante, ya que la mayor parte del terreno se ha convertido en intensidad cero y no contribuirá al cálculo de correlación cruzada. Así que ahora la correlación cruzada se puede aplicar directamente, dando el resultado deseado:

misha@misha-desktop:~/Desktop/stackoverflow$ python cross-correlation.py map-blue.png building-maskz-blue.png 
(163, 244)

Finalmente, aquí está otra pregunta relacionada.

PS. Qué juego es ¿esto?

 16
Author: mpenkov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:15

Tengo una solución un poco más de muerte cerebral para este problema que en realidad parece funcionar razonablemente bien: Reemplazar el canal alfa de la imagen de la plantilla con ruido, que más o menos hace que las regiones transparentes sean estadísticamente insignificantes durante el proceso de coincidencia.

Por ejemplo, mi caso de uso implicaba buscar caracteres emoji en capturas de pantalla de iOS. El fondo del teclado iOS cambia de color según el contexto, lo que hace que el proceso de coincidencia sea problemático si comprometerse a un color de fondo particular en la imagen de la plantilla.

Aquí está la imagen de plantilla raw en alpha:
imagen de plantilla raw en alpha

Aquí está la plantilla procesada con el relleno de ruido para el canal alfa:
introduzca la descripción de la imagen aquí

Envié la imagen de plantilla procesada a través del código de ejemplo que coincide con la plantilla proporcionado en la documentación de OpenCV. En fondo oscuro o claro, el partido se encuentra con confianza razonable.

Buscando en la oscuridad fondos:

emparejado en la oscuridad

Buscando en fondos claros:

emparejado en la luz

En comparación, dejar el canal alfa de la plantilla transparente - o comprometerse con un fondo oscuro o claro - no devolvió coincidencias aceptables.

 9
Author: kitschpatrol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-09 00:31:09

OpenCV 3.0 ofrece soporte nativo para la coincidencia de plantillas con plantillas enmascaradas. Consulte la nueva documentación :

Parámetros:

Imagen ...

Templ ...

Resultado ...

Método ...

Mask Máscara de la plantilla buscada. Debe tener el mismo tipo de datos y tamaño con templ. No está configurado de forma predeterminada.

[Ligera Digresión]

Tenga en cuenta que la plantilla coincide con enmascarado sin embargo, las imágenes de referencia (la imagen más grande) no son posibles. Y eso tiene sentido, dado que OpenCV utiliza la coincidencia de plantillas basada en FFT.

Por lo tanto, si necesita realizar la coincidencia de plantillas solo en regiones específicas de sus imágenes de referencia, deberá implementar su propio método para eso o enmascarar la salida de cv::matchTemplate.

Implementarlo desde cero debería compensar los casos en los que solo desea buscar la plantilla en regiones muy específicas (es decir, alrededor de Harris esquina).

 8
Author: Marcello Salomao,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-22 15:32:27

La opción SQDIFF/SQDIFF_N sería una solución si intentara reemplazar el canal alfa con el color RGB negro. Al menos esta fue mi solución al mismo problema. De mi resultado es obvio que este método es sensible a los valores de píxeles más brillantes, y aproveché la oportunidad de eso.

 1
Author: Marstep,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-22 20:08:07

Creo que estás tratando de hacer lo que en OpenCV se llama coincidencia de plantilla con una máscara. Creo que podrías intentar establecer un ROI (región de interés) en la plantilla. Esta pregunta muestra cómo hacerlo. (tenga en cuenta que en esa pregunta el ROI se establece en la imagen de destino, no en la plantilla, pero el procedimiento es el mismo).

 -1
Author: carlosdc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:00:34

No estoy seguro, pero el canal de transparencia se trata como cualquier otro canal. Si un píxel en una plantilla es "transparente", también debe ser "transparente" en la imagen principal. Sólo estoy adivinando.

 -1
Author: Utkarsh Sinha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-01-24 13:39:59

Me encontré con el mismo problema y pensé en una solución. Asumiendo que referenceImageMask y templateMask tienen 1s en los píxeles buenos y 0s en los malos. Y que referenceImage y templateImage ya han sido enmascarados y tienen 0s en los píxeles malos también.

Entonces, el primer resultado de la coincidencia de plantillas dará la correlación cruzada no normalizada entre las imágenes. Sin embargo, un montón de píxeles eran cero.

La segunda coincidencia de plantilla dará para cada posible desplazamiento del número de píxeles que eran al mismo tiempo diferentes de cero (desenmascarados) en ambas imágenes.

Entonces, normalizar la correlación por ese número debería dar el valor que tú (y yo) queríamos. El producto promedio para los píxeles que no están enmascarados en ambas imágenes.

Image<Gray, float> imCorr = referenceImage.MatchTemplate(templateImage,      Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCORR);
Image<Gray, float> imCorrMask = referenceImageMask.MatchTemplate(templateMask, Emgu.CV.CvEnum.TM_TYPE.CV_TM_CCORR);
_imCorr = _imCorr.Mul(_imCorrMask.Pow(-1));

ACTUALIZACIÓN: en realidad, esta solución no funciona. Debido a que la implementación de la correlación cruzada en opencv utiliza el DFT, habrá problemas numéricos y no puede usar el segundo crosscorrelation para corregir el primero.

 -2
Author: Jorge Otero-Millan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-22 15:44:31