template español image-processing opencv computer-vision template-matching

image-processing - español - template matching matlab



Coincidencia de plantilla de OpenCV y transparencia (7)

Creo que estás tratando de hacer lo que en OpenCV se llama correspondencia de plantillas con una máscara. Creo que podrías intentar establecer un ROI (región de interés) en la plantilla. Esta pregunta SO 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).

¿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 debe tener partes transparentes, porque en la imagen original podría haber algo en esos lugares.

Probé todos los métodos y ninguno arrojó resultados positivos (p. Ej., La posición de la plantilla en la imagen original no se detectó correctamente).

Editar: OK, veo que es necesario dar ejemplos.

Imagen original

Imagen de la plantilla

Como puede ver, es casi imposible hacer coincidir dicha 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 grayscaled + cvConvertScaleAbs

Imagen original adicional

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

Plantilla coincidente exitosa

Edición 3 - múltiples ocurrencias:

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

  • iterar sobre los datos de imagen
  • if (imageData [y, x, 0]> = maxValue * 0.95f) entonces cuenta [x, y] como una coincidencia (maxValue es de cvMinMaxLoc)

works para 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 existe dicha plantilla .


La opción SQDIFF/SQDIFF_N sería una solución si intentas 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é una oportunidad de eso.


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

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

La segunda coincidencia de plantilla dará para cada compensación posible el número de píxeles que fueron al mismo tiempo diferentes de cero (sin máscara) en ambas imágenes.

Entonces, la normalización de la correlación por ese número debería dar el valor que usted (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 usa el DFT, habrá problemas numéricos y no podrá usar la segunda correlación cruzada para corregir el primero.


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. Solo estoy adivinando aquí.


No parece que OpenCV maneje alfa de la forma en que lo desea.

Tienes dos opciones:

  1. Escribe tu propio método de correlación cruzada que usará el canal alfa
  2. Transforme sus imágenes para que su canal alfa se vuelva irrelevante

Dado que la primera opción es sencilla, exploraré la segunda opción aquí. Voy a volver a utilizar el código de muestra que proporcioné a una pregunta similar anterior. Si aplica una 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 juegas con canales de color, encontrarás 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 la 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 de detección de bordes (utilicé el detector de bordes Sobel en el canal Luma en GIMP, y luego un poco de intensidad).

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

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

Finalmente, aquí hay otra pregunta relacionada .

PD. ¿Qué juego es este?


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 ...

máscara máscara de plantilla buscada. Debe tener el mismo tipo de datos y tamaño con templ. No está configurado por defecto.

[Ligera digresión]

Sin embargo, tenga en cuenta que la coincidencia de plantillas con imágenes de referencia enmascaradas (la imagen más grande) no es posible. Y eso tiene sentido, dado que OpenCV usa la coincidencia de plantillas basada en FFT.

Por lo tanto, si necesita realizar una coincidencia de plantilla solo en regiones específicas de sus imágenes de referencia, deberá implementar su propio método para eso o enmascarar el resultado 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 las esquinas de harris).


Tengo una solución ligeramente más cerebral para este problema que parece funcionar razonablemente bien: reemplace el canal alfa de la imagen de la plantilla con ruido, lo que hace que las regiones transparentes sean prácticamente insignificantes durante el proceso de adaptación.

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

Aquí está la imagen de la plantilla sin procesar en alfa:

Aquí está la plantilla procesada con relleno de ruido para el canal alfa:

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

Buscando en fondos oscuros:

Buscando en fondos claros:

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