YouTube に動画をアップしたい。でも背景に通行人の顔、駐車中の車のナンバープレート、玄関先の表札が映り込んでいる——。SNS時代のいま、動画の特定エリアだけにモザイク・ぼかしをかけるスキルはプライバシー保護の必須技術です。本記事では FFmpeg だけで「顔」「ナンバープレート」「個人情報」を確実に隠す手順を、静止領域から動く対象まで段階的に解説します。
この記事でわかること
- モザイク(ピクセル化)と各種ぼかしフィルタの違いと使い分け
- 静止した1領域にモザイク・ぼかしをかける
crop+overlayサンドイッチパターン - 複数の領域を同時に隠す方法
- 時間で領域が動く場合の
tベースの式・キーフレーム処理 - 特定の時間範囲だけぼかす
enable='between(t,...)'の書き方 - 顔の自動追跡が必要な場合の OpenCV ワークフロー
- 出力品質を保つコツと典型的なトラブルの対処
テスト済みバージョン: FFmpeg 8.1
対象 OS: Windows / macOS / Linux
モザイクとぼかしの違い — どちらを選ぶか
「モザイク」「ぼかし」はよく混同されますが、技術的には別物です。プライバシーの強度・ファイルサイズ・見た目で選び分けます。
| 手法 | 仕組み | プライバシー強度 | 処理速度 | 見た目 |
|---|---|---|---|---|
| モザイク(ピクセル化) | scale で縮小→拡大、または pixelize | 強い(情報量を完全破壊) | 高速 | カクカクしたブロック |
| boxblur | 矩形カーネルの平均化 | 中(強度次第) | 最速 | 均一なソフトフォーカス |
| gblur | ガウシアン分布のぼかし | 中(強度次第) | やや遅い | 自然で滑らか |
| avgblur | 単純な平均化 | 中 | 速い | やや粗い |
プライバシー観点の目安:
- 顔・ナンバープレート・住所など「絶対に復元されたくない情報」→ モザイク(強めのピクセル化)
- 背景の人影・小物などの「見た目のため隠せばいい情報」→ ぼかし(boxblur / gblur)
弱いぼかしは AI による超解像で部分的に復元される可能性があります。本気で隠すならピクセルブロックを大きく取るのが鉄則です。
静止した1領域にモザイクをかける(ピクセル化)
最も需要が高いユースケース。映像内の固定位置にある顔やナンバーをブロック化します。
scale でダウンスケール→アップスケールする方法
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=80:60:100:80,scale=10:8,scale=80:60:flags=neighbor[fg];[0:v][fg]overlay=100:80[out]" -map "[out]" output.mp4
仕組みを分解すると次のとおりです。
crop=80:60:100:80— 元映像から幅80・高さ60、座標(100,80)の領域を切り出すscale=10:8— その切り出しを 10×8 まで縮小(情報量を破壊)scale=80:60:flags=neighbor— 元のサイズに最近傍補間で戻す(ブロックがクッキリする)overlay=100:80— 元映像の同じ位置に重ねる
ピクセルブロックを大きくしたいときは scale=5:4 のようにさらに小さくします。ブロックが大きいほど情報の復元は不可能になります。
pixelize フィルタを使う方法(FFmpeg 5.1+)
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=80:60:100:80,pixelize=w=10:h=10[fg];[0:v][fg]overlay=100:80[out]" -map "[out]" output.mp4
pixelize はモザイク専用フィルタで、w と h でブロックサイズを直感的に指定できます。
静止した1領域に gblur でぼかしをかける
ぼかしの王道。柔らかく自然な仕上がりになり、配信向けの動画におすすめです。
crop + overlay サンドイッチパターン
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=80:60:100:80,gblur=sigma=20[fg];[0:v][fg]overlay=100:80[out]" -map "[out]" output.mp4
ここで使われている「サンドイッチパターン」を視覚的に表すと次のとおりです。
元映像 [0:v]
│
├─────────────► そのまま下地に使う
│
└─► crop ─► gblur ─► [fg] ──┐
▼
overlay で同じ座標に重ねる
│
▼
[out] 出力
ポイントは、入力は1本のまま で [0:v] を分岐して使えること。split を使った別解もありますが、Filtergraph 内で [0:v] を複数回参照する書き方が最もシンプルです。
boxblur を使った高速版
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=80:60:100:80,boxblur=10[fg];[0:v][fg]overlay=100:80[out]" -map "[out]" output.mp4
CPU 負荷を抑えたいバッチ処理では boxblur が有利です。ぼかし強度の比較は boxblurフィルタの記事 で詳しく扱っています。
複数の領域を同時に隠す
複数人の顔や複数台の車を一度に処理するには、overlay を連結します。
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=60:50:40:40,boxblur=10[a];[0:v][a]overlay=40:40[v1];[0:v]crop=60:50:200:140,boxblur=10[b];[v1][b]overlay=200:140[out]" -map "[out]" output.mp4
処理の流れは次のとおりです。
- 領域A(左上)を
crop→ ぼかし →overlayで重ねた中間結果[v1] - 領域B(右下)を
crop→ ぼかし →[v1]の上にさらにoverlay - 最終出力
[out]
領域は3個・4個と増やせます。[v1]→[v2]→[v3]→...→[out] と中間ラベルを増やしていくだけです。
時間で領域が動く場合の対処
人物や車が映像内を移動するとき、固定領域では追従できません。t(秒)を含む式で位置を時間変化させます。
一定速度で水平移動する場合
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=60:50:40+t*5:40,boxblur=10[fg];[0:v][fg]overlay=40+t*5:40[out]" -map "[out]" output.mp4
40+t*5 は「初期 X 座標 40、毎秒 5 ピクセル右へ移動」を意味します。crop と overlay の式を必ず一致させるのがコツ。
キーフレーム的に位置を切り替える
5秒目で位置が大きく動く場合:
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=60:50:if(lt(t\,5)\,40\,150):40,boxblur=10[fg];[0:v][fg]overlay=if(lt(t\,5)\,40\,150):40[out]" -map "[out]" output.mp4
if(lt(t,5),40,150) は「t<5 なら 40、それ以外なら 150」。3区間以上は if(lt(t,2),A,if(lt(t,5),B,C)) のように入れ子にします。Filter 内では , を \, でエスケープしてください。
顔を自動で追跡してぼかすには
FFmpeg 単体では顔検出はできません。動く顔を自動で追従するには次のワークフローが必要です。
- OpenCV / dlib / MediaPipe で顔検出 — Python で各フレームの顔バウンディングボックスを抽出し、
(frame, x, y, w, h)を CSV に書き出す - 検出結果を
tベースの式に変換 — 短い区間ごとにif(between(t,a,b),x1,...)を生成 - FFmpeg で適用 — 上記「キーフレーム的に位置を切り替える」と同じ書式
シンプルな自動化スクリプトの例(擬似コード):
# OpenCV で顔検出 → FFmpeg コマンド生成
import cv2
cap = cv2.VideoCapture("input.mp4")
detector = cv2.CascadeClassifier(cv2.data.haarcascades + "haarcascade_frontalface_default.xml")
boxes = [] # (time, x, y, w, h)
fps = cap.get(cv2.CAP_PROP_FPS)
i = 0
while True:
ok, frame = cap.read()
if not ok: break
faces = detector.detectMultiScale(frame, 1.3, 5)
if len(faces):
x, y, w, h = faces[0]
boxes.append((i/fps, x, y, w, h))
i += 1
# boxes から FFmpeg の if() 式を生成して -filter_complex に渡す
商用品質を求めるなら、より頑健なモデル(YOLOv8、MediaPipe Face Detection)の使用を推奨します。
特定の時間範囲だけぼかす
「3秒目から7秒目だけぼかす」など、時間制限つきの適用は enable 式で行います。
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=60:50:40:40,boxblur=10[fg];[0:v][fg]overlay=x=40:y=40:enable='between(t,2,5)'[out]" -map "[out]" output.mp4
between(t,2,5)— 2秒〜5秒の間だけoverlayを有効化- それ以外の時間は元映像がそのまま出る
複数区間にしたいなら enable='between(t,2,5)+between(t,10,12)' のように +(OR)で連結できます。
出力品質を保つコツ
ぼかし処理は計算負荷が大きく、デフォルト設定だと画質劣化やバンディングが出やすい点に注意。
CRF を低めに設定する
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=80:60:100:80,boxblur=10[fg];[0:v][fg]overlay=100:80[out]" -map "[out]" -c:v libx264 -crf 18 -pix_fmt yuv420p output.mp4
-crf 18 は視覚的にロスレスに近い品質です(デフォルトは 23)。ぼかしを安定させるには 18〜20 が安全圏。
色空間を明示する
-pix_fmt yuv420p
を必ず付けると、再生互換性と色再現の安定が両立します。10bit ソースなら -pix_fmt yuv420p10le を選択。
トラブルシューティング
出力が真っ黒になる
原因: -map "[out]" を指定していない、もしくは Filtergraph のラベル名がタイポしている。
# 間違い
ffmpeg -i input.mp4 -filter_complex "[0:v]crop=80:60:100:80,boxblur=10[fg];[0:v][fg]overlay=100:80[result]" output.mp4
最後のラベル [result] を -map で参照しないと、FFmpeg はデフォルトで [0:v] を出してしまい、ぼかしが反映されない(あるいはサイズ不一致で真っ黒)状態になります。必ず -map "[out]" を入れる。
crop の領域がはみ出してエラー
crop=W:H:X:Y で X+W > 入力幅 または Y+H > 入力高さ だと “Invalid too big or non positive size” エラーになります。ffprobe -i input.mp4 で解像度を確認してから座標を決めましょう。
処理が極端に遅い
gblurのsigmaが大きすぎる(30 以上)と CPU 負荷が跳ね上がります。boxblurに置き換えるかsigma=10前後に抑える- 4K 動画では crop 領域も 4K スケールで考える必要があります(faces なら 200〜400 px 程度が現実的)
色がわずかに変わる
ぼかしフィルタは内部で色空間変換が入る場合があります。気になるなら入力前に -vf "format=yuv420p" を chain の前段に挟むと安定します。
比較早見表 — どのフィルタを選ぶ?
| フィルタ | 強度の指定 | 処理速度 | 復元耐性 | 推奨用途 |
|---|---|---|---|---|
scale,scale (モザイク) | 縮小サイズ | 最速 | 強(ブロックが大きいほど) | 顔・ナンバープレート |
pixelize | w, h | 最速 | 強 | 顔・ナンバープレート |
boxblur | luma_radius:luma_power | 速い | 中 | 背景・小物・量産処理 |
gblur | sigma | やや遅い | 中 | 配信品質・自然な仕上がり |
avgblur | カーネルサイズ | 速い | 中 | 軽量バッチ |
よくある質問
Q1. ぼかしが弱い/強くしたい
boxblur は boxblur=20:3 のように半径と繰り返し回数を上げます。gblur は gblur=sigma=30 のように sigma を増やします。ピクセル化なら縮小サイズを 5×4 など極小にするのが最強。
Q2. モザイクで個人情報は完全に隠せる?
ピクセルブロックが十分大きければ実質的に復元不能です。逆に弱いぼかしは AI 超解像で部分復元される事例があります。重要情報は「モザイク + ブロックサイズを大きく」が鉄則。文字情報(住所、電話番号)は黒矩形で完全に塗りつぶす(drawbox フィルタ)方が安全な場合もあります。
Q3. 領域が動く対象(人物・車)を追跡したい
FFmpeg 単体では追跡不可。OpenCV / MediaPipe / YOLO で各フレームの座標を取得し、本記事の「キーフレーム的に位置を切り替える」式に流し込む方式が一般的です。Python で前処理 → FFmpeg で本処理、というパイプラインを組みます。
Q4. 出力が真っ黒になる
-map "[out]" の指定漏れがほぼ全てです。-filter_complex を使った場合は明示的に出力ラベルを -map で指定する必要があります。
Q5. 1フレームだけぼかしたい
enable='between(n,30,30)' のように n(フレーム番号)を使います。秒単位なら enable='between(t,1.0,1.04)'(30fps なら約1フレーム)。1フレームだけのぼかしはサムネイル流用などで需要があります。
Q6. 処理した動画から元の領域を復元できる?
モザイク・ぼかしは情報を破壊する処理なので、元の動画ファイルが残っていない限り復元はできません(弱いぼかしは AI で推測復元される可能性あり)。逆に「間違えて全体にぼかしをかけてしまった」場合は、unsharp でわずかに鋭くできても完全復元は不可能です。原本のバックアップは必ず保管しましょう。
関連記事
- boxblurフィルタでボックスブラーをかける — 全体ぼかしの基礎
- drawboxフィルタで矩形を描画する — ナンバープレートを完全塗りつぶし
- overlayでウォーターマークを合成する — overlay の基礎
- crop で動画をトリミングする — crop 構文の詳細
Tested with ffmpeg 8.1 / Windows 11
Primary source: ffmpeg.org/ffmpeg-filters.html#boxblur