colorkey, chromakey, chromahold

Watch on youtube.com
doc

https://ffmpeg.org/ffmpeg-filters.html#colorkey, https://ffmpeg.org/ffmpeg-filters.html#chromakey, https://ffmpeg.org/ffmpeg-filters.html#chromahold

colorkey, chromakey

If you want to pass the value as hex for “colorkey” you can pass it in RGB form. If the value passed in is appropriate, as in this example, the color area becomes transparent with “overlay”. (Regarding the case that the boundary can not be handled properly, forget about now. (This is described after.))

#! /bin/sh
f1="Pexels_4709.mp4"
f2="Pexels_4614-zoomed-greenscreen.mp4"

ffmpeg -y -i "${f1}" -i "${f2}" -filter_complex "
[1:v]colorkey=0x80FF80[1v];
[0:v][1v]overlay[v]
" -map '[v]' -an out.mp4

As in the previous example, it is almost impossible for color keys to be strictly composed of one color in real video. Especially in live-action video. The solution to this is the “similarity” option.

The “similarity” option is given between 0.01 and 1.0. The larger the value, the more “the value is far apart” is allowed. In other words, 1.0 is a designation that “all colors are color key”, 0.01 means “I can not accept this as a color key except for this single color completely”.

00:00:36
#! /bin/sh
f1="Pexels_4709.mp4"
f2="Pexels_4614-zoomed-greenscreen.mp4"

ffmpeg -y -i "${f1}" -i "${f2}" -filter_complex "
[1:v]colorkey=0x80FF80:similarity=0.3[1v];
[0:v][1v]overlay[v]
" -map '[v]' -an out.mp4

If you know the color key for that video with YUV, use “chromakey” instead of “colorkey” filter. (In order to create this example, I calculated that the RGB value “0x80FF80” is YUV value “0xCA554A”. Of course you do not have to do it, if you try to do that you are just a fool.)

00:01:12
#! /bin/sh
f1="Pexels_4709.mp4"
f2="Pexels_4614-zoomed-greenscreen.mp4"

ffmpeg -y -i "${f1}" -i "${f2}" -filter_complex "
[1:v]chromakey=0xCA554A:similarity=0.1:yuv=1[1v];
[0:v][1v]overlay[v]
" -map '[v]' -an out.mp4

In the case without “yuv=1”, “chromakey” is the same as “colorkey” in terms of usage. That is, the hexadecimal form is regarded as RGB if “yuv=1” is not specified. However, one of them acts on RGB, the other acts on YUV, not the same thing. This can be seen by different results with the same color and same similarity.

00:01:48
#! /bin/sh
f1="Pexels_4709.mp4"
f2="Pexels_4614-zoomed-greenscreen.mp4"

ffmpeg -y -i "${f1}" -i "${f2}" -filter_complex "
[1:v]chromakey=0x80FF80:similarity=0.3[1v];
[0:v][1v]overlay[v]
" -map '[v]' -an out.mp4

chromahold

The usage of `chromahold’ is completely the same as `chromakey’. The value of this is, for example, visually confirming the efficacy of the `similarity’ designation in `chromakey’.

#! /bin/sh
#f1="Pexels_4709.mp4"
f2="Pexels_4614-zoomed-greenscreen.mp4"

for i in {1..5} ; do
    "/c/Program Files/ffmpeg-4.1-win64-shared/bin/ffmpeg" -y \
        -i "${f2}" -vf "chromahold=0x80FF80:similarity=0.${i}:yuv=1" -an out${i}.mp4
done
# Note: {1..5} form is of bash-builtin. If you don't use bash, you can use "expr" like this:
#     i=1
#     while test ${i} -le 5 ; do
#         # ...
#         i=`expr ${i} + 1`
#     done