Detectar una imagen de plantilla fija de un cuadro de video semi constante

8

Hay una serie de videos que estoy buscando procesar de diferentes videojuegos para detectar varios "estados" en ellos.

El primer juego que estoy abordando es cualquier edición de Super Street Fighter 4 .

En él, me gustaría detectar cuándo aparece la pantalla del personaje "vs". Aquí hay un ejemplo de un cuadro del video:

Akuma vs Ryu - SSF4
(tomado de la marca de ~ 10s de este video )

Si pudiera detectar el "vs", sería capaz de detectar que el cuadro de video es de hecho la pantalla "vs", lo que me permitiría buscar otra información (por ahora, digamos que lo usaré para detectar la marca de tiempo en el video donde el partido está por comenzar).

Dicho esto, esto es lo que se puede suponer acerca de los cuadros de los videos que voy a procesar (este no es el único video, hay miles, si no decenas o cientos de miles de videos, sino el problema de la escala en el procesamiento que muchos videos es un dominio completamente diferente):

  • Preferiría (pero no es necesario) procesar la imagen con la resolución más baja posible con resultados confiables (resoluciones más bajas = tiempo de procesamiento más rápido). La imagen de arriba es de 480 x 270 píxeles (tomada de un video de YouTube con un fmt18 ) pero pueden venir en diferentes tamaños (obtuve videos de YouTube con fmt18 pero con dimensiones de 640 x 360 píxeles).
  • La mayoría de los videos serán de alimentación directa
  • La mayoría de los videos tendrán una relación de aspecto de 16: 9
  • El fondo rojizo estará animado, pero generalmente estará dentro de ese color rojo anaranjado (es llamas)
  • A veces habrá una insignia que se desvanece dentro y fuera de la parte inferior de la "vs" para indicar una versión (que será importante, pero no en este momento), que podría ofuscar la "vs", así:

Sagat vs. Adon - SSF4: AE 2012
(tomado de la marca ~ 3s de este video ; también tenga en cuenta que lo anterior es una resolución de 640 x 360 píxeles)

  • El tamaño y la posición del "vs" será más o menos el mismo (no lo he verificado aún, pero sé que no se mueve) en proporción a otros videos de alimentación directa
  • Los personajes serán elegidos de un grupo de más de 30 en cada lado (en otras palabras, esas áreas del marco variarán)
  • Los videos generalmente durarán entre dos y cuatro minutos, con entre 4,000 y 6,00 cuadros. Sin embargo, puede haber videos más largos (quizás dos horas) que tienen varios otros juegos y acción en vivo. Estos videos no son tan importantes, pero si una solución me dice dónde aparece un determinado juego en el video general más grande, genial
  • La resolución nativa de las capturas es 720p, por lo que se puede tomar una imagen de referencia del "vs" en lo que se consideraría un tamaño "nativo".

En última instancia, estoy buscando codificar esta canalización en .NET, pero eso no es muy importante, la prueba de concepto es más importante aquí, así como una comprensión de las técnicas involucradas para poder traducirla y optimizarla para .NET así como para otros videos de otros juegos del mismo género (si puedo elegir los discriminadores significativos y videos de, por ejemplo, Ultimate Marvel vs. Capcom 3 , Street Fighter x Tekken , BlazBlue: Continuum Shift , etc.).

También estoy sumergiendo mis pies en Mathematica y tengo la versión casera 8.0, por lo que una prueba de conceptos en ese entorno es más que bienvenida.

casperOne
fuente
Tengo curiosidad por saber por qué estás solicitando otros enfoques. ¿Has probado el enfoque de correlación cruzada que sugeriste? Es una técnica muy sencilla y natural para resolver este tipo de problema, y ​​creo que debería funcionar bien para usted.
Jason R
@JasonR Perdón por la respuesta tardía. En realidad, Yoda y yo discutimos el enfoque en longitud y funciona bien para la situación, ya que está limitado anteriormente (esta técnica no tiene en cuenta la cizalladura o la traducción). Dicho esto, ambos estamos interesados ​​en ver si hay otros que tienen enfoques diferentes y una recompensa es una forma natural de alentar eso.
casperOne

Respuestas:

9

Si el "VS" es más o menos el mismo (salvo para algunas superposiciones de credenciales como en el segundo ejemplo), puede usar una correlación cruzada directa para detectar la presencia de la plantilla en su cuadro de video. Respondí una pregunta similar sobre cómo hacer esto en MATLAB en Stack Overflow. Puede usar algo como la herramienta "varita mágica" en Photoshop para seleccionar el "VS" del marco para crear una plantilla. Lo hice y binaré la imagen para obtener esta plantilla .

Al observar los diferentes canales de color (RGB) en sus dos imágenes, el canal rojo parece ser el mejor para detectar su plantilla.

ingrese la descripción de la imagen aquí

Ahora puede realizar una correlación cruzada del canal rojo con su plantilla binarizada y debería obtener un pico en la ubicación de la plantilla. Elijo limitar y binarizar la plantilla roja también, aunque puedes detectarla sin hacerlo. Prefiero usar una función de distancia en lugar de valores de correlación cruda sin procesar, ya que tiende a ser un poco más robusto contra los falsos positivos. No sé C # /. NET, pero aquí hay un resumen del enfoque en Mathematica:

image = Import["http://i.stack.imgur.com/7RwAh.png"];
ImageCorrelate[ Binarize[ColorSeparate[image][[1]], 0.1], vsTemplate, 
   NormalizedSquaredEuclideanDistance] // Binarize[#, 0.2] & // ColorNegate

que te da lo siguiente. El punto blanco marca la región con la distancia mínima en cada una de las dos imágenes.

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

NMN+M1

También puede construir sobre esto e implementar un criterio de umbral más robusto propio. Por ahora, solo resaltaré la detección en beneficio de otros:

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Puede generar lo anterior con una función combinada:

detectVS[i_Image] := 
 Module[{mask = 
    ImageCorrelate[ Binarize[ColorSeparate[i][[1]], 0.1], vsTemplate, 
       NormalizedSquaredEuclideanDistance] ~Binarize~ 0.2 // 
     ColorNegate},

  ColorConvert[i, "Grayscale"]~ImageAdd~ 
   ImageMultiply[i, Image[mask]~Dilation~ DiskMatrix@100]
  ]

Hay mucho potencial de mejora aquí. Soy un aficionado al sillón en el procesamiento de imágenes, por lo que no sé cuáles son los algoritmos más rápidos. Sin embargo, hay algunas cosas que podría considerar:

  1. Si el VS es aproximadamente la misma ubicación en cada video, no necesita una correlación cruzada con toda la imagen, solo puede seleccionar un cuadro en el medio y trabajar con eso.
  2. Esta podría ser una operación costosa para cada cuadro. Sin embargo, al mirar su video, tiene aproximadamente un poco más de 4 segundos de fotogramas en los que se muestran el VS y los nombres de los personajes. Por lo tanto, le sugiero que analice un cuadro cada segundo o como máximo cada 2 segundos, garantizando así que aterrizará en uno con un VS en él. Una vez que detecte VS, puede comenzar a procesar cada fotograma sucesivo para hacer la siguiente parte de su procesamiento.
  3. Este proceso debería ser, en un grado razonable, robusto hacia el cambio de tamaño, es decir, podría hacer correlaciones cruzadas en imágenes pequeñas, pero necesitará una plantilla adecuada para que coincida. Si sabe que sus imágenes estarán en ciertos tamaños establecidos / estándar, puede crear plantillas para cada una de ellas y seleccionar la plantilla adecuada según el tamaño de la imagen.
  4. Los umbrales que elegí fueron por prueba y error, pero parecen funcionar para las dos imágenes de arriba y de los otros videos de YouTube relacionados, probablemente funcionarán para la mayoría de ellos. Un enfoque más especializado implicaría dividirlo en bloques y mirar el histograma para inferir si pertenece a VS o no, tal vez un clasificador bayesiano. Sin embargo, asegúrese de que necesita hacer esto antes de embarcarse en él. Me parece que es lo suficientemente simple como para que no lo necesite.
Lorem Ipsum
fuente
Dado que hay un tamaño "nativo" para el "vs" a 720p (ver el último punto en la pregunta actualizada), ¿se puede escalar automáticamente (supongo que se debe reducir) dadas las dimensiones del video que se está observando o eso podría sesgarse? la correlación cruzada resulta demasiado?
casperOne
@casperOne Debería poder reducirlo y aún así hacerlo funcionar siempre que esté seguro de que las imágenes de prueba se reducen (es decir, no se recortan). Mi preocupación fue en los casos en que el tamaño de la imagen no es lo que se supone que debe ser. Por ejemplo, si tenía una imagen de 450x250 que originalmente se suponía que era 480x270, pero se recortó, reducir un VS obtenido de un 640x480 no dará una buena coincidencia (aunque podría estar lo suficientemente cerca). Por otro lado, si sabe que todas esas imágenes serán de 450x250, simplemente puede usar una plantilla de uno de esos marcos.
Lorem Ipsum