web-dev-qa-db-fra.com

Stabilisation vidéo avec OpenCV

J'ai un flux vidéo qui est pris avec une caméra en mouvement et contient des objets en mouvement. Je souhaite stabiliser la vidéo afin que tous les objets stationnaires restent immobiles dans le flux vidéo. Comment puis-je le faire avec OpenCV?

par exemple, si j'ai deux images prev_frame et next_frame, comment transformer next_frame pour que la caméra vidéo apparaisse stationnaire?

36
Eldila

Je peux suggérer l'une des solutions suivantes:

  1. Utilisation de fonctionnalités locales de haut niveau: OpenCV inclut SURF, donc: pour chaque image, extrayez les fonctionnalités SURF. Ensuite, créez la fonctionnalité Kd-Tree (également dans OpenCV), puis faites correspondre chacune des deux trames consécutives pour trouver des paires de fonctionnalités correspondantes. Alimentez ces paires dans cvFindHomography pour calculer l'homographie entre ces trames. Cadres de chaîne selon les homographies (combinées ..) à stabiliser. Il s'agit, à ma connaissance, d'une approche très robuste et sophistiquée, mais l'extraction et l'appariement SURF peuvent être assez lents
  2. Vous pouvez essayer de faire ce qui précède avec des fonctionnalités "moins robustes", si vous vous attendez à un mouvement mineur entre deux images, par exemple utilisez la détection des coins Harris et créez des paires de coins les plus proches les uns des autres dans les deux trames, alimentez cvFindHomography puis comme ci-dessus. Probablement plus rapide mais moins robuste.
  3. Si vous limitez le mouvement à la traduction, vous pourrez peut-être remplacer cvFindHomography par quelque chose de plus ... simple, pour obtenir simplement la traduction entre les paires de fonctionnalités (par exemple, la moyenne)
  4. Utilisez la corrélation de phase (réf. http://en.wikipedia.org/wiki/Phase_correlation ), si vous vous attendez uniquement à une traduction entre deux images. OpenCV inclut DFT/FFT et IFFT, voir l'article wikipedia lié sur les formules et les explications.

[~ # ~] modifier [~ # ~] Trois remarques que je ferais mieux de mentionner explicitement, juste au cas où:

  1. L'approche basée sur l'homographie est probablement très exacte, donc l'objet stationnaire restera stationnaire. Cependant, les homographies incluent également une distorsion en perspective et un zoom, de sorte que le résultat peut sembler un peu inhabituel (ou même déformé pour certains mouvements rapides). Bien qu'exact, cela pourrait être moins agréable visuellement; utilisez-le plutôt pour un traitement ultérieur ou, comme, pour la criminalistique. Mais vous devriez l'essayer, cela pourrait être très agréable pour certaines scènes/mouvements.
  2. À ma connaissance, au moins plusieurs outils gratuits de stabilisation vidéo utilisent la corrélation de phase. Si vous souhaitez simplement "secouer" l'appareil photo, cela peut être préférable.
  3. Il y a pas mal de recherches en cours dans ce domaine. Vous trouverez des approches beaucoup plus sophistiquées dans certains articles (bien qu'elles nécessitent probablement plus que juste OpenCV).
39
zerm

OpenCV a les fonctions estimationRigidTransform () et warpAffine () qui gèrent très bien ce genre de problème.

C'est à peu près aussi simple que cela:

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

Maintenant output contient le contenu de frame2 qui est le mieux aligné pour s'adapter à frame1. Pour les grands décalages, M sera une matrice nulle ou ce ne sera peut-être pas du tout une matrice, selon la version d'OpenCV, vous devrez donc les filtrer et ne pas les appliquer. Je ne suis pas sûr de sa taille; peut-être la moitié de la largeur du cadre, peut-être plus.

Le troisième paramètre d'estimation de RigidTransform est un booléen qui lui indique s'il faut également appliquer une matrice affine arbitraire ou la limiter à la traduction/rotation/mise à l'échelle. Dans le but de stabiliser une image provenant d'un appareil photo, vous voulez probablement ce dernier. En fait, pour la stabilisation d'image de la caméra, vous pouvez également supprimer toute mise à l'échelle de la matrice renvoyée en la normalisant uniquement pour la rotation et la translation.

De plus, pour une caméra en mouvement, vous voudrez probablement échantillonner M dans le temps et calculer une moyenne.

Voici des liens vers plus d'informations sur estimationRigidTransform () , et warpAffine ()

15
Octopus

openCV a maintenant une classe de stabilisation vidéo: http://docs.opencv.org/trunk/d5/d50/group__videostab.html

13
RawMean

J'ai passé ma réponse de celle-ci. Comment stabiliser la vidéo webcam?


Hier, je viens de faire quelques travaux (en Python) sur ce sujet, les principales étapes sont:

  1. utilisation cv2.goodFeaturesToTrack pour trouver de bons coins.
  2. utilisation cv2.calcOpticalFlowPyrLK pour suivre les coins.
  3. utilisation cv2.findHomography pour calculer la matrice d'homographie.
  4. utilisation cv2.warpPerspective pour transformer l'image vidéo.

Mais le résultat n'est pas si idéal maintenant, peut-être devrais-je choisir SIFT keypoints autre que goodFeatures.


La source:

enter image description here

Stabilisez la voiture:

enter image description here

5
Kinght 金

C'est un problème délicat, mais je peux suggérer une situation quelque peu simple du haut de ma tête.

  1. Maj/rotation next_frame D'un montant arbitraire
  2. Utilisez la soustraction d'arrière-plan threshold(abs(prev_frame-next_frame_rotated)) pour trouver les éléments statiques. Vous devrez jouer avec la valeur de seuil à utiliser.
  3. Rechercher min(template_match(prev_frame_background, next_frame_rotated_background))
  4. Enregistrez le décalage/rotation de la correspondance la plus proche et appliquez-le à next_frame

Cela ne fonctionnera pas bien pour plusieurs images au fil du temps, vous devrez donc examiner l'utilisation d'un accumulateur d'arrière-plan afin que l'arrière-plan recherché par l'algorithme soit similaire dans le temps.

3
Ian Wetherbee

Je devrais ajouter les remarques suivantes pour terminer réponse de zerm . Cela simplifiera votre problème si un objet stationnaire est choisi, puis fonctionnera avec l'approche de zerm (1) avec cet objet unique. Si vous trouvez un objet stationnaire et lui appliquez la correction, je pense qu'il est sûr de supposer que les autres objets stationnaires auront également l'air stables.

Bien qu'il soit certainement valable pour votre problème difficile, vous aurez les problèmes suivants avec cette approche:

  • La détection et l'estimation de l'homographie échouent parfois pour diverses raisons: occlusions, mouvements brusques, flou de mouvement, graves différences d'éclairage. Vous devrez chercher des moyens de le gérer.

  • Votre ou vos objets cibles peuvent avoir des occlusions, ce qui signifie que sa détection échouera sur cette trame et vous devrez gérer les occlusions qui sont elles-mêmes un sujet de recherche complet.

  • En fonction de votre matériel et de la complexité de votre solution, vous pouvez rencontrer des problèmes pour obtenir des résultats en temps réel à l'aide de SURF. Vous pouvez essayer l'implémentation gpu d'opencv ou d'autres détecteurs de fonctionnalités plus rapides comme ORB, BRIEF ou FREAK.

3
Rui Marques

Voici déjà une bonne réponse, mais il utilise un algorithme un peu ancien et j'ai développé le programme pour résoudre le problème similaire, donc j'ajoute une réponse supplémentaire.

  1. Au début, vous devez extraire la fonctionnalité de l'image à l'aide d'un extracteur de fonctionnalités comme SIFT, l'algorithme SURF. Dans mon cas, l'algorithme FAST + ORB est le meilleur. Si vous voulez plus d'informations, Voir cet article
  2. Après avoir obtenu les fonctionnalités des images, vous devriez trouver des fonctionnalités correspondantes avec les images.Il existe plusieurs correspondances, mais la correspondance Bruteforce n'est pas mauvaise. Si Bruteforce est lent dans votre système, vous devez utiliser un algorithme comme KD-Tree.
  3. Enfin, vous devriez obtenir une matrice de transformation géométrique qui minimise l'erreur des points transformés. Vous pouvez utiliser l'algorithme RANSAC dans ce processus. Vous pouvez développer tout ce processus en utilisant OpenCV et je l'ai déjà développé sur des appareils mobiles. Voir ce dépôt
3
Eunchul Jeon

Contexte: Je travaillais sur ce projet de recherche où j'essayais de calculer le temps qu'il faudrait à une personne debout dans la file d'attente pour atteindre le comptoir . La première chose dont j'avais besoin était FOOTAGE alors je suis allé sur le campus et j'ai enregistré des touristes se déplaçant dans la file d'attente pour obtenir des billets. Jusqu'à ce point, je ne savais pas comment calculer le temps de mise en file d'attente et quelle précaution devrais-je prendre lors de l'enregistrement de la séquence. À la fin de la journée, j'ai constaté que toutes les images que j'ai enregistrées ont été enregistrées avec une caméra tremblante. Donc, à ce stade, je devais d'abord stabiliser la vidéo, puis développer uniquement une autre solution pour calculer le temps de mise en file d'attente.

Stabilisation vidéo à l'aide de la correspondance de modèles

  • Trouvez des objets statiques tels qu'un bureau de scrutin, une porte ou quelque chose que vous savez ne sont pas censés bouger
  • Utilisez la mise en correspondance de modèles pour calculer le décalage du changement d'emplacement de l'objet statique (par rapport aux limites du cadre) dans chaque cadre consécutif.
  • Traduisez chaque image avec la valeur de décalage, c'est-à-dire disons tx et ty.

Séquence de résultats:

Gif pour montrer le résultat de cette technique

Comme vous pouvez le voir dans le gif, l'objet statique sélectionné reste statique par rapport aux limites du cadre tandis que le mouvement peut être vu par un remplissage noir depuis les bords du cadre.

0
Yash_6795