FFmpeg / VidStab

Ayant acquis récemment une actioncam, la Xiaomi Yi (2K), afin de filmer mes sorties vélos, j'ai rapidement eu besoin de stabiliser mes vidéos, histoire de ne pas faire irrémédiablement vomir mes spectacteurs.

Je n'ai pas eu à chercher bien loin, les outils étaient déjà là, il ne restait plus qu'a m'en saisir. Aujourd'hui nous allons voir comment stabiliser nos vidéos avec l'incontournable FFMpeg et VidStab qui sont à l'origine de bon nombre de logiciels de stabilisation.

Dans cet article nous allons aborder la stabilisation vidéo en CLI, notamment sous les distributions GNU/Linux. Pour le présent article j'utilise Fedora, mais quoiqu'il en soit les manipulations restent à peu de choses près les mêmes, peu importe votre système d'exploitation. Je vous laisse tout de même jeter un oeil à ces articles afin d'installer/utiliser correctement vos outils : macOS et Windows.

Prérequis

  • 1 - On commence par vérifier si ffmpeg n'est pas déjà installé en tapant simplement la commande ffmpeg. Si la commande est inconnue, c'est tout bon. Sinon il faut désinstaller pour éviter les conflits de versions - sudo dnf remove ffmpeg
  • 2 - Petite mise à jour de rigueur - sudo dnf update && sudo dnf upgrade

Installation / configuration

Allez savoir pourquoi, libvidstab ne semble pas présent dans la version de ffmpeg, des dépôts officiels. S'offre à nous deux possibilités, soit compiler nous-même ffpmeg avec les librairies souhaitées, soit utiliser ce qu'on appelle une static build autrement dit une version pré-compilée embarquant tout ce dont nous aurons besoin. Aujourd'hui j'ai la migraine, on va donc opté pour la seconde option.

Il va nous falloir passer par les static builds (plus ou moins) officiels de ffmpeg, gracieusement précompilés par John Van Sickle. Merci à lui.

  • 1 - Tout d'abord on passe en root : sudo su -
  • 2 - On se rend dans le bon répertoire : cd /usr/local/bin
  • 3 - On créé un répertoire pour accueillir ffmpeg : mkdir ffmpeg
  • 4 - Et on y accède : cd ffmpeg
  • 5 - Téléchargeons le static build adéquat. Dans notre cas une version Git (recommandée pour ses correctifs) en 64bit : wget https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-64bit-static.tar.xz
  • 6 - On extrait l'archive : tar xf ffmpeg-git-64bit-static.tar.xz
  • 7 - On vérifie le nom de version, dans mon cas il se nomme ffmpeg-git-20171216-64bit-static : ls
  • 8 - Et on y accède en veillant au nom de version: cd ffmpeg-git-VERSION-64bit-static
  • 9 - On vérifie la version : ./ffmpeg -version
  • 10 - Nous sommes donc à la version N-89508-g1f1207145a-static. On s'assure aussi au passage que la librairie recherchée, libvidstab, est bien présente. Dans mon cas me retourne :
# ./ffmpeg -version
ffmpeg version N-89508-g1f1207145a-static https://johnvansickle.com/ffmpeg/  Copyright (c) 2000-2017 the FFmpeg developers
built with gcc 6.4.0 (Debian 6.4.0-11) 20171206
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-librtmp --enable-libsoxr --enable-libspeex --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg
libavutil      56.  6.100 / 56.  6.100
libavcodec     58.  8.100 / 58.  8.100
libavformat    58.  3.100 / 58.  3.100
libavdevice    58.  0.100 / 58.  0.100
libavfilter     7.  7.100 /  7.  7.100
libswscale      5.  0.101 /  5.  0.101
libswresample   3.  0.101 /  3.  0.101
libpostproc    55.  0.100 / 55.  0.100
  • 11 - On déplace maintenant le contenu fraîchement extrait dans le répertoire parent (/usr/local/bin/ffmpeg) mv * ../
  • 12 - Pis on termine en créant un lien symbolique afin de pouvoir exécuter ffmpeg depuis n'importe où :
ln -s /usr/local/bin/ffmpeg/ffmpeg /usr/bin/ffmpeg
ln -s /usr/local/bin/ffmpeg/ffprobe /usr/bin/ffprobe #for ffprobe

Voilà c'est installé ! pas besoin de faire le ménage, pour mettre à jour il faudra recommencer l'opération et par la même occasion supprimer le contenu du répertoire. Passons à la suite.

Utilisation / Stabilisation

C'est parti ! passons aux choses sérieuses en stabilisant ENFIN notre vidéo renversante grâce à FFmpeg et à sa librairie VidStab. Rien de bien sorcier, il suffit d'exécuter deux commandes (pour deux pass) pour faire ça propre OU seulement une ..mais bon.. c'est pas recommandée, ça fait moins joli.

la méthode de cochon (1 pass)

Si jamais tel est votre désir, il suffit de taper cette commande en prenant soin d'indiquer le fichier original. Vous obtiendrez alors sans outre forme de procès, une version stabilisée de votre vidéo, plus rapidement mais dont le fichier original n'aura pas été pré-analysé.

  • ffmpeg -i input.mp4 -vf vidstabtransform,unsharp=5:5:0.8:3:3:0.4 output.mp4

Un boulot de sagouin vous dis-je.

La bonne méthode (2 pass)

J'insiste, si vous souhaitez bien faire les choses, mieux vaut tout d'abord lancer une analyse détaillée de votre fichier original (première pass), pour après seulement stabiliser votre vidéo en prenant pour réfèrence un fichier baptisé transform.trf, généré lors de la première analyse (seconde pass).

Voyons donc la méthode optimum qui nous permettra d'avoir un bon rendu !

  • Pass 1 - Pour analyser une vidéo avec ffmpeg/vidstab, on utilise la valeur vidstabdetect qui nous permettra d'obtenir un fichier d'analyse. Par défaut : ffmpeg -i input.mp4 -vf vidstabdetect -f null -

  • Pass 2 - Une fois la première pass terminée et notre fichier transform.trf obtenu, il ne nous reste plus qu'à lancer la stabilisation à proprement parler : ffmpeg -i input.mp4 -vf vidstabtransform=input="transforms.trf" output.mp4

Voilà le type de résultat que vous pourriez obtenir grâce à FFmpeg/Vidstab (l'exemple n'est pas de moi).

Voilà Ca a été long mais vous avez dorénavant une vidéo stabilisée correctement. Les commandes ci-dessus ont été exécutées avec les valeurs par défaut (nous n'en avons indiquée aucune). Entrons maintenant dans le détail.

Détails

Nous allons aborder succinctement le sujet en voyant des cas de figures typiques et les réglages possibles qu'il est toujours bon de connaître. Je vous invite à consulter ces documentations qui sauront vous rendre heureux et vous renseigneront d'autant plus : GeorgMartius / vid.stab et ffmpeg.org.

Les réglages par défaut font l'affaire dans la majorité des cas, si votre vidéo est correcte, ni trop mouvementée.

Mais si jamais l'envie vous prend de bidouiller un peu plus et que vous souhaitiez améliorer le rendu final, il peut être intéressant d'approfondir un peu plus encore. Typiquement face à une vidéo particulièrement instable vous pourriez indiquer des valeurs spécifiques en insistant sur les tremblements (shakiness) ou sur la précision (accuracy), le zoom, etc.

Les principales valeurs sur lesquelles vous allez intervenir, dans la première et la seconde pass, seront probablement:

Vidstabdetect (pass 1/2)

  • shakiness - le degré de tremblement de la vidéo et la rapidité de la caméra. Il accepte un nombre entier compris entre 1 et 10, une valeur de 1 signifie peu de tremblements, une valeur de 10 signifie un fort tremblement. La valeur par défaut est 5.
  • accuracy - la précision du processus de détection. Ce doit être une valeur comprise entre 1 et 15. Une valeur de 1 signifie une faible précision, une valeur de 15 signifie une précision élevée. La valeur par défaut est 15.

Vidstabtransform (pass 2/2)

  • smoothing - le nombre d'images (valeur * 2 + 1) utilisées pour le filtrage lowpass des mouvements de la caméra. La valeur par défaut est 10. Un nombre de 10 signifie que 21 images sont utilisées (10 dans le passé et 10 dans le futur) pour lisser le mouvement dans la vidéo. Une valeur plus élevée conduit à une vidéo plus fluide, mais limite l'accélération de la caméra (mouvements de panoramique / inclinaison). 0 est un cas spécial où une caméra statique est simulée.
  • crop - le rognage des bordures a appliqué selon la compensation des mouvements. Les valeurs disponibles sont keep pour conserver les informations de l'image précédente (par défaut) et black remplir la bordure de noir.
  • zoom - le pourcentage à zoomer. Une valeur positive entraînera un effet de zoom, une valeur négative un effet de zoom arrière. La valeur par défaut est 0 (pas de zoom).

Exemples

Allez, je vous gratifie de quelques commandes de réglages qui vous seront utiles selon le cas de figure. Je n'invente rien, c'est quoi il est écrit sur la doc.

Bien évidemment ces exemples n'ont pour fonction que de vous aiguiller, il vous appartient de les tester et d'adapter en conséquence afin d'obtenir un rendu qui vous convient.

Vidéo moyennement instable

  • Analyse d'une vidéo moyennement instable - ffmpeg -i input.mp4 -vf vidstabdetect=shakiness=5:accuracy=7:show=1 output.mp4
  • Et on stabilise en adoucissant/zoomant un poil - ffmpeg -i input.mp4 -vf vidstabtransform=smoothing=15:zoom=1:input="transforms.trf" output.mp4

Vidéo très instable

  • Analyse d'une vidéo particulièrement instable - vidstabdetect=shakiness=10:accuracy=15:result="mytransforms.trf"
  • On peut rectifier le tir en adoucissant le rendu et en le rognant/zoomant un tant soi peu - ffmpeg -i input.mp4 -vf vidstabtransform=smoothing=30:zoom=1:input="transforms.trf" output.mp4

Conclusion

Ce n'est pas magique.
Stabiliser en post-prod une vidéo ne sera pas totalement transparent, des déformations, des coupes, seront engendrées et ne remplacera jamais un stabilisateur physique lors de la prise de vue mais fera un très bon complément à celui-ci.
Quoiqu'il en soit, au vu des autres solutions existantes, avec FFmpeg et VidStab vous êtes certains d'obtenir des résultats très satisfaisants.

Sources