ffmpeg には標準でロゴを消すフィルタがあるが、以前紹介した特定の場所にだけフィルタを当てる方法と、ロゴ消しに適したロゴデータの作り方を交えてロゴをきれいに消す方法。

ffmpeg でロゴを消すフィルタと言えば、removelogodelogo があるが、ロゴデータを元にロゴを消すのが removelogo で、座標を指定して周りの色でブレンドするのが delogo である。

ロゴ画像を用意する

最終的にロゴを消す映像と同じ解像度で同じ位置にある白黒のロゴデータを用意して removelogo でロゴを消す。ロゴの色は白でロゴ以外の背景は黒にするときれいにロゴが消える。このロゴをきれいに作ることで removelogo だけできれいにロゴを消すことができる。

ロゴ画像を動画から探すには blackframe フィルタでフレーム単位で見つけることができる。crop して画面の対象範囲を小さくすれば処理速度を上げられるが、小さすぎても精度が悪くなるので4分の1程度とする。今回はインターレース素材の 1920×1080, 30000/1001 fps で本編は 24000/1001 fps の動画とする。

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番目の引数がロゴ座標のオフセット。format でグレースケール変換して処理を簡略する。
ffmpeg -ss <seconds> -i input -vf yadif=0:-1:1,decimate,crop=160:48:1700:30,format=gray -vframes 1 logo.png

ロゴ画像が出来たら removelogo で使うロゴ画像を pad で黒い余白を追加する。removelogo は .bmp 形式限定なのでそれで出力し、フォーマットは gray にしたほうが容量は小さくなる。

座標を求めない場合

一番容量の少ない logo.png の PTS時間を指定する
ffmpeg -ss <seconds> -i input -vf yadif=0:-1:1,decimate,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

座標を求める場合

lutrgb で真っ黒になっていない微妙な部分を修正して、colorchannelmixer でロゴを真っ白(最大値255)に色を変え、padcrop と同じように最初の2つの引数が画像の解像度、3,4番目の引数がロゴ座標のオフセットで余白をつける。

NHK総合の場合

crop=91:38:1273:84
pad=1440:1080:1273:84

ロゴ画像を調整するには 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 -y logo.bmp

removelogo に弱点があるとしたら急激な明暗の反転シーンや、ロゴ周辺で輝度が急激に変わっているところ、シーンチェンジでロゴ自体が不明確またはノイズが乗っているところなどでロゴの輪郭が少し残る。
ffplay -i input -vf yadif=0:-1:1,decimate,removelogo=logo.bmp

ロゴ部分に unsharp を使ってぼかすこともできる
ffmpeg -i input -loop 1 -i logo.png -filter_complex [0:0]yadif=0:-1:1,decimate,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,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 でインターレース解除

フィルタ別の出力サンプル画像

removelogo はロゴ周辺の色の変化が少ない場面はきれいに消えるので、そうではないロゴがきれいに消えていない場面での出力比較。

オリジナル1

removelogo だけ

removelogo と unsharp

オリジナル2

removelogo だけ

removelogo と unsharp

オリジナル3

removelogo だけ

removelogo と unsharp

修正 2016年10月28日
RGB の10以下の値を修正するようにフィルタチェーンを見直した

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)