フェイクタイムワープワンライナーの解説

はじめに

GoPro HERO7で強化された手ブレ補正機能「タイムワープ」をどうにか後処理で実現できないか?を色々試した結果、何とかモノになったのでYoutubeに公開しました。

ただ、今回のスクリプトは非常に長く使いにくいのでマニュアル未満な解説をしようかと思います。

フェイクタイムワープワンライナー

下記が今回のワンライナーとなります。

ffmpeg -threads 0 -framerate 30 -pattern_type glob -i '*.jpg' -an -s 3820x2160 -an -b 200000k -vcodec libx264 -pix_fmt yuv420p -g 1 -r 60 temp.mp4 && ffmpeg -threads 0 -i temp.mp4 -vf vidstabdetect=shakiness=8:accuracy=15:mincontrast=0.4 -an -f null - && ffmpeg -threads 0 -i temp.mp4 -vf vidstabtransform=input=transforms.trf:smoothing=30:crop=keep:zoom=15:optzoom=1:zoomspeed=5 -an -s 3820x2160 -an -b 200000k -vcodec libx264 -pix_fmt yuv420p -g 1 -r 60 EXPORT_FILENAME.mp4 && rm -rf temp.mp4 && rm -rf transforms.trf

しかし判る人には判ることとして今回のワンライナーは「Bash」向けに書かれたものでWindowsの「cmd」や「PowerShell」ではおそらく上手く動作しません(未検証)。

MacやLinux(とBash環境のあるWindows)では動作するのですが、普通のWindowsでは動作しないのでWindowsで使う場合は3回に分けてスクリプトを実行していくのが確実かと思われます。

それではスクリプトを分解していきましょう。

分解したものを1つ1つ実行していくわけです。

用意するもの

このワンライナーではデジカメで撮影した動画ではなくJPEG画像を”基本的には”使用します。

撮影方法は秒間4〜10枚の連射撮影(今回公開した動画では秒間4枚)を用います。

秒間撮影枚数を増やしたり、ボディもしくはレンズ内手ブレ補正を併用するとよりスムースな映像を得られるでしょう。

JPEG画像から手ブレ補正なしの動画を生成する

このパートではJPEG画像から手ブレ補正なしの動画を取り敢えず生成します。

ffmpeg -threads 0 -framerate 30 -pattern_type glob -i '*.jpg' -an -s 3820x2160 -an -b 200000k -vcodec libx264 -pix_fmt yuv420p -g 1 -r 60 temp.mp4

ちなみにこのパートの動画は下記の仕様で生成されています。

情報 数値
動画形式 H.264
解像度 3820x2160
入力フレームレート 30FPS
音声 なし
ビットレート 200Mbps
GOP フルIフレーム
動画フレームレート 60FPS
コンテナ形式 MP4
ファイル名 temp.mp4

この時点で非常に高い品質を得られて居ますが、(ボディもしくはレンズ内手ブレ補正がなければ)手ブレ補正のないガタガタの動画のままです。

この動画へ対して手ブレ補正処理を適用するこよによってタイムワープのような映像表現を実現します。

Tips FFmpeg以外の手ブレ補正処理

この時点で生成されている動画へ対してFFmpeg以外の手ブレ補正ソフトウェアは利用可能です。

Adobee PremiereやDavinci Resolveなどお気に入りの手ブレ補正を使って下さい。

FFmpeg以外の手ブレ補正ソフトウェア利用する場合は以下の解説は必要ないかも知れません。

Tips PNG画像をソースとする

今回のワンライナーでは'*.jpg'の部分でJPEG画像を指定しています。

例えばRAW現像ソフトウェアでより高画質を狙ってPNG画像を用いる場合は'*.png'と書き換えて下さい。

RAW現像時間が許すのであれば高画質を狙っていくのもアリでしょう。

ちなみにTIFF画像ならば'*.tif'ですしBMP画像ならば'*.bmp'です。

ただし、DNGなどのRAW画像形式には対応して居ないので必ず汎用的な画像形式へ変換して下さい。

Tips 120FPSにする

連射秒間10枚などの超ハイスピードなJPEG画像を用意し、高フレームレートである120FPSが欲しいという要望もあるかと思います。

動画フレームレートは-r 60で指定されていますので、この部分を-r 120にすると120FPSの動画が得られます。

ちなみに連射秒間10枚などの超ハイスピードなJPEG画像が用意できる環境であり、よりスムースな映像が欲しい際は-framerate 30-framerate 60にするとスムースになります。

手ブレ補正のための解析を行なう

解析を行なわなくともFFmpegでは手ブレ補正を適用することは出来ますが、より品質の高い手ブレ補正を適用する場合は解析を行なった方が良いです。

ffmpeg -threads 0 -i temp.mp4 -vf vidstabdetect=shakiness=8:accuracy=15:mincontrast=0.4 -an -f null -

このパートでは上記のスクリプトを実行する以外することがありません。

実行するとtransforms.trfというファイルが生成されると思いますが、これが解析に必要なファイルですので削除しないで下さい。

手ブレ補正を適用する

下記のスクリプトを実行すると手ブレ補正が適用されます。

ffmpeg -threads 0 -i temp.mp4 -vf vidstabtransform=input=transforms.trf:smoothing=30:crop=keep:zoom=15:optzoom=1:zoomspeed=5 -an -s 3820x2160 -an -b 200000k -vcodec libx264 -pix_fmt yuv420p -g 1 -r 60 EXPORT_FILENAME.mp4

上記のスクリプトを実行すると下記の仕様で動画が生成します。

情報 数値
動画形式 H.264
解像度 3820x2160
入力フレームレート 30FPS
音声 なし
ビットレート 200Mbps
GOP フルIフレーム
動画フレームレート 60FPS
クロップ率 15%
コンテナ形式 MP4
ファイル名 EXPORT_FILENAME.mp4

最も注目すべき点はクロップ率15%です。

後処理による手ブレ補正の仕様上どうしてもクロップせざる得ず、タイムワープのようなヌルヌルとした手ブレ補正を実現するには15%ものクロップが必要でした。

しかし、ボディもしくはレンズ内手ブレ補正があればクロップ率を下げることが可能です。

ちなみに動画が生成されればtemp.mp4とtransforms.trfはもう必要ないので削除しても構いません。

Tips クロップ率の変更

クロップ率はzoom=15で指定されています。単位は%です。

ボディもしくはレンズ内手ブレ補正がある環境ではzoom=10にしたりzoom=5にしたりすると良いでしょう。

おわりに

長い記事となりましたが、以上でフェイクタイムワープワンライナーの解説は終わりです。

今後も何か面白い発想が浮かべば色々作っていきたいと思います。

FFmpegの導入方法や解説などはわかりやすいものがネット上にたくさんあるので、解説はそちらにお任せします。