2入力した映像の YUVA や RGBA を比較して結果を表示するblendの使い方。差分を調べて比較動画を作ったり、マスクした部分に別の映像を重ねたりいろいろな映像効果を作ることができる。

基本コマンド

比較動画として上に二つ並べて左下に差分(Y は 0 差分、UV は1入力)の動画を表示するコマンド例。
ffplay -f lavfi -i "movie=left.mp4,setpts=PTS-STARTPTS,split[a1][a2];movie=right.mp4,setpts=PTS-STARTPTS,split[b1][b2];[a1][b1]blend=c0_mode=difference,pad=2*iw:ih:0:0[blend];[a2][b2]hstack[tmp];[tmp][blend]vstack"
ffmpeg -i left.mp4 -i right.mp4 -filter_complex [0:v]setpts=PTS-STARTPTS,split[a1][a2];[1:v]setpts=PTS-STARTPTS,split[b1][b2];[a1][b1]blend=c0_mode=difference,pad=2*iw:ih:0:0[blend];[a2][b2]hstack[tmp];[tmp][blend]vstack -c:a copy output

比較動画として上に二つ並べて左下に差分(Y は 0 差分、UV は128)の動画を表示するコマンド例。
ffplay -f lavfi -i "movie=left.mp4,setpts=PTS-STARTPTS,split[a1][a2];movie=right.mp4,setpts=PTS-STARTPTS,split[b1][b2];[a1][b1]blend=c0_mode=difference,lutyuv=val:128:128,pad=2*iw:ih:0:0[blend];[a2][b2]hstack[tmp];[tmp][blend]vstack"
ffmpeg -i left.mp4 -i right.mp4 -filter_complex [0:v]setpts=PTS-STARTPTS,split[a1][a2];[1:v]setpts=PTS-STARTPTS,split[b1][b2];[a1][b1]blend=c0_mode=difference,lutyuv=val:128:128,pad=2*iw:ih:0:0[blend];[a2][b2]hstack[tmp];[tmp][blend]vstack -c:a copy output

さらに音声も再生するコマンド例(音声は left.mp4)。
ffplay -f lavfi -i "movie=left.mp4,setpts=PTS-STARTPTS,split[a1][a2];movie=right.mp4,setpts=PTS-STARTPTS,split[b1][b2];[a1][b1]blend=c0_mode=difference,lutyuv=val:128:128,pad=2*iw:ih:0:0[blend];[a2][b2]hstack[tmp];[tmp][blend]vstack[out0];amovie=left.mp4[out1]"

開始フレームが一致しない場合はsetptsフィルタの前にtrimフィルタを使う。以下は開始1フレームカットする例。
trim=start_frame=1

間違い探しを簡単に調べるコマンド(インターネット上の画像も入力できる)。
ffmpeg -i img1.jpg -i img2.jpg -filter_complex setsar=1/1[0a];[1]setsar=1/1,[0a]blend=c0_mode=grainextract,lutyuv=val:128:128 output.jpg

公式ドキュメント:FFmpeg Filters Documentation : blend, tblend

オプション

オプションは1入力をトップレイヤーに2入力をボトムレイヤーとして2つの入力から1つの出力に変える。指定チャンネル以外は1入力を返す。framesyncの設定にも対応している。

YUV は(0,128,128)で黒、(128,128,128)で灰、(255,128,128)で白になり、(255,255,255)で明るい紫、(0,0,0)で濃い緑になる。RGB は GBR の順番でフィルタを扱う。

外部記事での解説。
加算とスクリーンを正しく使い分けて綺麗な光を描くヒント – コンポジゴク

  • c0_mode[int]:最初のチャンネル。一般的には G または Y
  • c1_mode[int]:2番目のチャンネル。一般的には B または U
  • c2_mode[int]:3番目のチャンネル。一般的には R または V
  • c3_mode[int]:4番目のチャンネル。一般的には A
  • all_mode[int]:全チャンネル
    1. normal。それぞれの詳細は下にまとめてある
    2. addition
    3. and
    4. average
    5. burn
    6. darken
    7. difference, difference128
    8. grainextract
    9. divide
    10. dodge
    11. exclusion
    12. hardlight
    13. lighten
    14. multiply
    15. negation
    16. or
    17. overlay
    18. phoenix
    19. pinlight
    20. reflect
    21. screen
    22. softlight
    23. subtract
    24. vividlight
    25. xor
    26. hardmix
    27. linearlight
    28. glow
    29. addition128, grainmerge
    30. multiply128
    31. heat
    32. freeze
    33. extremity
  • モードの効果具合を調整できる。1 より小さくするとその割合だけモードの反映が小さくなる
    • c0_opacity[double]
      最初のチャンネル。一般的には G または Y
      既定値:1
      範囲:0 から 1 まで
    • c1_opacity[double]
      2番目のチャンネル。一般的には B または U
      既定値:1
      範囲:0 から 1 まで
    • c2_opacity[double]
      3番目のチャンネル。一般的には R または V
      既定値:1
      範囲:0 から 1 まで
    • c3_opacity[double]
      4番目のチャンネル。一般的には A
      既定値:1
      範囲:0 から 1 まで
    • all_opacity[double]
      全チャンネル
      既定値:1
      範囲:0 から 1 まで
  • expr で適応する時間を指定できる
    • c0_expr[string]:最初のチャンネル。一般的には G または Y
    • c1_expr[string]:2番目のチャンネル。一般的には B または U
    • c2_expr[string]:3番目のチャンネル。一般的には R または V
    • c3_expr[string]:4番目のチャンネル。一般的には A
    • all_expr[string]:全チャンネル
        指定できる計算書式
      • N:現在のフレームナンバーを返す
      • X, Y:入力した座標
      • W, H:入力したチャンネルの座標
      • SW, SH:入力したチャンネルの縦横の座標比率。yuv420p の luma だと 1、1。chroma だと 0.5、0.5
      • T:タイムスタンプ秒を返す
      • TOP, A:1入力の現在のチャンネルを返す
      • BOTTOM, B:2入力の現在のチャンネルを返す
  • shortest[boolean]
    2入力の内で映像の時間が短い場合にそこで処理を止めるか
    既定値:0
  • repeatlast[boolean]
    2入力の内で映像の時間が短い場合に最終フレームの表示を継続するか
    既定値:1

exprの使用例(1秒から3秒にかけてクロスフェードをかける)。
ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[0:v][1:v]blend=all_expr='A*(if(lte(T,1),1,if(gte(T,3),0,1-T/3)))+B*(if(lte(T,1),0,if(gte(T,3),1,T/3)))'" -t 6 fade.mp4

手軽に扱えるフェードフィルタがある:
映像のトランジションの設定ができる xfade
音声のフェードイン、フェードアウトの設定ができる afade

左上から右下へ斜めに分割して同時表示。
ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[1:v][0:v]blend=all_expr='if(gt(X,Y*(W/H)),A,B)'" diagonal.mp4

shell – FFMPEG Crop with side by side merge – Stack Overflow

exprの使い方:ffmpeg で使える評価式

mode の詳細

multiply、screen、burn、dodge(a)、(x) がよく分からないので空欄になっている。8ビット映像を参照しているが高ビット深度も対応している。1入力を A、2入力を B とする。

オプション int 計算内容 説明
normal 0 A Aの値
addition 1 FFMIN(255, A + B) AとBの和と255を比べて小さい値
and 2 A & B AとBの論理積
average 3 (A + B) / 2 AとBの和を2で割る
burn 4 BURN(A, B)
darken 5 FFMIN(A, B) AとBを比べて小さい値
difference 6 FFABS(A – B) AからBを引いた絶対値
difference128 7 128 + A – B AからBを引いた値に128を足す
grainextract 7 128 + A – B AからBを引いた値に128を足す
divide 8 B == 0 ? 255 : 255 * A / B Bが0だと255、そうでなければAをBで割って255を掛けた値
dodge 9 DODGE(A, B)
exclusion 10 A + B – (2 * A * B) / 255 AとBの和から2倍のAとBの積に255を割った値を引く
hardlight 11 B < 128 ? MULTIPLY(2, B, A) : SCREEN(2, B, A)
lighten 12 FFMAX(A, B) AとBを比べて大きい値
multiply 13 MULTIPLY(1, A, B)
negation 14 255 – FFABS(255 – A – B) 255からAとBの和を引いた絶対値を255から引く
or 15 A | B AとBの論理和
overlay 16 A < 128 ? MULTIPLY(2, A, B) : SCREEN(2, A, B)
phoenix 17 FFMIN(A, B) – FFMAX(A, B) + 255 AとBを比べて小さい値からAとBを比べて大きい値を引いて255を足す
pinlight 18 B < 128 ? FFMIN(A, 2 * B) : FFMAX(A, 2 * (B – 128)) Bが128よりも小さければAと2倍のBを比べて小さい値、そうでなければBから128を引いて2倍した値とAを比べて大きい値
reflect 19 B == 255 ? B : FFMIN(255, (A * A / (255 – B))) Bが255ならばB、そうでなければAの2乗に255からBを引いた値を割った値と255を比べて小さい値
screen 20 SCREEN(1, A, B)
softlight 21 A > 127 ? B + (255 – B) * (A – 127.5) / 127.5 * (0.5 – fabs(B – 127.5) / 255): B – B * ((127.5 – A) / 127.5) * (0.5 – fabs(B – 127.5)/255)
subtract 22 FFMAX(0, A – B) AからBを引いた値と0を比べて大きい値
vividlight 23 A < 128 ? BURN(2 * A, B) : DODGE(2 * (A – 128), B)
xor 24 A ^ B AとBの排他的論理和
hardmix 25 A < (255 – B) ? 0: 255 255からBを引いた値がAと比べて大きければ0、そうでなければ255
linearlight 26 B < 128 ? B + 2 * A – 255 : B + 2 * (A – 128) Bが128よりも小さければBと2倍のAの和から255を引いた値、そうでなければAから128を引いて2倍しBを足した値
glow 27 A == 255 ? A : FFMIN(255, (B * B / (255 – A))) Aが255だとA、そうでなければBの2乗に255からAを引いた値で割った値と255を比べて小さい値
addition128 28 A + B – 128 AとBの和から255を引く
grainmerge 28 A + B – 128 AとBの和から255を引く
multiply128 29 A – 128 * B / 32. + 128
heat 30 A == 0 ? 0 : 255 – FFMIN(((255 – B) * (255 – B)) / A, 255) Aが0だと0、そうでなければ255からBを引いた値の2乗をAで割った値と255を比べて小さい値
freeze 31 B == 0 ? 0 : 255 – FFMIN(((255 – A) * (255 – A)) / B, 255) Bが0だと0、そうでなければAを引いた値の2乗をBで割った値と255を比べて小さい値を255から引いた値
extremity 32 FFABS(255 – A – B) 255からAとBの和を引いた絶対値

コメントを残す

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

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