ffmpeg でクロマキー合成


ffmpeg に colorkey フィルタが取り込まれたことにより、クロマキー合成や特定色に個別のフィルタを当てられるようになった。

ffmpeg 2.7.1 以降か master を使っていれば colorkey フィルタが使える。
avfilter/vf_colorkey: Add colorkey video filter

colorkey は指定した色の部分をアルファチャンネルにして、それ以外を RGB の RGBA で出力する。指定する色は16進数の ffffff 形式か、色名を指定する。入力映像が RGB の方が YUV よりも処理が早い。

YUVA で処理する chromakey はこちら:ffmpeg でクロマキー合成 その2

16進数と色の説明:FFmpeg Utilities Documentation :: Color

基本コマンド

ffmpeg -i input -vf colorkey=red:0.01:0 output
ffmpeg -i input -vf colorkey=0xFF0000:0.01:0 output

公式ドキュメント:FFmpeg Filters Documentation : colorkey

オプション内容

  • color[color]
    指定した色を透過させる。16進数形式か、色名を指定
    既定値:black
  • similarity[float]
    一致の範囲指定。0.01 は完全一致、1は全画面。大きい値ほど透過範囲が広く濃くなる。
    範囲:0.01 から 1 まで
    既定値:0.01
  • blend[float]
    似た色の透過の影響具合、0 は指定した色だけで大きくするほど似た色も少しずつ透過する。つまり透過のグラデーションがきれいになる
    範囲:0 から 1 まで
    既定値:0

blend, similarity について

基本画像(赤の右端が少し透過して欠けている)

colorkey=red

ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red -vframes 1 rgbtestsrc.png

colorkey=red:.01:.1

ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:.01:.1 -vframes 1 rgbtestsrc00101.png

colorkey=red:.01:.5

ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:.01:.5 -vframes 1 rgbtestsrc00105.png

colorkey=red:.01:1

ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:.01:1 -vframes 1 rgbtestsrc00110.png

colorkey=red:.1:.1

ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:.1:.1 -vframes 1 rgbtestsrc0101.png

colorkey=red:.5:.1

ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:.5:.1 -vframes 1 rgbtestsrc0501.png

colorkey=red:1:.1

ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:1:.1 -vframes 1 rgbtestsrc1001.png

colorkey=red:1:1

ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:1:1 -vframes 1 rgbtestsrc1010.png

透過具合を調べる

アルファチャンネルを調べるにはそのチャンネルの暗さ具合を調べることで透過具合を調べられる。アルファチャンネルだけを調べるには2つの方法があり、extractplanes=aalphaextract がある。どちらもアルファチャンネルをグレースケールで出力する。このとき白(0.0.0)が透過しない部分になる。暗さを調べるには YUV の Y の最小値を signalstats,metadata で調べる。

ffmpeg -f lavfi -i smptebars=d=1 -vf colorkey=0x0000bf:.01:.1,alphaextract,signalstats,metadata=print:key=lavfi.signalstats.YMIN -vframes 1 test.png

各映像チャンネルを分離する extractplanes
YUV のデータを数値で表示する signalstats
メタデータをコンソールに表示する metadata, ametadata

基本的な使い方

ffmpeg -f lavfi -i smptebars -vframes 1 smptebars.png
上の色は左から

  • 0xbebebe
  • 0xc0be00
  • 0x00bebd
  • 0x00bc00(中央の緑)
  • 0xbe00bf
  • 0xbf0000
  • 0x0000bf(青)

下の色は左から

  • 0x003d67
  • 0xffffff
  • 0x3e0076
  • 0x000000(黒)

となっている

10進数と16進数のどちらでも調べられる:SpotColor : Vector
各色の2桁目の値が何もない場合は 0 を代入する。


中央の緑(0x0ede04)が透過する

ffmpeg -i smptebars.png -vf colorkey=0x0ede04 smptebars_alpha.png

動画や画像にアルファチャンネルが付いている場合は先に付いているアルファチャンネルと、指定した色のアルファチャンネルを合成する方法をとる。


透過画像からさらに透過(0x0000b6)を追加する

ffmpeg -i smptebars_alpha.png -vf split[a][b];[a]colorkey=0x0000b6[a1];[b][a1]blend=all_mode=and -y smptebars_alpha2.png


一度に2カ所透過する

ffmpeg -f lavfi -i smptebars -vf split[a][b];[a]colorkey=0x0ede04[a1];[b]colorkey=0x0000b6[b1];[a1][b1]blend=all_mode=and -vframes 1 smptebars_alpha3.png

応用例

アルファチャンネルをグレースケールで取り出して、その部分だけフィルタを適応してオーバーレイすることで指定した色に個別のフィルタが当てられる。特定の場所にフィルタを当てる例に、hqdn3d(ノイズ除去)、unsharp, smartblur, sab(シャープ、ぼかし)、gradfun(バンディング低減) などが考えられる。

alphaextract はアルファチャンネルを黒にそうでないのは白のグレースケール出力に変換する。つまり、colorkey から alphaextract につなげた場合の出力フォーマットにはアルファチャンネルは付かない。

alphamerge は2番目の入力のグレースケール(グレースケールでなければ変換される)の白黒具合に応じて1番目の入力を透過させる。透過具合については黒が透過し、白に近いほど透過しなくなり、出力は YUVA または ARGB, RGBA になる。アルファチャンネルを含む映像になるのでそれに対応したコーデックで出力しないとアルファチャンネルが消えてしまうのに注意。YUVA なら ffv1。RGBA なら utvideo で出力する。同じ機能のフィルタに mergeplanes があるがこちらの方が負荷が少し軽い。

各映像チャンネルを結合する mergeplanes

マスクする場合、白に近いほどフィルタが強く当たり、黒に近いほどフィルタが当たらない。つまり colorkey から alphaextract につなげると、colorkey で指定した部分は黒くなる。この白黒をきれいに反転するには colorkey=white,alphaextract の代わりに curves=negative を使う。

注意点:overlay で画像出力する場合は出力フォーマットで RGB 指定しないときれいに出力できない。(overlay=format=rgb)

以下のマスク(alphamerge)を使った処理方法はフォトショップなどの画像処理の手順を参考にするのがよい。

応用例:明るいところ、暗いところにフィルタを当てる

  • 中央の 00bc00 にノイズを載せる

    00bc00 にノイズを載せる


  • 中央の 00bc00 以外にノイズを載せる

    00bc00 以外にノイズを載せる

  • 指定した3カ所にノイズを載せる

    指定した3カ所にノイズを載せる


  • ニコ生など配信ビットレートに制限がある場合、特定箇所だけぼかすことで容量を節約できる。まずは特定場所の色を調べてその色が他に使われていないかどうか、特定場所が固定ならば colorkey を使わずに crop してそこだけぼかすことも出来る。
  • 動画の特定の色を透過させて別の動画をクロマキー合成する

動画出力

画像の場合は出力拡張子を .png にすればそのままアルファチャンネル付きで出力される。動画にする場合は選択肢が複数ある。ひとつは無圧縮、もう一つは可逆圧縮である。無圧縮の場合は解像度とフレーム数が大きければ大きいほど容量が莫大になる。可逆圧縮の場合はアルファチャンネルに対応したエンコーダーを指定する。

  • バランス型の utvideo。速度と容量、デコード速度もバランスがよい。ニコニコモンズに投稿できない。
    ffmpeg -f lavfi -i smptebars -vcodec utvideo -t 10 smptebars.avi
  • 容量の大きい huffyuv。ニコニコモンズに投稿できる。
  • 画像なら apng。エンコード速度はとても遅い。ブラウザ(firefox)で再生確認できるがループ再生はしてくれない。拡張子は .apng。出力した後に拡張子を .png に直せばニコニコモンズに投稿できる。

更新履歴

smptebars で出力される色が最初に記事を書いたときと少し変わっているのを直した。ただし画像は直していないので記事の画像と実際に表示される画像の色が少し異なっている(2016年7月7日)

コメントを残す

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