FFmpeg の vidstab を使うと、三脚なしの手持ち撮影や歩きながら撮った動画の手ブレを補正できます。まず映像を解析して揺れを検出し(vidstabdetect)、その結果をもとに揺れを打ち消す(vidstabtransform)2パス方式です。


前提条件: vidstabdetectとvidstabtransformフィルターを使うには、FFmpegが--enable-libvidstab付きでビルドされている必要があります。Ubuntu / Debian の apt install ffmpeg は条件を満たします(詳細はインストール)。まず ffmpeg -filters | grep vidstab で確認してください。

動画手ブレ補正の仕組み

FFmpegの動画手ブレ補正は外部ライブラリlibvidstabに依存し、2つのフィルターを使用します:

  1. vidstabdetect(パス1):動画のカメラの動きを分析し、モーションベクターファイル(デフォルト: transforms.trf)に書き出す
  2. 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 のように軽めに設定してください。