Détection d'une image de modèle fixe à partir d'une image vidéo semi-constante

8

Il y a un certain nombre de vidéos que je cherche à traiter de différents jeux vidéo pour détecter divers "états" en eux.

Le premier jeu auquel je m'attaque est une édition de Super Street Fighter 4 .

Dans celui-ci, je voudrais détecter quand l'écran de caractère "vs" apparaît. Voici un exemple d' une image de la vidéo:

Akuma contre Ryu - SSF4
(extrait de la marque ~ 10s de cette vidéo )

Si je pouvais détecter le "vs", je serais alors en mesure de détecter que la trame de la vidéo est bien l'écran "vs", ce qui me permettrait de rechercher d'autres informations (pour l'instant, disons que je vais l'utiliser pour détecter l'horodatage dans la vidéo où le match est sur le point de commencer).

Cela dit, voici ce que l'on peut supposer des images des vidéos que je vais traiter (ce n'est pas la seule vidéo, il y a des milliers, sinon des dizaines ou des centaines de milliers de vidéos, mais la question de l'échelle dans le traitement qui de nombreuses vidéos est un domaine complètement différent):

  • Je préférerais (mais ce n'est pas nécessaire) traiter l'image à la résolution la plus basse possible avec des résultats fiables (résolutions plus faibles = temps de traitement plus rapide). L'image ci-dessus est de 480 x 270 pixels (prise à partir d'une vidéo YouTube avec un fmt18 ) mais ils peuvent venir de différentes tailles (j'ai des vidéos YouTube avec fmt18 mais avec des dimensions 640 x 360 pixels).
  • La plupart des vidéos seront alimentées directement
  • La plupart des vidéos seront au format 16: 9
  • Le fond rougeâtre sera animé, mais généralement dans cette couleur orange-rouge (ce sont des flammes)
  • Parfois, il y aura un badge apparaissant dans la partie inférieure du "vs" pour indiquer une version (qui sera importante, mais pas pour le moment), qui pourrait obscurcir le "vs", comme ceci:

Sagat contre Adon - SSF4: AE 2012
(tiré de la marque ~ 3s de cette vidéo ; notez également que ce qui précède est une résolution de 640 x 360 pixels)

  • La taille et la position du "vs" vont être à peu près les mêmes (je n'ai pas encore vérifié cela mais je sais que cela ne bouge pas) proportionnellement aux autres vidéos à alimentation directe
  • Les personnages seront choisis dans un pool de plus de 30 de chaque côté (en d'autres termes, ces zones du cadre varieront)
  • Les vidéos durent généralement de deux à quatre minutes, avec entre 4 000 et 6 000 images. Cependant, il peut y avoir des vidéos plus longues (peut-être deux heures) avec divers autres jeux et des actions en direct. Ces vidéos ne sont pas aussi importantes, mais si une solution me dit où un certain jeu apparaît dans la vidéo globale plus grande, super
  • La résolution native des captures est de 720p, donc une image de base du "vs" peut être prise à ce qui serait considéré comme une taille "native".

En fin de compte, je cherche à coder ce pipeline dans .NET, mais ce n'est pas super important, la preuve de concept est plus importante ici ainsi que la compréhension des techniques impliquées afin que je puisse le traduire et l'optimiser pour .NET ainsi que pour d'autres vidéos d'autres jeux du même genre (si je peux identifier les discriminants importants, et des vidéos de disons, Ultimate Marvel vs Capcom 3 , Street Fighter x Tekken , BlazBlue: Continuum Shift , etc.).

Je plonge également mes orteils dans Mathematica et j'ai la version familiale 8.0, donc une preuve de concept dans cet environnement est également la bienvenue.

casperOne
la source
Je suis curieux de savoir pourquoi vous sollicitez d'autres approches. Avez-vous essayé l'approche de corrélation croisée suggérée par Yoda? C'est une technique très simple et naturelle pour résoudre ce genre de problème, et je pense que cela devrait bien fonctionner pour vous.
Jason R
@JasonR Désolé pour la réponse tardive. Yoda et moi avons en fait discuté longuement de l'approche et cela fonctionne bien pour la situation car elle est étroitement limitée ci-dessus (cette technique ne prend pas en compte le cisaillement ou la translation). Cela dit, nous sommes tous deux intéressés de voir s'il y en a d'autres qui ont des approches différentes et une prime est un moyen naturel d'encourager cela.
casperOne

Réponses:

9

Si le "VS" est à peu près le même (sauf pour certaines superpositions de badges comme dans le deuxième exemple), vous pouvez utiliser une corrélation croisée simple pour détecter la présence du modèle dans votre image vidéo. J'ai répondu à une question similaire à ce sujet dans MATLAB sur Stack Overflow. Vous pouvez utiliser quelque chose comme l'outil "baguette magique" dans Photoshop pour sélectionner le "VS" dans le cadre pour créer un modèle. Je l'ai fait et binarisé l'image pour obtenir ce modèle .

En regardant les différents canaux de couleur (RVB) dans vos deux images, le canal rouge semble être le meilleur pour détecter votre modèle.

entrez la description de l'image ici

Vous pouvez maintenant intercorréler le canal rouge avec votre modèle binarisé et vous devriez obtenir un pic à l'emplacement du modèle. J'ai également choisi de seuiller et de binariser le modèle rouge, bien que vous puissiez le détecter sans le faire. Je préfère utiliser une fonction de distance plutôt que des valeurs de corrélation croisée brutes, car elle a tendance à être un peu plus robuste contre les faux positifs. Je ne connais pas C # /. NET, mais voici un aperçu de l'approche dans Mathematica:

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

ce qui vous donne ce qui suit. Le point blanc marque la région avec la distance minimale dans chacune des deux images

entrez la description de l'image ici entrez la description de l'image ici

Vous pouvez ensuite utiliser ce qui précède dans votre prochaine étape comme vous le souhaitez. Notez que généralement, la corrélation croisée entraînera un surplomb. En d'autres termes (en utilisant un exemple 1D) si vous effectuez une corrélation croisée entre un signal à points et un signal à points, vous obtiendrez un résultat de point de long. L'implémentation de Mathematica s'occupe du surplomb pour vous. Cependant, je ne sais pas ce que fait C #, et vous voudrez peut-être garder cela à l'esprit (MATLAB ne le fait pas, et j'ai dû en tenir compte dans ma réponse liée ci-dessus).NMN+M1

Vous pouvez également en tirer parti et implémenter un critère de seuillage plus robuste. Pour l'instant, je vais juste souligner la détection au profit des autres:

entrez la description de l'image ici entrez la description de l'image ici

Vous pouvez générer ce qui précède avec une fonction combinée:

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

Il y a beaucoup de potentiel d'amélioration ici. Je suis un amateur de fauteuil au traitement d'image, donc je ne sais pas quels sont les algorithmes les plus rapides. Cependant, il y a quelques choses que vous pourriez examiner:

  1. Si le VS est à peu près au même endroit dans chaque vidéo, vous n'avez pas besoin de faire une corrélation croisée en utilisant l'image entière - vous pouvez simplement sélectionner une case au milieu et travailler avec cela.
  2. Cela peut être une opération coûteuse à effectuer pour chaque trame. Cependant, en regardant votre vidéo, vous avez environ un peu plus de 4 secondes d'images où les VS sont affichés et les noms des personnages. Je vous suggère donc d'analyser une image toutes les secondes ou au plus toutes les 2 secondes, garantissant ainsi que vous atterrirez sur une image avec un VS dessus. Une fois que vous avez détecté VS, vous pouvez alors commencer à traiter chaque trame successive pour effectuer la partie suivante de votre traitement.
  3. Ce processus devrait être, dans une mesure raisonnable, robuste aux changements de taille, c'est-à-dire que vous pourriez faire des corrélations croisées sur de petites images, mais vous aurez besoin d'un modèle approprié pour correspondre. Si vous savez que vos images seront dans certaines tailles définies / standard, vous pouvez créer des modèles pour chacune d'elles et sélectionner le modèle approprié en fonction de la taille de l'image.
  4. Les seuils que j'ai choisis étaient par essais et erreurs, mais ils semblent fonctionner pour les deux images ci-dessus et des autres vidéos youtube connexes, ils fonctionneront probablement pour la plupart d'entre eux. Une approche plus spécialisée impliquerait de le diviser en blocs et de regarder l'histogramme pour déduire s'il appartient à VS ou non - peut-être un classificateur bayésien. Cependant, soyez absolument sûr que vous devez le faire avant de vous y lancer. Il me semble que c'est assez simple pour que vous n'en ayez pas besoin.
Lorem Ipsum
la source
Étant donné qu'il existe une taille "native" pour le "vs" à 720p (voir la dernière puce de la question mise à jour), celle-ci peut-elle être mise à l'échelle automatique (vers le bas, je suppose) compte tenu des dimensions de la vidéo observée ou est-ce que cela fausserait la corrélation croisée résulte trop?
casperOne
@casperOne Vous devriez être en mesure de le réduire et de le faire fonctionner tant que vous êtes sûr que vos images de test sont juste réduites (c'est-à-dire non recadrées). Ma préoccupation était dans les cas où la taille de l'image n'est pas ce qu'elle est censée être. Par exemple, si vous aviez une image 450x250 qui était à l'origine censée être 480x270, mais a été rognée, la réduction d'un VS obtenu à partir d'un 640x480 ne donnera pas une bonne correspondance (elle pourrait cependant être assez proche). D'un autre côté, si vous savez que toutes ces images seront en 450x250, vous pouvez simplement utiliser un modèle à partir de l'un de ces cadres.
Lorem Ipsum