普通の人には役に立たないと思われる豆知識の紹介
タイトルだけでは何を言ってるかわかりにくいと思います。ということで図を用意しました
IIPPPのトップフィールドファースト(TFF)のソースです。DoubleWeave()した後はSelectEveryやPulldownを使って1、3 or 4、6、8 or 9の4フレームを選択すれば24pにできますよね
このときフレーム1はボトムフィールドにはソースのaのボトムフィールド、トップフィールドにはソースのbのトップフィールドが使われています。ボトムフィールドがトップフィールドより前のフレームのものを使っていることになるので、ボトムフィールドファースト(BFF)になるのです
3,5,7,9も同様にBFFということになります。2つのフレームからフィールドを選択してフレームを作る場合は、そのフレームのフィールドオーダーは元の逆になるのです
|
1 2 3 |
AssumeTFF() DoubleWeave().SelectEvery(10, 1, 4, 6, 8) nnedi3(field=-1) |
こんなスクリプトがあったとします。クリップをAssumeTFF()を使ってTFFと定義しましたが、DoubleWeave().SelectEvery(10, 1, 4, 6, 8)の後は先頭の1がBFFなので、nnedi3にはBFFとして認識されてしまいます
3行目のnnedi3はfield=-1(自動選択/TFFなら1、BFFなら0になる)が指定されていますが、一度AssumeTFF()を使ったにも関わらず0として全フレーム動作してしまうのです
|
1 2 3 4 |
AssumeTFF() DoubleWeave().SelectEvery(10, 1, 4, 6, 8) AssumeTFF() nnedi3(field=-1) |
このようにAssumeTFF()をしなおせばnnedi3のfieldは1として全フレーム動作します。逆テレシネの後にフィールドオーダーを読んで処理させる場合、おまじないのようにAssumeTFF()やBFF()をするのはこのためです
Pulldown()で考えるなら、(0,2)や(0,3)や(2,4)を実行した後はフィールドオーダーは変わらず、(1,3)や(1,4)の後はフィールドオーダーが逆転してしまう、となります
さて、逆転することがあるということと、逆転する原因はわかりました。では次にフィールドオーダーはクリップごとに保存されているのか、フレームごとに保存されているのかを考えてみます。まずこうやってみました
|
1 2 3 |
AssumeTFF() DoubleWeave().SelectEvery(10, 1, 4, 6, 8) Subtitle(string(GetParity())) |
GetParity()はTFFならtrue、BFFならfalseを返します。こうしてみたところ、全フレームでfalseが表示されました。ということは全フレームBFFになっているからクリップごとに保存かな?と思えます
次にこうやってみました
|
1 2 3 4 |
AssumeTFF() DoubleWeave().SelectEvery(10, 1, 4, 6, 8) ScriptClip(last, " Subtitle(string(fo)) ") FrameEvaluate(last,"fo = Trim(current_frame,0).GetParity()") |
0フレーム目では普通にGetParity()をした結果を表示する、1フレーム目では先頭0フレーム目を削除してからGetParity()をした結果を表示する、2フレーム目では先頭の0,1の2フレームを削除してからGetParity()をした結果を表示する・・・ということをしています
するとなんと、0フレーム目はfalse、1~3フレーム目はtrue、4フレーム目はfalse・・・が表示されたのです
次に
|
1 2 3 4 5 |
AssumeTFF() DoubleWeave().SelectEvery(10, 1, 4, 6, 8) AssumeTFF() ScriptClip(last, " Subtitle(string(fo)) ") FrameEvaluate(last,"fo = Trim(current_frame,0).GetParity()") |
こうしてAssumeTFF()を間に挟んでみました。そうすると全フレームでtrueが表示されました
つまり
- フィールドオーダーを読んで処理できるもの(GetParityやnnedi3など)の一部はクリップの先頭のフレームのフィールドオーダーしか見ていないものがある
- フィールドオーダーはフレームごとに保存されている
- DoubleWeave()後の10フレームのうち、1,3,5,7,9番目の5フレームはフィールドオーダーが逆転する
- AssumeTFF()/BFF()は全フレームのフィールドオーダーを書き換える
こういうことになります。ちなみにSeparateFields()は毎フレームTFFかBFFか見て処理しているようです
また、
|
1 2 |
ConditionalFilter(last, hoge(), last, "fo", "=", "false") FrameEvaluate(last,"fo = Trim(current_frame,0).GetParity()") |
こんな風に書けば、2つのフレームからフィールドを取って作ったフレーム(DoubleWeave().SelectEvery(10,・・・)なら奇数を指定したフレーム)に対してのみhoge()が実行できる、ということにもなります
はい、役に立たない知識かもしれません。しかし、無理やり使おうと思えば使えなくもないかもしれません。2つのフレームからフィールドを選択して作ったフレームの特徴として
- 海外映画やドラマなどで、逆テレシネ前に字幕の縞がなかったソースの場合は、そのフレームにのみ字幕に縞が出る可能性がある
- そのフレームがシーンチェンジ直後か直前だったら画質の劣化が激しい
こういうことがあげられます
と、いうことで次のようなケースを考えてみました
|
1 2 3 4 5 6 7 8 9 |
v1 = Trim(0,5214).AssumeTFF().DoubleWeave().SelectEvery(10,0,3,6,8) v2 = Trim(5215,30774).AssumeTFF().DoubleWeave().SelectEvery(10,1,4,6,8) v3 = Trim(30779,43003).AssumeTFF().DoubleWeave().SelectEvery(10,0,2,4,7) v4 = Trim(43006,43905).AssumeTFF().DoubleWeave().SelectEvery(10,0,3,6,8) v1++v2++v3++v4 ConditionalFilter(last, AssumeTFF().CombReduce(last), last, "fo", "=", "false") FrameEvaluate(last,"fo = Trim(current_frame,0).GetParity()") |
CombReduce()は以前コメント欄で教えていただいた、字幕に縞が出た場合それだけ消す関数です。こう書けば、ソース次第では、縞が出る可能性のあるフレームにだけ関数を実行できて、結果は変わらないのに速度が稼げてしまう!
次に画質劣化に対処するケースを考えてみましょう
|
1 2 3 4 5 6 7 8 9 |
v1 = Trim(0,5214).AssumeTFF().DoubleWeave().SelectEvery(10,0,3,6,8) v2 = Trim(5215,30774).AssumeTFF().DoubleWeave().SelectEvery(10,1,4,6,8) v3 = Trim(30779,43003).AssumeTFF().DoubleWeave().SelectEvery(10,0,2,4,7) v4 = Trim(43006,43905).AssumeTFF().DoubleWeave().SelectEvery(10,0,3,6,8) v1++v2++v3++v4 ConditionalFilter(last, AssumeTFF().DecombUCF(last), last, "fo", "=", "false") FrameEvaluate(last,"fo = Trim(current_frame,0).GetParity()") |
DecombUCFはちょっとだけさんの、ノイズ量を計算して破綻したフレームの画質を修復するスクリプトです。このスクリプトでノイジーなフレームと判定されるのは大抵2フレームからフィールドを取って作ったフレームです(絶対にそうなるというわけではありませんが、全フレームそうなる場合もあります)
なのでこのようにしてしまえば結果は変わらない可能性も結構あるのに速度が稼げてしまう!
どちらも関数を適応するフレームを最大1/4まで減らせます!
と、無理やり考えれば活用できなくもないかもしれません




コメント
CombReduce関数について検索しても出てこなかったので某掲示板で聞いてしまったんですが、よろしければCombReduce関数を公開していただけませんか?
こんばんは。関数は紹介記事があったのですが、使ったSSがあまり良くなかったのでお蔵入りにしてしまってそのまま放置しちゃってました
いずれちゃんとした紹介記事を復活させたいですが、ひとまずこちらに書いておきます
オリジナルは私ではなく別の方で、私の方でかなり変えてしまってます
逆テレシネした後にに出る縞々な字幕を潰す関数です
必要なプラグインはmasktools2, combmask, nnedi3です(mode=1)
<使用例1>
# 逆テレシネ後に実行するだけ
# 縞判定をして、縞と判定されたら縞の部分を消そうとします
AssumeTFF().DoubleWeave().SelevtEvery(10, 1, 4, 6, 8)
CombReduce()
<使用例2>
# 縞なフレームのリストがすでにある場合
# 縞判定をスキップします
AssumeTFF().DoubleWeave().SelevtEvery(10, 1, 4, 6, 8)
ConditionalFilter( last, makeCombReduce( mode=1, mmode=2 ), last, “combed”, “=”, “true” )
ConditionalReader ( “xxxx.log”, “combed”, false)
——————————————————————————————-
https://quintrokk.subness.net/misc/combreduce.avsi
片フィールドの字幕を処理するためにTFMを使用していましたが、たまに字幕の切れ端が点々と残ったり、残像のように残ったりがあり、他に良い方法はないかと悩んでいました。
以前より検索でcombreduce.avsiが引っ掛かってはいましたが、リンクが切れており入手できずでしたが、気になっていました。
ふとドメイン変更したら良いことに気づき、無事見られて試したところ、上に書いたようなことが今のところ見られません。
boolcheckerとの組み合わせでリスト作成も容易です。
とても感動したので、このままリンクも切れたまま埋もれてしまって世の中に出ていないのが非常に勿体ないと思い、コメントさせていただきました。
7年前に記事にされようとしてそのままとなっているかと思いますが、是非改めて記事にしていただければと思います。
ご検討をお願いします。
コメントありがとうございます。ドメイン変更時にリンクを更新するプラグインを使って書き換えたつもりだったのですが、コメント欄には適用されなかったようです。助かりました
ひとまずリンクは更新しておきました。著作権的に問題なく、かつわかりやすい画像の素材の用意が難しいと思っていたので記事化は見送っていたのですが、今でも需要があるならちょっとがんばってみようかな…
リンク修正と返信ありがとうございます。
ドメイン変更されたのは2018年かと思いますが、それ以降、恐らく同様に入手できず仕舞いの人が多数いるかと思います。
これから再訪してコメント欄のURLが更新されたことに気付く人は恐らく少ないでしょうから、簡単な内容でも新しい記事としてアップしていただけると幸いです。
(前にこの記事のコメント欄でこんなスクリプトを紹介したけどリンク切れてたから修正したよ程度でも)
私的には、せっかくの良いスクリプトなので、別の内容の記事のおまけではなく、単体で紹介していただければと思います。
古い記事へのコメントで失礼します。
CombReduceについて、片フィールドの字幕を、消す、のではなく、表示する、ようにできるものでしょうか。
理由
PPPIIと並んでおり、字幕が1番目のフレームから4番目のフレームまで表示されているとした場合、フィールドマッチング後に、CombReduceで4番目の元Iの片フィールドの字幕を消すと、3番目のPと4番目の処理後のPが字幕の有無で異なることになり、TDecimateでどちらのフレームも残ってしまうため
コメントありがとうございます。古い記事でも歓迎なのでお気軽にどうぞ
TFMの後にCombReduceを使ってその後にTDecimateということでしょうか
CombReduceを使わずにTDecimateのclip2オプションを使う方をお勧めします
https://quintrokk.subness.net/?page_id=1699
こちらの記事で少し触れてます
CombReduceで字幕を残すようにしたいのであれば、makeCombReduce関数内の不等号(combreduce.avsiの51行目)を逆にすれば字幕が残ります(輝度が高い≒白が多いフィールドが残ります)
ただし片フィールドから字幕を作るので綺麗な字幕にはなりません。なので誤爆は期待通りには減らないかもしれません。
TDecimateのclip2や上記の修正でも誤爆が残る場合は、CombReduceを更に修正して綺麗な字幕を復元できるように修正も(多分)可能です。
まずはTDecimateのclip2から試してみてください。すでに使用してたらすみません…。
ご返信ありがとうございます。
不等号を逆向きにすることで、字幕が残ることを確認しました。
TDecimateで試したところ、標準的なシーンでは上手く同一視されました。
しかし、動きの少ないシーンでは、他のフレームが選ばれてしまうことがありました。
なお、スクリプトを見て気づきましたが、”reverse && mode == 2″で、mode=2の動作(字幕始点を表示・終点を非表示)が逆転するんですね。
ただし、始点・終点のどちらもノイズが出るため、不等号逆転の処理の方が良さそうです。
今回は汎用的な処理を行いたいと考えていまして、動画一本ごとシリーズごとに調整が必要となるTDecimateのclip2については、使用を考えておりません。
もしご面倒でないようでしたら、綺麗な字幕を復元する版のご用意をいただけましたら嬉しいです。
mode=2は地震速報等の字幕縞が2重になったときにどちらかを綺麗に復元するためのものなので、字幕縞を消すだけならmode=1ですね
mode=1も字幕の背景の輝度が高いと逆の挙動してしまうので完璧ではありません
大抵の場合は字幕があるフィールドの方が白い部分のおかげで輝度が高くなるのですが、もともと背景の輝度が高い場合は字幕がある方が字幕の縁の黒い部分の影響で輝度が低くなるためです
一応対策していたはずですが、誤爆を更に減らせないか、その辺も踏まえて1回スクリプトを見直してみます。少し時間ください。
単体の解説記事にして、というご要望も頂いてたけどそれもいずれ対応しようかなと思ってたらもう2年近く経ってしまっていました
久々にTFMやCombReduce試してみました。
例えばPPPIIPPPIIがあったときに PPP[字]IIPPP だった場合は縞を復元しないといけないのですが、 PPPI[字]IPPP だった場合は縞を消さないと誤爆しやすくなると思われます。
TDecimateで誤爆を減らすなら、常に字幕を復元するのではなく、TFFソースならボトムフィールドを復元するようにした方がいいのかなと
https://quintrokk.subness.net/misc/combreduce2.avsi
これでmode=2で試してみてください。
AssumeTFF()
TFM(pp=0, order=-1, slow=2, mChroma=true)
CombReduce(last, mode=2)
TDecimate(mode=1)
こんな感じでTFFソースのもので試してみたところシーンチェンジと字幕タイミングが被ったとき以外はうまく動いたように感じました。シーンチェンジでの誤爆はTDecimateは字幕関係なく起こりやすいと思うので字幕のせいじゃない可能性があります
早速の更新ありがとうございます。
字幕自体は変わらず、復元タイミングの調整ということですね。
mode=2の処理を確認しました。
TDecimateの処理結果、
PPP[字]IIPPP の場合は、同一視されれば削除されることになりますが、
PPPI[字]IPPP の場合は、そのまま残ります。
後者は場面によりノイズが残ることがあり、気になりました。
mode=2でノイズが残るフレームで、mode=1ではノイズは見当たらないため、縞を消す処理は、mode=1の方が良い結果に見えます。
また、前バージョンと字幕自体は変更ないため、動きの少ないシーンでの結果は変わらずでした。
試した結果のご報告でしたが、更新いただけただけで感謝です。
ソースを見て気になりました。
前バージョンのmode=2もコメントで初めて利用シーンを知りましたが、今回のmode=3:manual は、どういったシーンでの利用目的でしょうか。
今回のmode=2は新規のもので、以前のmode=2はmode=3にうつってます。紛らわしくてすみません
mode=3(以前のmode=2)は地震速報や気象情報等のテロップ用で、字幕用途・CombReduce経由で使うことは想定していません。無視していただいて構いません
ノイズが残るのはシーンチェンジでのノイズでしょうか。ソースによってはシーンチェンジで壮大にノイズが乗る場合があるので
間引きが正しい方がシーンチェンジでノイズが残るということもあります。mode=1でノイズが見当たらない場合はmode=1で重複フレームになってる(誤爆している)こともあるかと思います
もしノイズフレームが増えたけど重複(誤爆)フレームが減っている、のであれば想定通りの結果です
動きの少ないシーンでの結果についてはTdecimateのmode=0を使っているなら1に変更、の方がいいのかもしれません
ありがとうございます。
mode=2でノイズが残るのは、PPP[字]IIPPP と PPPI[字]IPPP のどちらもでした。
特にシーンチェンジのタイミングではなく、激しく動く場面でもなく、消す処理の場合は全て同様のノイズが出るようです。
言葉では伝わらないと思いますので、スクショを確認いただければと思います。
https://imgur.com/a/TzjvFeO
PPP[字]IIPPP はTDecimateが同一視してくれれば消えますが、
PPPI[字]IPPP は必ず残り続けるフレームなので、こちらは縞を消さずに復元する、で良さそうに思います。
バージョン2のmode=2は、ノイズが残る動作がバージョン1のmode=2+reverseと似ており、ソース上でどちらもTDeintを使用しているため、mode=2はmode=2のまま改良し、mode=3が新しいものかと思いましたが、mode=3は無視で承知しました。
余談ですが、スクリプトあるあるなのかと思いますが、ソース内で複数回CombReduceを定義すると、稀に動作が逆になることがありますね。
スクショありがとうございます。助かります。字幕が消しきれてない感じですね
ちょっと無駄な動作をさせてたので、mode=2を修正しました。消す場合の処理はmode=1と全く同じにしたので
これで直ると思います。CombReduce2をダウンロードしなおして試してみてください
mode=2も字幕が綺麗に消されることを確認しました。
一連のご対応、本当にありがとうございました。
配信に押されてAviSynthの情報が減ってきていますが、今後も有益な情報がありましたら掲載いただけましたら幸いです。
元のmode=1より誤爆は減ったのでしょうか。減ってたのなら良かったです
久しぶりにスクリプト見たらあまり読めなくなっていました。リハビリが必要そうです><
書きかけの記事は結構あるのですが、サンプル画像を作るのが大変でお蔵入りになってるのが多いです
この縞字幕記事も要望があったのでいずれ出さないと…
すみません、TDecimateのmode=1の報告がありました。
こちらは、TDecimateのmode=0からmode=1に変更しても変わらずでした。
TDecimateの表示上、CombReduceのmode=3で復元された字幕のフレームと一つ手前のフレームとの差分が1.69で、その2つ後ろのフレームが1.37のため、TDecimateのmode=0でも1でもそちらが選ばれてしまいます。
片フィールドからの復元だと、字幕部分の差分が少なくないようです。
最初の質問時のご回答に、「綺麗な字幕を復元できるように修正も(多分)可能です。」といただいておりましたが、可能なものでしょうか。
チャレンジしてみたんですが、シーンチェンジと輝度判定ミスが重なると破綻してしまったので
私にはちょっと難しそうです。すみません
手動間引きを避けるならTDecimateのclip2使用がやっぱり楽かもしれません
いえいえ、ここまで対応いただいて十分感謝です。
ありがとうございます。
締めの言葉は既に書いてしまったので(笑)、これで失礼いたします。
今後も更新を楽しみにしております。