2010-08-07 20 views
32

Ho un feed video che viene preso con una telecamera in movimento e contiene oggetti in movimento. Mi piacerebbe stabilizzare il video, in modo che tutti gli oggetti fermi rimangano stazionari nel feed video. Come posso fare questo con OpenCV?Stabilizzazione video con OpenCV

Ad esempio, se ho due immagini prev_frame e next_frame, come posso trasformare next_frame in modo che la videocamera appaia fissa?

risposta

32

posso suggerire una delle seguenti soluzioni:

  1. Utilizzo delle funzioni locali di alto livello: OpenCV include SURF, quindi: per ogni fotogramma, estrarre caratteristiche SURF. Quindi crea la funzione Kd-Tree (anche in OpenCV), quindi combina ogni due frame consecutivi per trovare coppie di funzionalità corrispondenti. Feed quelle coppie in cvFindHomography per calcolare l'omografia tra quei fotogrammi. Ordinare i fotogrammi secondo le omografie (combinate ..) per stabilizzare. Questo è, a mia conoscenza, un approccio molto robusto e sofisticato, tuttavia l'estrazione e l'abbinamento SURF possono essere piuttosto lenti
  2. Si può provare a fare quanto sopra con caratteristiche "meno robuste", se si prevede un minimo movimento tra due fotogrammi, per esempio usa il rilevamento angolo di Harris e crea coppie di angoli più vicini tra loro in entrambi i fotogrammi, passa a cvFindHomography come sopra. Probabilmente più veloce ma meno robusto.
  3. Se si limita il movimento alla traduzione, si potrebbe essere in grado di sostituire cvFindHomography con qualcosa di più ... semplice, per ottenere solo la traduzione tra funzionalità coppie (ad esempio media)
  4. Usa fase di correlazione (rif. http://en.wikipedia.org/wiki/Phase_correlation) , se ti aspetti solo la traduzione tra due frame. OpenCV include DFT/FFT e IFFT, vedi l'articolo wikipedia collegato su formule e spiegazione.

EDIT tre osservazioni dovrei meglio citare in modo esplicito, per ogni evenienza: approccio basato

  1. L'omografia è probabile molto preciso, oggetto in modo stazionario rimarranno stazionari. Tuttavia, le omografie includono la distorsione prospettica e lo zoom, quindi il risultato potrebbe sembrare un po '.. uncommon (o persino distorto per alcuni movimenti rapidi). Sebbene esatto, questo potrebbe essere meno visivamente piacevole; quindi usa questo piuttosto per un'ulteriore elaborazione o, come, la scientifica. Ma dovresti provarlo, potrebbe essere anche super piacevole per alcune scene/movimenti.
  2. Per quanto ne so, almeno diversi strumenti di stabilizzazione video gratuiti utilizzano la correlazione di fase.Se vuoi solo "scuotere" la fotocamera, potrebbe essere preferibile.
  3. C'è un po 'di ricerca in corso in questo campo. Troverai alcuni approcci più sofisticati in alcuni articoli (anche se probabilmente richiedono molto più di OpenCV).
+0

Grande risposta! Una bella lista. Non conoscevo la correlazione di fase. Grazie ! –

3

Questo è un problema complicato, ma posso suggerire una situazione piuttosto semplice in cima alla mia testa.

  1. Scorrimento/rotazione next_frame da una quantità arbitraria
  2. Usa sottrazione del fondo threshold(abs(prev_frame-next_frame_rotated)) per trovare gli elementi statici. Dovrai giocare con quale valore soglia usare.
  3. Trova min(template_match(prev_frame_background, next_frame_rotated_background))
  4. Record lo spostamento/rotazione della corrispondenza più vicina e applicarlo al next_frame

Questo non funziona bene per più fotogrammi nel corso del tempo, in modo ti consigliamo di considerare di usare un background accumulator quindi lo sfondo che l'algoritmo cerca è simile nel tempo.

2

Vorrei aggiungere le seguenti osservazioni per completare zerm's answer. Semplifica il tuo problema se viene scelto un oggetto stazionario e poi funziona con l'approccio di zerm (1) con quel singolo oggetto. Se si trova un oggetto fermo e si applica la correzione ad esso, penso che sia sicuro assumere che anche gli altri oggetti stazionari sembreranno stabili.

Anche se è certamente valida per il vostro problema difficile, si avrà i seguenti problemi con questo approccio:

  • rilevamento e la stima omografia a volte fallire per vari motivi: occlusioni, movimenti improvvisi, motion blur, gravi differenze di illuminazione. Dovrai cercare modi per gestirlo.

  • Gli oggetti target potrebbero avere occlusioni, il che significa che il rilevamento non avrà esito positivo su quel fotogramma e sarà necessario gestire le occlusioni che sono di per sé un argomento di ricerca completo.

  • A seconda dell'hardware e della complessità della soluzione, è possibile che si verifichino dei problemi nel raggiungere risultati in tempo reale utilizzando SURF. Potresti provare l'implementazione gpu di opencv o altri rilevatori di funzioni più veloci come ORB, BRIEF o FREAK.

14

OpenCV ha le funzioni estimateRigidTransform() e warpAffine() che gestiscono questo tipo di problema molto bene.

La sua più o meno semplice come questo:

Mat M = estimateRigidTransform(frame1,frame2,0) 
warpAffine(frame2,output,M,Size(640,480),INTER_NEAREST|WARP_INVERSE_MAP) 

Ora output contiene il contenuto della frame2 che è meglio allineate per adattarsi a frame1. Per i turni di grandi dimensioni, M sarà una matrice zero o potrebbe non essere affatto una matrice, a seconda della versione di OpenCV, quindi dovresti filtrarli e non applicarli. Non sono sicuro di quanto sia grande; forse metà della larghezza del frame, forse di più.

Il terzo parametro per valutareRigidTransform è un valore booleano che indica se applicare anche una matrice affine arbitraria o limitarla alla traslazione/rotazione/ridimensionamento. Ai fini della stabilizzazione di un'immagine da una fotocamera probabilmente si desidera solo quest'ultima. In effetti, per la stabilizzazione dell'immagine della telecamera si potrebbe anche voler rimuovere qualsiasi ridimensionamento dalla matrice restituita normalizzandolo solo per rotazione e traslazione.

Inoltre, per una telecamera in movimento, probabilmente si desidera campionare M nel tempo e calcolare una media.

Ecco i link a più informazioni estimateRigidTransform(), e warpAffine()

+0

In che libreria è il metodo 'Size' in? – user3731622

2

Ecco già buona risposta, ma usare un po 'vecchio algoritmo e ho sviluppato la programma per risolvere il problema simile, quindi aggiungo una risposta aggiuntiva.

  1. In un primo momento, è necessario estrarre la funzione dall'immagine utilizzando feature extractor come SIFT, algoritmo SURF. Nel mio caso, l'algoritmo FAST + ORB è il migliore. Se vuoi maggiori informazioni, See this paper
  2. Dopo aver ottenuto le funzionalità nelle immagini, dovresti trovare le funzionalità di corrispondenza con le immagini. Esistono diversi matcher ma Bruteforce matcher non è male. Se Bruteforce è lento nel tuo sistema, dovresti usare un algoritmo come KD-Tree.
  3. Infine, è necessario ottenere la matrice di trasformazione geometrica che riduce al minimo l'errore dei punti trasformati. È possibile utilizzare l'algoritmo RANSAC in questo processo. È possibile sviluppare tutto questo processo utilizzando OpenCV e l'ho già sviluppato nei dispositivi mobili. See this repository
3

Ho superato la mia risposta da questo. How to stabilize Webcam video?


Ieri ho appena fatto alcuni lavori (in Python) su questo argomento, fasi principali sono:

  1. uso cv2.goodFeaturesToTrack trovare buoni angoli.
  2. utilizzare cv2.calcOpticalFlowPyrLK per tracciare gli angoli.
  3. utilizzare cv2.findHomography per calcolare la matrice di omografia.
  4. utilizzare cv2.warpPerspective per trasformare il frame del video.

Ma il risultato non è ideale ora, potrebbe essere che dovrei scegliere SIFT keypoints diverso da goodFeatures.


Fonte:

enter image description here

stabilizzare la vettura:

enter image description here

Problemi correlati