Rilevamento di un'immagine del modello fissa da un fotogramma video semi-costante


8

Ci sono un certo numero di video che sto cercando di elaborare diversi videogiochi per rilevare vari "stati" in essi.

Il primo gioco che sto affrontando è una qualsiasi edizione di Super Street Fighter 4 .

In esso, vorrei rilevare quando viene visualizzata la schermata del personaggio "vs". Ecco un esempio di un fotogramma del video:

Akuma vs. Ryu - SSF4
(tratto dal segno ~ 10s di questo video )

Se potessi rilevare lo "vs", allora sarei in grado di rilevare che il frame del video è davvero lo schermo "vs", che mi permetterebbe di cercare altre informazioni (per ora, diciamo che lo userò per rilevare il timestamp nel video in cui la partita sta per iniziare).

Detto questo, ecco cosa si può presumere riguardo ai frame dei video che elaborerò (questo non è l'unico video, ci sono migliaia, se non decine o centinaia di migliaia di video, ma il problema della scala nell'elaborazione che molti video è un dominio completamente diverso):

  • Preferirei (ma non è necessario) elaborare l'immagine con la risoluzione più bassa possibile con risultati affidabili (risoluzioni inferiori = tempo di elaborazione più veloce). L'immagine sopra è di 480 x 270 pixel (presa da un video di YouTube con un fmt18 ) ma possono avere dimensioni diverse (ho ottenuto video di YouTube con fmt18 ma con dimensioni di 640 x 360 pixel).
  • La maggior parte dei video verrà alimentata direttamente
  • La maggior parte dei video avrà proporzioni 16: 9
  • Lo sfondo rossastro sarà animato, ma generalmente si trova all'interno di quel colore rosso-arancio (sono le fiamme)
  • A volte ci sarà un badge che si dissolve dentro e fuori nella parte inferiore del "vs" per indicare una versione (che sarà importante, ma non adesso), che potrebbe offuscare il "vs", in questo modo:

Sagat vs. Adon - SSF4: AE 2012
(tratto dal segno ~ 3s di questo video ; nota anche che quanto sopra ha una risoluzione di 640 x 360 pixel)

  • Le dimensioni e la posizione di "vs" saranno all'incirca le stesse (non l'ho ancora verificato ma so che non si muove) in proporzione ad altri video con feed diretto
  • I personaggi saranno scelti da un pool di oltre 30 su ciascun lato (in altre parole, le aree del riquadro varieranno)
  • I video dureranno generalmente dai due ai quattro minuti, con un numero di fotogrammi compreso tra 4.000 e 6,00. Tuttavia, potrebbero esserci video più lunghi (forse due ore) in cui sono presenti vari altri giochi e azioni live. Questi video non sono così importanti, ma se una soluzione mi dice dove appare un determinato gioco nel video generale più grande, fantastico
  • La risoluzione nativa delle acquisizioni è 720p, quindi un'immagine di base del "vs" può essere presa a quella che sarebbe considerata una dimensione "nativa".

In definitiva, sto cercando di codificare questa pipeline in .NET, ma non è molto importante, la dimostrazione del concetto è più importante qui e una comprensione delle tecniche coinvolte in modo da poterlo tradurre e ottimizzare per .NET così come per altri video di altri giochi dello stesso genere (se riesco a individuare i discriminatori significativi e i video di dire, Ultimate Marvel vs. Capcom 3 , Street Fighter x Tekken , BlazBlue: Continuum Shift , ecc.).

Sto anche immergendo le dita dei piedi in Mathematica e ho la versione home 8.0, quindi anche una prova di concetti in quell'ambiente è più che benvenuta.


Sono curioso di sapere perché stai sollecitando altri approcci. Hai provato l'approccio di correlazione incrociata suggerito da Yoda? È una tecnica molto semplice e naturale per risolvere questo tipo di problema e penso che dovrebbe funzionare bene per te.
Jason R,

@JasonR Ci scusiamo per la risposta tardiva. Yoda e io abbiamo discusso a lungo dell'approccio e funziona bene per la situazione poiché è strettamente limitato sopra (questa tecnica non tiene conto del taglio o della traduzione). Detto questo, siamo entrambi interessati a vedere se ci sono altri che hanno approcci diversi e una generosità è un modo naturale per incoraggiarlo.
casperUn

Risposte:


9

Se "VS" è praticamente lo stesso (salvo alcuni overlay badge come nel secondo esempio), è possibile utilizzare la correlazione incrociata semplice per rilevare la presenza del modello nel frame video. Ho risposto a una domanda simile nel fare questo in MATLAB su Stack Overflow. Puoi usare qualcosa come lo strumento "bacchetta magica" in Photoshop per selezionare "VS" dalla cornice per creare un modello. L'ho fatto e binarizzato l'immagine per ottenere questo modello .

Guardando i diversi canali di colore (RGB) nelle tue due immagini, il canale rosso sembra essere il migliore per rilevare il tuo modello.

inserisci qui la descrizione dell'immagine

Ora puoi correlare in modo incrociato il canale rosso con il tuo modello binarizzato e dovresti ottenere un picco nella posizione del modello. Ho scelto di mettere in soglia e binarizzare anche il modello rosso, sebbene sia possibile rilevarlo senza farlo. Preferisco usare una funzione di distanza piuttosto che i valori di correlazione incrociata grezzi, poiché tende ad essere un po 'più robusto rispetto ai falsi positivi. Non conosco C # /. NET, ma ecco uno schema dell'approccio in Mathematica:

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

che ti dà quanto segue. Il punto bianco segna la regione con la distanza minima in ciascuna delle due immagini

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

È quindi possibile utilizzare quanto sopra nel passaggio successivo come desiderato. Si noti che in genere la correlazione incrociata si tradurrà in una sporgenza. In altre parole (usando un esempio 1D) se si esegue una correlazione incrociata di unN segnale punto con un M punto uno, otterrai un risultato che è N+M1punto lungo. L'implementazione di Mathematica si occupa della sporgenza per te. Tuttavia, non so cosa fa C # e potresti voler tenerlo a mente (MATLAB non lo fa, e ho dovuto tenerne conto nella mia risposta collegata sopra).

Puoi anche basarti su questo e implementare un tuo criterio di soglia più solido. Per ora, devo solo evidenziare il rilevamento a beneficio di altri:

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

È possibile generare quanto sopra con una funzione combinata:

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

C'è un grande potenziale di miglioramento qui. Sono un appassionato di poltrona nell'elaborazione delle immagini, quindi non so quali siano gli algoritmi più veloci. Tuttavia, ci sono alcune cose che potresti esaminare:

  1. Se il VS si trova all'incirca nella stessa posizione in ogni video, non è necessario correlare in modo incrociato usando l'intera immagine: puoi semplicemente selezionare una casella nel mezzo e lavorare con quello.
  2. Questa potrebbe essere un'operazione costosa da fare per ogni singolo frame. Tuttavia, guardando il tuo video, hai circa poco più di 4 secondi di frame in cui hai il VS visualizzato e i nomi dei personaggi. Quindi suggerirei di analizzare un fotogramma ogni secondo o al massimo ogni 2 secondi, garantendo così di atterrare su uno con un VS su di esso. Una volta rilevato VS, è quindi possibile iniziare l'elaborazione di ogni frame successivo per eseguire la parte successiva dell'elaborazione.
  3. Questo processo dovrebbe essere, in misura ragionevole, robusto per il cambiamento delle dimensioni, ad esempio, potresti fare correlazioni incrociate su piccole immagini, ma avrai bisogno di un modello adatto da abbinare. Se sai che le tue immagini saranno in determinati set / dimensioni standard, puoi creare modelli per ciascuno di essi e selezionare il modello appropriato in base alla dimensione dell'immagine.
  4. Le soglie che ho scelto erano per tentativi ed errori, ma sembrano funzionare per le due immagini sopra e dagli altri video di YouTube correlati, probabilmente funzioneranno per la maggior parte di loro. Un approccio più specializzato implicherebbe di dividerlo in blocchi e guardare l'istogramma per dedurre se appartiene o meno a VS - forse un classificatore bayesiano. Tuttavia, sii assolutamente sicuro di doverlo fare prima di imbarcarti. Mi sembra che sia abbastanza semplice da non averne bisogno.

Dato che esiste una dimensione "nativa" per "vs" a 720p (vedere l'ultimo punto elenco sulla domanda aggiornata), può essere ridimensionato automaticamente (verso il basso, presumo) date le dimensioni del video che si sta osservando o sarebbe inclinato la correlazione incrociata risulta troppo?
Casper:

@casperOne Dovresti essere in grado di ridimensionarlo e farlo funzionare fino a quando sei sicuro che le tue immagini di test siano ridimensionate (ovvero, non ritagliate). La mia preoccupazione era nei casi in cui la dimensione dell'immagine non è quella che dovrebbe essere. Ad esempio, se avevi un'immagine 450x250 che originariamente doveva essere 480x270, ma è stata ritagliata, ridimensionare un VS ottenuto da un 640x480 non darà una buona corrispondenza (potrebbe essere abbastanza vicino però). D'altra parte, se sai che tutte quelle immagini saranno 450x250, puoi semplicemente usare un modello da uno di quei frame.
Lorem Ipsum,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.