🎞️
ffmpegで画像を動画にオーバーレイすると色がくすむ問題の対処法
overlay
フィルターを使うと色がくすむ
単純にffmpegのフィルターを使って、画像を動画にオーバーレイする(重ねる)ことができる。
ffmpeg -i input.mp4 -i yellow_FFFF00.png \
-filter_complex "[0:v][1:v]overlay" /tmp/output.mp4
しかし、上の単純なフィルターだと画像は重なるが色が微妙にくすんでしまう。例えば、#FFFF00の画像が#FFF000の色になってオーバーレイされる。
入力画像の色空間を変換する
この問題に対処するには、色空間を変換するフィルターを追加する必要がある。
ffmpeg -i input.mp4 -i yellow_FFFF00.png \
-filter_complex "[1:v]colorspace=all=bt709:iall=bt601-6-625:fast=1[p1];[0:v][p1]overlay" \
/tmp/output.mp4
これでオーバーレイされる画像の色は#FFFF00
(もしくはその1bit誤差)となる。
動画に色空間メタデータを追加する
さらにプレイヤーに正しい色空間を使わせるヒントとして以下のオプションでメタデータを追加するとよりよい。
ffmpeg -i input.mp4 -i yellow_FFFF00.png \
-filter_complex "[1:v]colorspace=all=bt709:iall=bt601-6-625:fast=1[p1];[0:v][p1]overlay" \
-color_range 1 -colorspace 1 -color_primaries 1 \
/tmp/output.mp4
上の1
はbt709色空間を意味する。
透過レイヤーがある場合
上記フィルターで色空間を変換すると透過レイヤーが失われるのでsplit
して透過レイヤーを最後にalphamerge
する必要がある。
ffmpeg -i input.mp4 -i yellow_FFFF00.png \
-filter_complex "[1:v]split=2[p_color][p_alpha];[p_color]colorspace=all=bt709:iall=bt601-6-625:fast=1[p_color];[p_alpha]format=yuva420p,extractplanes=a[p_alpha];[p_color][p_alpha]alphamerge[p1];[0:v][p1]overlay" \
-color_range 1 -colorspace 1 -color_primaries 1 \
/tmp/output.mp4
参考
主に参考にしたのは以下のブログ。
以下のブログによればまだ改善の余地はあるらしくcolorspace=all=bt709:iprimaries=bt709:itrc=srgb:ispace=bt709
を推している。
Discussion