FFmpeg の vidstab を使うと、三脚なしの手持ち撮影や歩きながら撮った動画の手ブレを補正できます。まず映像を解析して揺れを検出し(vidstabdetect)、その結果をもとに揺れを打ち消す(vidstabtransform)2パス方式です。
前提条件:
vidstabdetectとvidstabtransformフィルターを使うには、FFmpegが--enable-libvidstab付きでビルドされている必要があります。Ubuntu / Debian のapt install ffmpegは条件を満たします(詳細はインストール)。まずffmpeg -filters | grep vidstabで確認してください。
動画手ブレ補正の仕組み
FFmpegの動画手ブレ補正は外部ライブラリlibvidstabに依存し、2つのフィルターを使用します:
vidstabdetect(パス1):動画のカメラの動きを分析し、モーションベクターファイル(デフォルト:transforms.trf)に書き出すvidstabtransform(パス2):モーションデータを読み込み、揺れを打ち消す変換(平行移動・回転)を適用する
2パス方式が必要なのは、滑らかなカメラの動きを計算するために、動き全体の軌跡を事前に把握しておく必要があるからです。
基本的な2パス手ブレ補正
注意: このセクションのFFmpegコマンドはすべて
--enable-libvidstabが必要です。
パス1(モーション検出):
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf vidstabdetect -f null /dev/null
カレントディレクトリにtransforms.trfが書き出されます。
パス2(手ブレ補正):
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf vidstabtransform output.mp4
transforms.trfを読み込み、安定化された動画を生成します。
補正強度の調整
パス1:shakiness
shakinessパラメータ(1〜10、デフォルト: 5)で、検出の強さを調整します。揺れが激しい映像では値を上げます:
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabdetect=shakiness=8:accuracy=15" -f null /dev/null
| パラメータ | 範囲 | デフォルト | 説明 |
|---|---|---|---|
shakiness |
1〜10 | 5 | 検出する動きの範囲 |
accuracy |
1〜15 | 15 | 検出精度(高いほど遅い) |
result |
パス | transforms.trf |
モーションファイルの出力先 |
パス2:smoothingとcrop
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabtransform=smoothing=30:crop=black" output.mp4
| パラメータ | デフォルト | 説明 |
|---|---|---|
smoothing |
15 | 時間的平滑化半径(フレーム数)。高いほど滑らかだが補正量が増える(既定の optzoom=1 では自動の拡大が大きくなり、optzoom=0 では縁が広くなる) |
crop |
keep |
安定化の境界処理: keep(前フレームの情報で縁を埋める/既定)または black(黒で塗りつぶす) |
zoom |
0 | 追加ズーム率(%)。正で拡大、負で縮小 |
optzoom |
1 | 自動ズーム: 0=しない / 1=静的に最適化(既定) / 2=動的に最適化 |
interpol |
bilinear |
補間方法: no・linear・bilinear・bicubic |
cropの既定値はblackではなくkeepです。 省略すると黒枠ではなく、前フレームの映像で縁が埋められます(残像状に見えます)。黒枠にしたい場合は明示的にcrop=blackを指定してください。ffmpeg -h filter=vidstabtransformで(default keep)と確認できます。
ズームで黒枠を隠す
手ブレ補正はカメラの動きを打ち消すためにフレームをずらすので、端に黒枠が出ることがあります。既定の optzoom=1 では、vidstabtransform が自動で少し拡大して黒枠を隠します(黒枠が見えるのは、とても大きな動きのときだけです)。zoom を指定すると、その上にさらに拡大を足せます:
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabtransform=smoothing=20:zoom=5:crop=black" output.mp4
zoom=5は、自動の拡大に5%を上乗せし、残った黒枠をさらに隠します。そのぶん、写る範囲がもう少し狭くなります。
カスタムパスを使った完全なパイプライン
スクリプトや複数ファイルを処理する場合、モーションファイルのパスを明示的に指定します:
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabdetect=result=/tmp/transforms.trf" -f null /dev/null
# requires --enable-libvidstab
ffmpeg -i input.mp4 -vf "vidstabtransform=input=/tmp/transforms.trf:smoothing=20" output.mp4
インストール
Ubuntu / Debian
標準リポジトリの ffmpeg パッケージで動きます。 PPAも自前ビルドも不要です。
sudo apt install ffmpeg
GitHub Actions の Ubuntu ランナーで apt-get install ffmpeg を実行すると、apt が libvidstab1.1 を依存パッケージとして一緒にインストールします。ログの該当行は次のとおりです。
Unpacking libvidstab1.1:amd64 (1.1.0-2build1) ...
インストールされた FFmpeg のビルド設定にも含まれています。次は ffmpeg -version の configuration: 行から、連続する3項目を抜き出したものです。
--enable-libvidstab --enable-libvorbis --enable-libvpx
自分の環境では、次のコマンドで同じ確認ができます。
ffmpeg -version | grep -o -- "--enable-libvidstab"
「Ubuntu の apt 版には libvidstab が入っていない」という説明を見かけますが、少なくとも 6.1.1-3ubuntu5 では誤りです。上の --enable-libvidstab の行は、Ubuntu 24.04 での実行ログからそのまま引用したものです。最終的には ffmpeg -filters | grep vidstab で自分の環境を確認するのが確実です。
libvidstab が含まれていない古いビルドを使っている場合は、libvidstab-dev を入れた上で --enable-libvidstab を付けて自分でビルドするか、静的ビルド(BtbN/FFmpeg-Builds)を使ってください。sudo apt install libvidstab-dev だけでは解決しません。 ライブラリの開発用ヘッダを入れるだけで、ビルド済みのFFmpegバイナリには影響しないためです。
macOS(Homebrew)
brew install ffmpeg-full
Homebrew の ffmpeg フォーミュラには libvidstab が入っていません。入っているのは ffmpeg-full です。ffmpeg-full は keg-only なので、brew info ffmpeg-full の案内どおりに PATH に追加してから、ffmpeg -filters | grep vidstabで確認してください。
Windows
gyan.dev/ffmpeg/buildsから“full”ビルドをダウンロードしてください。libvidstabが含まれています。
ビルドの確認方法
ffmpeg -filters 2>/dev/null | grep vidstab
出力にvidstabdetectとvidstabtransformが表示されれば、手ブレ補正を使えます。
制限事項
- libvidstabは中程度の手ブレに向いています。 極端な手ブレ(走りながら撮影した映像など)では、映像のゆがみや補正不足が起きることがあります。
- vidstab では2パスが必須です。 vidstab にシングルパスのモードはありません(1パスで補正する
deshakeフィルタは別にあります)。 - ズームで画像領域が縮小します。 補正量が多いほど黒枠を隠すために必要なズームが大きくなり、フレームがクロップされます。
関連記事
よくある質問
vidstabdetect と vidstabtransform は両方必要?
はい。2段階の処理です。1段目(detect)で動画を解析し、モーションデータ transforms.trf を生成します。2段目(transform)で、そのデータをもとに手ブレを補正します。
スマホで撮った揺れた動画も補正できる?
できます。vidstabdetect=shakiness=8 のように shakiness を上げると激しいブレも拾えます(accuracy は既定値の15がすでに最大です)。ただし揺れが極端だと縁の破綻が目立つので、vidstabtransform=zoom=5:crop=black のように数%ズームして縁を隠すのが一般的です。crop は keep か black の2択で、ピクセル数は指定できません(縁を数値で切り落としたい場合は、別の crop フィルタを後ろにつなぎます)。
vidstab で出力すると映像が小さくなる
補正で画面端に発生する破綻を避けるため、optzoom=1(既定)が自動的にやや拡大しています。拡大を止めるには zoom=0 ではなく optzoom=0 を指定してください(zoom の既定値はもともと 0 なので、zoom=0 を書いても何も変わりません)。拡大を止めると縁の処理は crop の設定次第になります。
リアルタイムで安定化したい
vidstab は事前の解析が必須なので、リアルタイムでは使えません。リアルタイムで手ブレを補正するには deshake フィルタを使います(精度は劣りますが、1パスで済みます)。
安定化後の動画を更に補正したい
可能ですが、補正を重ねるほど劣化が増えます。元の動画に1度だけ vidstab をかけるのが理想です。補正済みの動画にもう一度かける場合は、vidstabdetect=shakiness=2:accuracy=5 のように軽めに設定してください。