ffmpeg にcolorkey
フィルタが取り込まれたことにより、クロマキー合成や特定色に個別のフィルタを当てられるようになった。
ffmpeg 2.7.1 以降でcolorkey
フィルタが使える。
avfilter/vf_colorkey: Add colorkey video filter
colorkey
は指定した色の部分をアルファチャンネルにして、それ以外を RGB の BGRA で出力する。指定する色は16進数の rrggbb 形式か、色名を指定する。入力映像が 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]
指定した色を完全に透過(アルファが0)させる。16進数形式か、色名を指定
既定値:black - similarity[float]
一致の範囲指定。0.01 は完全一致、1 は全画面。大きい値ほど透過範囲が広くなる
既定値:0.01
範囲:0.01 から 1 まで - blend[float]
similarityの範囲外の色の透過の影響具合の指定。0 は指定した色だけ(similarityの範囲外は透過しない)で大きくするほど似た色も少しずつ透過する。つまり透過のグラデーションがきれいになる
既定値:0
範囲:0 から 1 まで
blend, similarity について
- 基本画像(赤の右端が少し透過して欠けている)
ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red -vframes 1 rgbtestsrc.png
-
ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:0.01:0.1 -vframes 1 rgbtestsrc00101.png
-
ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:0.01:0.5 -vframes 1 rgbtestsrc00105.png
-
ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:0.01:1 -vframes 1 rgbtestsrc00110.png
-
ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:0.1:0.1 -vframes 1 rgbtestsrc0101.png
-
ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:0.5:0.1 -vframes 1 rgbtestsrc0501.png
-
ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:1:0.1 -vframes 1 rgbtestsrc1001.png
-
ffmpeg -f lavfi -i rgbtestsrc -vf colorkey=red:1:1 -vframes 1 rgbtestsrc1010.png
透過具合を調べる
アルファチャンネルを調べるにはそのチャンネルの暗さ具合を調べることで透過具合を調べられる。アルファチャンネルだけを調べるには2つの方法があり、extractplanes=a
フィルタとalphaextract
フィルタがある。どちらもアルファチャンネルをグレースケールで出力する。このとき白(255.255.255)が透過しない部分になる。暗さを調べるには YUV の Y の最小値をsignalstats,metadata
で調べられる。signalstats
フィルタは RGB の値に対応していない。
ffmpeg -f lavfi -i smptebars=d=1 -vf colorkey=0x0000bf:0.01:0.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
上の色は左から
- 190.190.190(0xbebebe)
- 192.190.0(0xc0be00)
- 0.190.189(0x00bebd)
- 0.188.0(0x00bc00)(中央の緑)
- 190.0.191(0xbe00bf)
- 191.0.0(0xbf0000)
- 0.0.191(0x0000bf)(青)
中央の色は左から
- 0.0.191(0x0000bf)
- 3.3.3(0x030303)
- 190.0.191(0xbe00bf)
- 3.3.3(0x030303)
- 0.190.189(0x00bebd)
- 3.3.3(0x030303)
- 190.190.190(0xbebebe)
下の色は左から
- 0.61.103(0x003d67)
- 255.255.255(0xffffff)
- 62.0.118(0x3e0076)
- 0.0.0(0x000000)
- 9.9.9(0x090909)
- 0.0.0(0x000000)
となっている
10進数と16進数のどちらでも調べられる:SpotColor : Vector
各色の2桁目の値が何もない場合は 0 を代入する。
ffmpeg -i smptebars.png -vf colorkey=0x00bc00 smptebars_alpha.png
動画や画像にアルファチャンネルが付いている場合は先に付いているアルファチャンネルと、指定した色のアルファチャンネルを合成する方法をとる。
ffmpeg -i smptebars_alpha.png -vf split[a][b];[a]colorkey=0x0000bf[a1];[b][a1]blend=all_mode=and smptebars_alpha2.png
ffmpeg -f lavfi -i smptebars -vf split[a][b];[a]colorkey=0x00bc00[a1];[b]colorkey=0x0000bf[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
フィルタがあるがこちらの方が負荷が少し軽い。
- アルファチャンネルをグレーで出力する alphaextract
- 別ファイルの情報から元映像を透過させる alphamerge
- 各映像チャンネルを結合する mergeplanes
- トーンカーブで RGB の調整が出来る curves
マスクする場合、白に近いほどフィルタが強く当たり、黒に近いほどフィルタが当たらない。つまりcolorkey
フィルタからalphaextract
フィルタにつなげると、colorkey
で指定した部分は黒くなる。この白黒をきれいに反転するにはcolorkey=white,alphaextract
フィルタの代わりにcurves=negative
フィルタを使う。
- FFmpeg Filters Documentation : hqdn3d
- FFmpeg Filters Documentation : unsharp
- FFmpeg Filters Documentation : smartblur
- FFmpeg Filters Documentation : sab
- FFmpeg Filters Documentation : gradfun
- FFmpeg Filters Documentation : noise
- FFmpeg Filters Documentation : alphaextract
- FFmpeg Filters Documentation : alphamerge
- FFmpeg Filters Documentation : curves
注意点:overlay フィルタで RGB の画像出力するときは出力フォーマットで RGB 指定しないときれいに出力できない。(overlay=format=rgb)
以下のマスク(alphamerge
)を使った処理方法はフォトショップなどの画像処理の手順を参考にするのがよい。
- 中央の 00bc00 にノイズをのせる
- 中央の 00bc00 以外にノイズをのせる
- 指定した3カ所にノイズをのせる
- 中央のロゴ周りの緑色(0x003900)に
smartblur
フィルタを当てる
- クロップして特定場所に効果がわかりやすいノイズをのせる
256:148 がcrop
フィルタの座標指定。128:64 がクロップの範囲指定。
- 動画の特定の色を透過させて別の動画をクロマキー合成する
動画出力
画像の場合は出力拡張子を .png にすればそのままアルファチャンネル付きで出力される。動画にする場合は選択肢が複数ある。ひとつは無圧縮、もう一つは可逆圧縮である。無圧縮の場合は解像度とフレーム数が大きければ大きいほど容量が莫大になる。可逆圧縮の場合はアルファチャンネルに対応したエンコーダを指定する。
- バランス型の utvideo。速度と容量、デコード速度もバランスがよい。ニコニコモンズに投稿できない。
ffmpeg -f lavfi -i smptebars -c:v utvideo smptebars.avi
- 容量の大きい huffyuv。ニコニコモンズに投稿できる。
- 画像なら APNG。エンコード速度はとても遅い。拡張子は .apng。出力した後に拡張子を .png に直せばニコニコモンズに投稿できる。-f apngをつければ .png でも出力できる
APNG をループ出力する
video – What are the differences between the HuffYUV and ffvhuff codecs in FFmpeg? – Super User
colorkey_opencl
opencl を使ってcolorkey_opencl
フィルタを使う。
opencl が使えれば以下のコマンドを実行すると対応 CPU、または GPU が表示される。
ffmpeg -hide_banner -v verbose -init_hw_device opencl
出力コマンド例。
ポイントは opencl を使うデバイスを上の例では 0.0 から 1.1 から指定する。能力によって処理速度が大きく異なる。オプション指定は通常と同じ。
コマンド例。RGBA 入力なので前後にフォーマット変換を挟む。
ffmpeg -init_hw_device opencl=ocl:1.0 -filter_hw_device ocl -f lavfi -i rgbtestsrc -vf format=rgba,hwupload,colorkey_opencl=red:.01:.1,hwdownload,format=rgba -vframes 1 rgbtestsrc.png
ffmpeg -init_hw_device opencl=ocl:1.0 -filter_hw_device ocl -i input -vf format=rgba,hwupload,colorkey_opencl=red:.01:.1,hwdownload,format=rgba -vframes 1 rgbtestsrc.png