ffmpeg には標準でロゴを消すフィルタがあるが、以前紹介した特定の場所にだけフィルタを当てる方法と、ロゴ消しに適したロゴデータの作り方を交えてロゴをきれいに消す方法。
ffmpeg でロゴを消すフィルタと言えば、removelogo
とdelogo
があるが、ロゴデータを元にロゴを消すのがremovelogo
で、座標を指定して周りの色でブレンドするのがdelogo
である。
ロゴ画像を用意する
最終的にロゴを消す映像と同じ解像度で同じ位置にある白黒のロゴデータを用意してremovelogo
でロゴを消す。ロゴの色は白でロゴ以外の背景は黒にするときれいにロゴが消える。このロゴをきれいに作ることでremovelogo
だけできれいにロゴを消すことができる。
ロゴ画像を動画から探すにはblackframe
フィルタでフレーム単位で見つけることができる。crop
して画面の対象範囲を小さくすれば処理速度を上げられるが、小さすぎても精度が悪くなるので4分の1程度とする。今回はインターレース素材の 1920×1080 30000/1001fps で本編は 24000/1001fps の動画とする。
blackframe
を使うと動画によっては候補が数千にも及ぶが区間の最初と最後の I-frame を除いた I-frame を候補として、全ての画像を出力したものから一番容量の少ないのを使うのが自動処理では一番きれいなロゴ画像が作れる。一般的には
blackframe
で連続したキーフレーム区間のほうがきれいになる。field
フィルタを使うことで片フィールドを対象とし-skip_frame nokeyでキーフレームだけを取得し、crop
フィルタも併用することで処理速度を上げている。
ffmpeg -skip_frame nokey -i input -an -vf field=0,crop=iw/2:ih/2:iw/2:0,blackframe=amount=99 -f null - > logo.txt 2>&1
logo.txt から読み込み開始時点を調べる。ここでロゴ座標をcrop
で指定する。AviSynth や AviUtl で使われているロゴデータを持っている人ならその座標を参考にしてもよい。
ffmpeg それ自体では座標を知ることは難しそうなのでここは目視をするか、放送局ごとに予めデータがあるとよい。
<seconds> には logo.txt に書いてある PTS時間を指定する。crop
の最初の2つの引数が画像の解像度、3、4番目の引数がロゴ座標の左上を 0 とする縦軸・横軸の座標指定。format
フィルタでグレースケール変換して処理を簡略する。
ffmpeg -ss <seconds> -i input -vf yadif=0:-1:1,decimate,setpts=N/(24000/1001)/TB,crop=160:48:1700:30,format=gray -vframes 1 logo.png
ロゴ画像が出来たらremovelogo
で使うロゴ画像をpad
フィルタで黒い余白を追加する。removelogo
はビットマップ形式(.bmp 以外に .png や .tiff も可能)で出力する。
座標を求めない場合
上で調べた一番容量の少ない logo.png のPTS時間を指定する。
ffmpeg -ss <seconds> -i input -vf yadif=0:-1:1,decimate,setpts=N/(24000/1001)/TB,lutrgb=r=between(val,11,255)*val:g=between(val,11,255)*val:b=between(val,11,255)*val,colorchannelmixer=1.25:1.25:1.25:0:1.25:1.25:1.25:0:1.25:1.25:1.25:0,format=gray -vframes 1 logo.bmp
logo.bmp を元に ffplay で表示確認する。
ffplay -i input -vf yadif=0:-1:1,decimate,setpts=N/(24000/1001)/TB,removelogo=logo.bmp
座標を求める場合
lutrgb
で真っ黒になっていない微妙な部分を修正して、colorchannelmixer
フィルタでロゴを真っ白(最大値255)に色を変え、pad
はcrop
と同じように最初の2つの引数が画像の解像度、3、4番目の引数がロゴ座標の左上を 0 とする縦軸・横軸の座標指定で余白をつける。
NHK総合
crop=91:38:1273:84 pad=1440:1080:1273:84
BSプレミアム(きれいに消えない)
crop=66:61:1740:37 pad=1920:1080:1740:37
BS11
crop=128:60:1675:51 pad=1920:1080:1675:51
WOWOW
crop=154:42:1702:34 pad=1920:1080:1702:34
ロゴ画像を調整するには RGB の各値の10以下を一律に 0 に調整し、colorchannelmixer
で一番明るい部分が 255 になりエッジ部分がうまくグラデーションするように調整する。
ffmpeg -i logo.png -vf lutrgb=r=between(val\,11\,255)*val:g=between(val\,11\,255)*val:b=between(val\,11\,255)*val,colorchannelmixer=1.25:1.25:1.25:0:1.25:1.25:1.25:0:1.25:1.25:1.25:0,pad=1920:1080:1700:30,format=gray logo.bmp
removelogo
に弱点があるとしたら急激な明暗の反転シーンや、ロゴ周辺で輝度が急激に変わっているところ、シーンチェンジでロゴ自体が不明確またはノイズが乗っているところなどでロゴの輪郭が少し残る。
ffplay -i input -vf yadif=0:-1:1,decimate,setpts=N/(24000/1001)/TB,removelogo=logo.bmp
ロゴ部分にunsharp
を使ってぼかすこともできる。
ffmpeg -i input -loop 1 -i logo.png -filter_complex [0:0]yadif=0:-1:1,decimate,setpts=N/(24000/1001)/TB,removelogo=logo.bmp,split[a][b];[a]crop=160:48:1700:30,unsharp=5:5:-1.5:5:5:0.0[a0];[a0][1:0]alphamerge[a1];[b][a1]overlay=1700:30 output
ffmpeg -i input -loop 1 -i logo.png -filter_complex [0:0]yadif=0:-1:1,decimate,setpts=N/(24000/1001)/TB,removelogo=logo.bmp,split[a][b];[a]crop=160:48:1700:30,unsharp=5:5:-1.5:5:5:0.0[a0];[a0][1:0]alphamerge[a1];[b][a1]overlay=1700:30 -f sdl -
明るいところ、暗いところにフィルタを当てる
別ファイルの情報から元映像を透過させる alphamerge
使ったフィルタの公式ドキュメント
- FFmpeg Filters Documentation : removelogo
- FFmpeg Filters Documentation : blackframe
- FFmpeg Filters Documentation : yadif
- FFmpeg Filters Documentation : decimate
- FFmpeg Filters Documentation : field
- FFmpeg Filters Documentation : format
- FFmpeg Filters Documentation : crop
- FFmpeg Filters Documentation : lutrgb
- FFmpeg Filters Documentation : colorchannelmixer
- FFmpeg Filters Documentation : unsharp
ブログで取り上げたフィルタ
- RGBA の各値を別のチャンネルに混ぜ合わせる colorchannelmixer の使い方
- 映像を指定座標に切り取る crop
- Windows の ffmpeg で生放送する方法 : decimate
- 輪郭を保護しながらシャープにしたりぼかしたりする unsharp
インタレ解除はこちら:ffmpeg でインターレース解除
.lgd ファイルを編集して ffmpeg 用のロゴデータを作る
Windows 用の lgdeditor を使って ffmpeg 用のロゴデータを作る。まずメモ置き場 lgdeditor ver0.1.0.3から ver0.1.0.4 を保存し、.lgd ファイルを開き、ロゴの上で右クリックから「画像をクリップボードでコピー(B)」して Paint などで開き、logo.png のように保存する。あとは lgdeditor で表示されている座標をoverlay
フィルタの横と縦の座標に指定すればロゴ画像を作れる。
.lgd ファイルが 1920×1080 のコマンド例。リサイズ方法や出力フォーマットによる品質の差違は未確認。
ffmpeg -f lavfi -i color=s=1920x1080:d=1,format=rgb24 -i logo.png -filter_complex overlay=1691:27:format=rgb -vframes 1 name-1920.bmp
ffmpeg -f lavfi -i color=s=1920x1080:d=1,format=rgb24 -i logo.png -filter_complex overlay=1691:27:format=rgb,scale=1440x1080 -vframes 1 name-1440.bmp
ffmpeg -f lavfi -i color=s=1920x1080:d=1,format=gbrp -i logo.png -filter_complex overlay=1691:27:format=gbrp,zscale=1440x1080 -vframes 1 name-1440.bmp
フィルタ別の出力サンプル画像
removelogo
はロゴ周辺の色の変化が少ない場面はきれいに消えるので、そうではないロゴがきれいに消えていない場面での出力比較。