fieldmatchフィルタで逆テレシネしてプログレッシブフレームを作り、プログレッシブ化に漏れたフレームを改めてインターレース解除フィルタでプログレッシブ化しdecimateフィルタで間引けば24p化することができる。テレシネではなくインターレースのときは逆テレシネしないので、あとのインターレース解除フィルタでプログレッシブ化できる。ポストプロセスppsrcでノイズ除去、または明るさ、コントラストの調整することでオリジナルフィールドを劣化させず逆テレシネすることもできる。逆テレシネして24pまたは25pの映像には効果的だが、30p(縞なし)、60p(毎フレーム縞)が大半を占めるときは通常のインターレース解除フィルタのほうがよい。

基本コマンド

アニメのインターレース解除漏れにはestdifフィルタがよさそうに感じた。次点はyadifフィルタ。
ffmpeg -i input -vf fieldmatch,estdif=0:0:1,decimate -c:a copy output
ffplay -i input -vf fieldmatch,estdif=0:0:1,decimate

cthreshを上げたほうが逆テレシネのフレームが増える。
ffmpeg -i input -vf fieldmatch=cthresh=40,estdif=0:0:1,decimate -c:a copy output
ffplay -i input -vf fieldmatch=cthresh=40,estdif=0:0:1,decimate

映像上部にあるロゴを判定区画から外す。適宜ロゴサイズに合わせて調整する。
ffmpeg -i input -vf fieldmatch=y0=0:y1=50:cthresh=40,estdif=0:0:1,decimate -c:a copy output
ffplay -i input -vf fieldmatch=y0=0:y1=50:cthresh=40,estdif=0:0:1,decimate

フィールド判定がうまくいってないときはsetfieldフィルタで指定する。
ffmpeg -i input -vf setfield=tff,fieldmatch=tff:cthresh=40,estdif=0:0:1,decimate -c:a copy output
ffplay -i input -vf setfield=tff,fieldmatch=tff:cthresh=40,estdif=0:0:1,decimate

デバグ方法はcombdbgを指定しほかのパラメータを変えながら挙動の変化を確認する。
ffmpeg -report -i input -vf setfield=tff,fieldmatch=tff:combmatch=full:combdbg=1:cthresh=9:combpel=80 -an -f null - > nul 2>&1

先にFFREPORTでファイル名とデバグレベルを指定するとログのファイル名を指定できる。
set FFREPORT=file=foo.log:level=48

カンマ区切りに整形したログ。
grep SC: foo.log | grep -oP "COMBS:\s+\K.*" | sed "s/ \+/,/g" > fieldmatch_combdbg_log.csv

ppsrcを有効にしてilフィルタでフィールド分離して縦に並べてbilateralフィルタでデノイズしてilフィルタで元の映像に戻す例。
ffmpeg -report -i input -vf setparams=tff,split[1],il=l=d:c=d,bilateral,il=l=i:c=i[0];[0][1]fieldmatch=tff:ppsrc=1:combmatch=sc:cthresh=8:combdbg=1 -an -f null - > nul 2>&1

ピクチャーをインターリーブ、デインターリーブするil
エッジ保持のスムースフィルタ bilateral

bilateralフィルタの代わりにlutyuvフィルタで少し明るくする。
ffmpeg -report -i input -vf setparams=tff,split[1],lutyuv=y=gammaval(1/1.1)[0];[0][1]fieldmatch=tff:ppsrc=1:combmatch=sc:cthresh=8:combdbg=1 -an -f null - > nul 2>&1

Windows の ffmpeg で生放送する方法 : LUT(ルックアップテーブル、ラット)

入力にテレシネの30iとプログレッシブの24pが混在したVFRのときはdejudderフィルタとfpsフィルタで大きいフレームレートで固定したCFRにする。テレシネの30iでOPEDなどが60iになる片フィールド補間が必要な映像はdecimateフィルタで間引かない。
ffmpeg -i input -vf dejudder,fps=30000/1001,fieldmatch,decimate -c:a copy output
ffplay -i input -vf dejudder,fps=30000/1001,fieldmatch,decimate

テレシネにテロップなどの60iが混在しているときはfieldmatchフィルタでは解除漏れするのでインターレース解除フィルタを併用し、解除するフィールド指定をインターレースだけにする。
ffmpeg -i input -vf dejudder,fps=30000/1001,fieldmatch=combmatch=full,estdif=0:-1:1 -c:a copy output

エッジ傾斜を考慮したインターレース解除フィルタestdif

さらに昔のノイタミナの冒頭にあった30pと本編テレシネとテロップの60iも揃うとインターレース解除フィルタで30pの部分がボケるので、30pの部分をインターレース解除フィルタから退避するなどしてボケないようにさせる。
ffmpeg -i input -filter_complex "split[1v],trim=start_frame=0:end_frame=120,fieldmatch=combmatch=full,setpts=PTS-STARTPTS[0v];[1v]trim=start_frame=120,fieldmatch=combmatch=full,estdif=0:-1:1,setpts=PTS-STARTPTS[1v];[0v][1v]concat=n=2:v=1:a=0" -c:a aac output

ただし上の方法だと冒頭の30pのフレームレートが少しおかしくなるので、正確さを求めるなら区間ごとにrawファイルの.264や.265などで出力してconcatする。
ffmpeg -i input -filter_complex "split[1v],trim=start_frame=0:end_frame=120,fieldmatch=combmatch=full,setpts=PTS-STARTPTS[0v];[1v]trim=start_frame=120,fieldmatch=combmatch=full,estdif=0:-1:1,setpts=PTS-STARTPTS[1v]" -map [0v] output1.264 -map [1v] output2.264

異なる fps を連結して VFR の動画にする

高ビット深度のテレシネコンテンツにはppsrc=1を使えばビット深度を保持できる。使わないと8ビット深度に落ちる。
ffmpeg -i input -vf setparams=tff,split,fieldmatch=tff:ppsrc=1,estdif=0:0:1,decimate -c:a copy output
ffplay -i input -vf setparams=tff,split,fieldmatch=tff:ppsrc=1,estdif=0:0:1,decimate

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

オプション

  • order[int]
    想定されるフィールドオーダーの指定
    • -1, auto:自動検出。ffmpegの処理と同じ。既定値
    • 0, bff
    • 1, tff
  • mode[int]
    フィールドマッチ方法の指定。下にいくほど処理が遅くなる。orderで指定したフィールドを元に対のフィールドをp:過去、c:現在、p:未来のフィールドを移動したのがこのグラフ。u/bはよくわからない
    • 0, pc
    • 1, pc_n:既定値
    • 2, pc_u
    • 3, pc_n_ub
    • 4, pcn
    • 5, pcn_ub
  • ppsrc[boolean]
    2入力して1入力目をポストプロセスでフィルタを当ててフィールドマッチに役立てる。フィルタはデノイズや明るさ調整が考えられる。出力フレームには1入力目のフィルタの影響はない
    既定値:0
  • field[int]
    照合するフィールドの指定。通常はorderと同じ設定にする
    • -1, auto:orderと同じ。既定値
    • 0, bottom
    • 1, top
  • mchroma[boolean]
    フィールドマッチに彩度を考慮する。通常は有効にするが、大きな虹やその他アーティファクトなど、映像によくない彩度の問題があるときに無効にする。無効にすると処理速度が上がる
    既定値:1
  • y0[int]
    既定値:0
  • y1[int]
    それぞれの値を含むy0y1の間をフィールドマッチの決定から除外する縦幅の指定。y0はスキャン開始座標、y1はスキャン終了座標を設定する。字幕、ロゴ、黒枠などマッチの邪魔になるものが映像にあるときに指定する。y0、y1を同じ値にすると効果が無効になる
    既定値:0
  • scthresh[double]
    シーンチェンジで使う輝度変化の最大の割合値。適切な値は8から14でcombmatch=scのときだけに効果がある
    既定値:12
    範囲:0から100まで
  • combmatch[int]
    インターレース櫛がないときに最終的にどの方法で櫛の程度を決めるか
    • 0, none:しない
    • 1, sc:シーンチェンジ。既定値
    • 2, full:全部。シーンチェンジ以外でフィールドタイプが変わる60iクレジットやテロップの区間を調べるときに使う
  • combdbg[int]
    計算した櫛のスコアをコンソールに流す。match=0はフィールドマッチしていなく、match=1はフィールドマッチしている。一般的なテレシネでは映像が継続的に動いて櫛が見えるとmatchが11001を繰り返す。途中から見れば1が3連続、0が2連続になる。映像が動いてなければフィールドがマッチしないフレームは1になりやすい。combpelで指定した値が、例えば以下の最初の3つの数値以上でcombed=YESになる。62が80より小さいのでcombed=NOになる。combed=YESのときにコンソールのログに「is still interlaced」が表示される
    例:COMBS: 256 62 256 -1 -1 (combpel=80) match=1 combed=NO
    • 0, none:ログは非表示。既定値
    • 1, pcn:mode=pc_nに強制してログを表示する
    • 2, pcnub:mode=pcn_ubに強制してログを表示する
  • cthresh[int]
    櫛検出の閾値。大きな値では大きく見える櫛を検出し、小さな値では見えにくい櫛を検出する。-1はすべてのピクセルに櫛があると検出し、255は逆に櫛が検出されない。この値はピクセルの差分値である。小さな値はフィールドマッチ漏れしやすくなる
    既定値:9
    範囲:-1から255まで
  • chroma[boolean]
    櫛フレーム検出に彩度を考慮する。大きな虹やその他アーティファクトなど、映像によくない彩度の問題がありchromaを有効にして櫛フレーム検出に問題があるときは無効にする。しかし実際は彩度だけに櫛が残る場合を除いて無効にしたほうが信頼性が高い
    既定値:0
  • blockx[int]
    combpelで櫛フレーム検出に使われる領域の横幅の指定。2のべき乗である任意の値を指定する
    既定値:16
    範囲:4から512まで
  • blocky[int]
    combpel櫛フレーム検出に使われる領域の縦幅の指定。2のべき乗である任意の値を指定する。縦スクロールのクレジット検出にこの値を上げると検出しやすくなる
    既定値:16
    範囲:4から512まで
  • combpel[int]
    櫛状態のピクセルがblockxblocky内にどれだけ含まれていたら櫛状態と判定する閾値。blockxblockyの乗算以下でなければならない
    既定値:80
    範囲:0からINT_MAXまで

テレシネ以外の映像を検出するには

  • テレシネ以外の映像の検出にはcombmatch=fullを追加する。
  • テレシネに30pが混在するとmatch=1、combed=YESが連続する。
  • テレシネに下テロップやクレジットなどの60iが混在してもmatch=1、combed=YESが連続する。
  • cthreshを上げすぎるとテレシネ以外の映像が検出しにくくなる。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

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