Photo Gallery

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
ブレンドするとノイズが減ります。

各ソースから綺麗な部分を持ち寄って 1 つのクリップを生成するわけですから、NR フィルターなどによる画像の「加工」とはちょっと違うということを、今回はこちらの画像を使って検証したいと思います。
今回の検証では数値は一切ありません。プレビューと主観で喋るので、合わない人は browser back

画像の比較は、ビフォーアフターを並べるよりも、タブなどで切り替えて行うことを推奨します。
並べると視野角の影響を受けますし、視線を動かすことによって変化に気づきにくいからです。



BS11 ソース
BS11.png




目ポイントは?

Area.png

画像のように、黄色いエリアと、赤いエリアを分けて考えていきます。
目標とする画質のポイントは次の 2 点

・ノイズが少ない
・ボケていない

これを踏まえて、いくつか有名な NR フィルターを使ってみたのでご紹介します。




NRの検証

AviSynth と AviUtl から、独断と偏見でいくつかチョイスしました。
すべてデフォルト値でプレビューしています。

| Deblock()

BS11_Deblock.png

黄色領域に多く見られる 8x8 ブロッキングノイズの多くが低減され、尚且つ赤色領域のエッジ付近などの高周波領域には目立った影響は少ないように見えます。
しかしまだまだブロックノイズは目立ちます。圧縮率の低下にも繋がっています。


| MosquitoNR()

BS11_MosquitoNR.png

エッジ付近への平滑化が積極的に行われています。エッジの歪みが是正されている感じですが、当然ながらブロックノイズへのアプローチは Deblock() よりも弱め。


| RemoveGrain()

BS11_RemoveGrain.png

名前に違わず、均さずに取り除いているという感じ。細かい範囲で処理されているので、赤色領域の解像度感は保持されている印象を受けますね。逆に黄色領域は積極的に削られているように見えるので、割と理想に近いかも。


| Convolution3D(preset="animeBQ")

BS11_Convolution3D(preset=animeBQ).png

これよりも弱いプリセットでは効果が薄すぎたので、ここでは BQ で検証します。
なんか全体的に、x 軸にブレています…。効果の割にボケ率高いように感じます。


| AviUtl ノイズ除去フィルタ

BS11_AviUtlNR.png

エッジは保護されているのかな?ただ、非エッジ領域ではこれでもかというくらい除去します。閾値調整次第かもしれないですが。
印象としては RemoveGrain() の強力版。


| AviUtl NL-Means

BS11_AviUtlNL-Means.png

高周波、低周波に関わらず、一定の基準で平均値で均している、といった感じでしょうか。
メディアンと違ってぼかしの部類なので、解像度感が落ちてノイズはうっすら残るというマイナスな見方もできますが、、このフィルターには保護機能が備わっているので、上手く調整すれば AviUtl の中ではかなり有用な NR だと感じます。




してブレンドは

一口にブレンドといってもソースの数や種類、閾値調整などによっても結果は大きく変わります。
今回は BS11 / WOWOWプレミアム / GTV のソースを使いました。細かい設定はキリがないので端折ります。

Blend.png

パッと見た感じ、なんかボケてるかな?とも取れますが、 BS11 のプレビューのほうが解像度感があるように感じるのは、単純に細かいノイズが多すぎてアニメのディテールのように映るからではないか?というのが最近の私の見解です。

その点を踏まえてポイントを絞りながら見比べると、NR ではまず不可能な、黄色領域のノイズ量と赤色領域の再現度の両立が出来ているのが分かります。

たとえば下の画像のように、圧縮の影響でエッジが繋がっていない箇所を復元。
edgeBreak_BS11.png

edgeBreak_Blend.png


そうかと思えば、ブロックノイズはここまで是正されていて、エッジ領域の保護(というより復元)とノイズの低減という相反することを同時に実現出来ています。
BlockArea_BS11.png

BlockArea_Blend.png




とめ

ノイズは、それ自体が汚く映るというだけに留まらず、エンコード時の圧縮率の低下や、それに影響され本来綺麗だったフレームや領域の足を引っ張るというデメリットを孕んでいます。
そして、DTV におけるノイズとは、インターレースによるコーミング、ビットレート不足によるブロッキングと、量子化によるモスキートノイズが殆どです。
そして、インターレースさえ存在しなければ、ビットレート不足に陥ることも、それによってブロックやモスキートが発生することも減ります。
昨年放送していた攻殻機動隊S.A.C.の再放送がプログレッシブで、その映像はとてもクリアでノイズが殆ど見受けられなかったので、その経験を元に、私の中ではそう結論付けました。


つまり何が言いたいかと言うと、インタレ滅びろ







関連記事
一部のエンコオタクの間で流行っているブレンドエンコードとは?



©BNEI/PROJECT iM@S

スポンサーサイト
この記事は DTV Advent Calendar 2015 に登録させて頂きました。


とうとうカレンダーの予約が途切れていたので、即席の小ネタですが…
前回の記事 で触れた、差分を吸収してブレンドする関数の応用ライブラリです。


使い方

DiffMerge(clip1, clip2)

clip1 と clip2 をブレンドし、差分箇所は clip2 が使用されます。


DiffMerge(clip1, clip2, debug=true)

差分のマスクを表示します。


# 透過率コントロールを OFF にする
DiffMerge(clip1, clip2, debug=true, transctrl=false)

# 前回記事でも紹介したマスク生成
a=mt_makediff(clip1, clip2, U=-128, V=-128)
b=mt_makediff(clip2, clip1, U=-128, V=-128)
mt_logic(a, b, mode="or")

この二つは同じ結果になります。


trans_control(mask, padding_range=8, fade_range=0)

trans_control.png

mask_ab+ba.png

trans_control は、画像のようなマスクに対して、透過率の調整を行う関数です。
DiffMerge 関数の内部で使用しているので、同パラメータが DiffMerge からも呼び出せます。
padding_range は、グレーの部分(マスク外領域)の許容値で、明るさの中間値 128 ± padding_range で領域を広げます。
fade_range は、128 ± padding_range ± fade_range で、フェードアウトしながら領域を広げます。



trans_control(mask, deflate=3, expand=8)

deflate はマスク領域を減らします。微量のノイズを差分マスクに含めたくない場合は数値を増やすと効果がありますが、やりすぎると必要なマスクまで削ってしまいます。
expand はマスク領域を拡大します。マスキング漏れを防ぐ意図があります。






数定義

/*

クリップa,bを合成する
差分がある領域はbに置き換わる

clip a 合成対象
clip b 合成対象
float weight <0.25> auto_merge_order の weight
float weight2 <0.1> auto_merge_order の weight2
int thr <10> auto_merge_order の thr
int exc <0> auto_merge_order の exc
int nmax <5> auto_merge_order の nmax
bool transctrl <true> trans_control を使用するか
int padding_range <8> trans_control (輝度の中間値からの許容範囲)
int fade_range <0> trans_control (輝度の中間値からの許容フェード範囲)
int deflate <3> trans_control (領域を減らす)
int expand <6> trans_control (領域を大きくする)
bool debug <false> マスクを表示

*/

function DiffMerge(clip a, clip b, float "weight", float "weight2", int "thr", int "exc", int "nmax", bool "transctrl", int "padding_range", int "fade_range", int "deflate", int "expand", bool "debug") {
weight=default(weight,0.25)
weight2=default(weight2,0.1)
thr=default(thr,10)
nmax=default(nmax,5)
exc=default(exc,0)
transctrl=default(transctrl,true)
padding_range=default(padding_range,8)
fade_range=default(fade_range,0)
deflate=default(deflate,3)
expand=default(expand,6)
debug=default(debug,false)
clip=auto_merge_order(a,b,weight,weight2,thr,exc,nmax)
mask=get_diffmask(a,b,transctrl,padding_range,fade_range,deflate,expand)
return debug?mask:mt_merge(clip,b,mask,luma=true)
}

/*

差分マスク生成

clip a 差分対象
clip b 差分対象
bool transctrl <true> trans_control を使用するか
int padding_range <8> trans_control (輝度の中間値からの許容範囲)
int fade_range <0> trans_control (輝度の中間値からの許容フェード範囲)
int deflate <3> trans_control (領域を減らす)
int expand <6> trans_control (領域を大きくする)

*/

function get_diffmask(clip a, clip b, bool "transctrl", int "padding_range", int "fade_range", int "deflate", int "expand") {
transctrl=default(transctrl,true)
padding_range=default(padding_range,8)
fade_range=default(fade_range,0)
deflate=default(deflate,3)
expand=default(expand,8)
#~ mask1=mt_makediff(a.Vinverse(),b.Vinverse(),U=-128,V=-128) # Vinverse.dll使用で精度が少しUP
#~ mask2=mt_makediff(b.Vinverse(),a.Vinverse(),U=-128,V=-128) # Vinverse.dll使用で精度が少しUP
mask1=mt_makediff(a,b,U=-128,V=-128)
mask2=mt_makediff(b,a,U=-128,V=-128)
return transctrl?trans_control(mask1,padding_range,fade_range,deflate,expand):mt_logic(mask1,mask2,mode="or")
}

/*

マスクのアルファ領域をコントロール

clip c マスク
int padding_range <8> 輝度の中間値からの許容範囲
int fade_range <0> 輝度の中間値からの許容フェード範囲
int deflate <3> 領域を減らす
int expand <6> 領域を大きくする

*/

function trans_control(clip c, int "padding_range", int "fade_range", int "deflate", int "expand") {
padding_range=default(padding_range,8)
fade_range=default(fade_range,0)
deflate=default(deflate,3)
expand=default(expand,6)
mask=mt_merge(blankclip(c,color=$004d00),blankclip(c,color=$00ff00),c.yrangemask(128-(padding_range+fade_range),fade_range,128+(padding_range+fade_range),fade_range).mt_invert(),luma=true).mt_binarize(U=-0,V=0)
mask=deflate==0?mask:add_deflates(mask,deflate)
mask=expand==0?mask:add_expand(mask,expand)
return mask
}

/*

マスクに指定回数分の deflates 処理を施す

clip c マスク
int limit deflates 回数
int cnt <0> 再起処理用

*/

function add_deflates(clip c, int limit, int "cnt") {
cnt=default(cnt,0)
cnt=cnt+1
c=limit==cnt?c:c.mt_deflate()
return limit==0?c:limit==cnt?c:add_deflates(c,limit,cnt)
}

/*

マスクに指定回数分の expand 処理を施す

clip c マスク
int limit expand 回数
int cnt <0> 再起処理用

*/

function add_expand(clip c, int limit, int "cnt") {
cnt=default(cnt,0)
cnt=cnt+1
c=limit==cnt?c:c.mt_expand()
return limit==0?c:limit==cnt?c:add_expand(c,limit,cnt)
}

/*

FlexibleMerge の Merge 順序を自動選択

clip a 合成対象
clip b 合成対象
float weight <0.25> FlexibleMerge の weight
float weight2 <0.1> FlexibleMerge の weight2
int thr <10> FlexibleMerge の thr
int exc <0> FlexibleMerge の exc
int nmax <5> FlexibleMerge の nmax
int show <0> FlexibleMerge の show
bool rev <false> false=綺麗なフレームを返す, true=汚いフレームを返す

*/

function auto_merge_order(clip a, clip b, float "weight", float "weight2", int "thr", int "exc", int "nmax", int "show", bool "rev") {
weight=default(weight,0.25)
weight2=default(weight2,0.1)
thr=default(thr,10)
nmax=default(nmax,5)
exc=default(exc,0)
rev=default(rev,false)
show=default(show,0)
a=FlexibleMerge(a,b,weight=weight,weight2=weight2,thr=thr,nmax=nmax,exc=exc,show=show)
b=FlexibleMerge(b,a,weight=weight,weight2=weight2,thr=thr,nmax=nmax,exc=exc,show=show)
return ConditionalFilter(interleave(a,b),a,b, \
"AverageChromaV(CombCheck(SelectEven))", (rev?">":"<"), "AverageChromaV(CombCheck(SelectOdd))")
}






出典
にわとり遊び - 2つのソースからノイズの無い部分を選んでブレンドする (FlexibleMerge) その2
メモ置き場 - yの範囲を指定してマスク


関連記事
多少映像に違いがあっても問題なくブレンドするには?
一部のエンコオタクの間で流行っているブレンドエンコードとは?


Tag:DTV AviSynth FlexibleMerge DiffMerge ブレンド エンコード

この記事は DTV Advent Calendar 2015 に登録させて頂きました。


えがき

前回の記事 でご紹介したブレンド技術は、 2 つのクリップの間に 1 フレームの映像の違いも許されないという縛りがありました。
今日はそのあたりを上手く回避して、テロップの違いや作画修正などが認められる場合でもブレンドする方法をご紹介したいと思います。
一例ですので、無理にこの方法に拘る必要はありません。





例によって AviSynth が使える事を前提に進めさせて頂きます。
必須プラグインは Masktools v2 です。



うやるの?

映像の違いがある部分のみマスキングを施し、それ以外の部分のみブレンドしたクリップを表示します。
以下 code と preview で順を追って説明します。

■ ソースの読み込み
a=ImageSource("ClipA.bmp", start=0, end=0).ConvertToYV12(matrix="Rec709")
b=ImageSource("ClipB.bmp", start=0, end=0).ConvertToYV12(matrix="Rec709")

ClipA.png ClipB.png
今回はとりあえず画像で説明します。
違いが分かり易いように、あえて全く違う図形を用意しました。




■ 差分マスク生成
ab=mt_makediff(a,b,U=-128,V=-128)
ba=mt_makediff(b,a,U=-128,V=-128)

ab.png ba.png
a-b 間の、差異がある部分のマスクを生成します。
順序を変えると別のマスクが出来上がるので、両方とも作っておきます。




■ 差分マスクを合成
mask=mt_logic(ab,ba,mode="or")

mask_ab+ba.png
2 つのマスクを合成。
mode パラメータで論理演算を or に設定して、すべての領域をマージします。




■ とりあえずブレンドクリップを作成
clip=FlexibleMerge(a,b)

clip_ab+ba.png
この時点では、○と△を無理やりブレンドしているので、乱れた映像になります。



■ ブレンドしたクリップをベースに、マスキング領域を b に置き換える
mt_merge(clip,b,mask,luma=true)

result.png
無理やりブレンドしたクリップの内、マスク領域のみ b に置き換えます。
第 2 引数を a にすることで○のクリップにすることも可能です。
これで、とりあえず目標達成です。




用編

作成したマスクは、意図したマスク外領域にアルファ値(透過率)を含んでいますので、輝度に閾値を設けて階調化します。
こうすれば一々 mt_makediff を二通り生成する必要もありません。
別途 yRangeMask を使用します。

■ マスクのアルファ領域をコントロールする関数定義
function trans_control(clip c, int "padding_range", int "fade_range") {
padding_range=default(padding_range,0)
fade_range=default(fade_range,0)
return mt_merge(BlankClip(c,color=$004D00),BlankClip(c,color=$00FF00),c.yrangemask(128-(padding_range+fade_range),fade_range,128+(padding_range+fade_range),fade_range).mt_invert(),luma=true)
}

■ 使用例
a=ImageSource("ClipA.bmp", start=0, end=0).ConvertToYV12(matrix="Rec709")
b=ImageSource("ClipB.bmp", start=0, end=0).ConvertToYV12(matrix="Rec709")
diff=mt_makediff(a, b, U=-128, V=-128)
trans_control(diff)
return last

mask_trans_control.png



総括として、簡単な差分マスク関数を書きます。

■ 差分マスク関数定義
function get_diffmask(clip a, clip b, int "padding_range", int "fade_range", int "deflate") {
padding_range=default(padding_range,0)
fade_range=default(fade_range,0)
deflate=default(deflate,2)
trans_control(mt_lutxy(a,b,"x y - 128 +",U=-128,V=-128),padding_range=padding_range,fade_range=fade_range)
return add_deflates(mt_binarize(U=-0, V=0), deflate)
}

function add_deflates(clip clip, int limit, int "cnt") {
cnt=default(cnt,0)
cnt=cnt+1
clip=limit==cnt?clip:clip.mt_deflate()
return limit==cnt?clip:add_deflates(clip, limit, cnt)
}

function trans_control(clip c, int "padding_range", int "fade_range") {
padding_range=default(padding_range,0)
fade_range=default(fade_range,0)
return mt_merge(BlankClip(c,color=$004D00),BlankClip(c,color=$00FF00),c.yrangemask(128-(padding_range+fade_range),fade_range,128+(padding_range+fade_range),fade_range).mt_invert(),luma=true)
}


■ 使用例
a=ImageSource("ClipA.bmp", start=0, end=0).ConvertToYV12(matrix="Rec709")
b=ImageSource("ClipB.bmp", start=0, end=0).ConvertToYV12(matrix="Rec709")
mask=get_diffmask(a, b)
clip=FlexibleMerge(a, b)
mt_merge(clip, b, mask, luma=true)
return last



わりに

以上の方法を活用することで、ED など映像に差異があるクリップ同士でも、可能な限りの範囲をブレンドすることが出来ます。
OP でも、油断をしていると作画修正を見逃してミスエンコードしてしまうので、細心の注意を払ってチェックし、修正箇所を見つけたら今回の手法でブレンドしてみてください。



それでは、良いエンコライフをー





出典
にわとり遊び - 2つのソースからノイズの無い部分を選んでブレンドする (FlexibleMerge) その2
メモ置き場 - yの範囲を指定してマスク


関連記事
一部のエンコオタクの間で流行っているブレンドエンコードとは?


Tag:DTV AviSynth FlexibleMerge ブレンド エンコード

この記事は DTV Advent Calendar 2015 に登録させて頂きました。

えがき

録画環境に関しての知識は全然ないので今まで見る専でしたが、エンコネタも OK ということでしたので、無い頭を絞って一筆書きます。
6日目の記事 でブレンドエンコードについて軽く採り上げられていて面白そうだったので、今回はその点にスポットを当てようと思います。





私の知る限り、これまでの DTV エンコードの常識として、ソースファイルを超える画質を出すのは不可能というのが大前提でした。
シャープネスやノイズリダクション等の画質補正で、いくらかマシに“見せる”方法はありますが、どんな処理にも大なり小なり副作用が付き物です。
しかしその前提が揺らぐ技術がとある方のブログで提示され、これまで不可能だったソースの壁を突破(厳密には違いますが)したことで、DTV エンコードの可能性に新しい光が差し込みました。
それは フレーム補完 や waifu2x のように画像を予測生成するようなものではなく、全うな方法で正しい映像を作り出すことが可能なものでした。
この技術を利用するにあたり、必要なものは AviSynth を使える知識と時間です。(メインメモリも多いほうがハッカドール)



リットとデメリット

メリット ─ トンでもなく画質が良い。ファイルサイズを大幅に削減出来る。画質調整をする必要性が減る。
デメリット ─ エンコードに時間がかかる。ソースそのものが綺麗になるので、画質調整の余地(楽しみ?)が減る。



くみ

この技術を利用するにあたり、条件が 1 つあります。
それは、映像の内容が同一であり、且つエンコードプロセスが同一ではないソースファイルを 2 つ以上用意する 事です。
つまり 同じアニメを 2 週以上に亘って録画したものの OP 映像であるとか、同じアニメの同じ話数を複数の放送局から録画したものがこれに該当します。

現在の日本の一般的な放送規格では、たとえ全く同じ映像が流れていたとしても、その時々によってノイズの乗り方が変化します。ブレンド技術はその隙を突いたもので、2 つ以上のソースからノイズ部分を補い合う形で、単一ソースでは実現不可能な画質を実現することが可能になりました。
これは単純な Merge や Overlay とは一線を画する技術です。

blend_process_map.png






手近にあった 2 本の録画データを使って、比較検証します。
今回の検証対象は、コーミング量/SSIM/PSNR/ファイルサイズ とし、ブレンド前・後の数値を出します。

ファイル①: 学○都市アスタリスク #8 (CBC) OP
ファイル②: 学○都市アスタリスク #9 (CBC) OP

コーミング量採取方法
LoadPlugin("MaskTools.dll")

AVISource("asterisk_cbc_09.raw.avi").ConvertToYV12()
WriteCombLog("asterisk_cbc_09.raw.avi.log")

return last

function WriteCombLog(clip clip, string file) {
global file=file
ScriptClip(clip, """
frame=LPad(String(Current_Frame),"0",StrLen(String(FrameCount)))
comb=LPad(String(CombCheck().AverageChromaV()),"0",10)
line=string("-")
value=frame+line+comb
WriteFile(last, file, "value",append=true)
"""
)
}

function LPad(string a, string b, int cnt){
a=strlen(a)<cnt?b+a:a
return strlen(a)<cnt?lpad(a,b,cnt):a
}

function Combcheck (clip clip, int "thr") {
thr=default(thr,10)
clip=mt_merge(Grayscale(clip),ColorYUV(Grayscale(clip),gain_u=100,gain_v=100),CombMask(clip,thY1=thr,thY2=thr),luma=true)
return clip
}


ファイルサイズ採取方法(品質固定)
x264 --preset Medium --ssim --psnr --output %out% %src% 2>%out%.log


SSIM/PSNR採取方法(ビットレート固定)
x264 --preset Medium --bitrate 6000 --qcomp 1.0 --no-mbtree --ssim --psnr --output %out% %src% 2>%out%.log


検証結果


















ファイル コーミング量 ファイルサイズ SSIM(Y) PSNR(Avg)
ファイル①
130.4182803
69,234,880
0.9732863
44.076
ファイル②
130.4626961
69,458,405
0.9734497
44.037
①+②
129.1796893
62,503,931
0.9795467
45.100


コーミング量は、コーミング 0 の状態で 128.0 という数値が出るので、差し引いて計算すると 約 52% の削減
ファイルサイズは 約 10% の削減
SSIM と PSNR も良くなっていますが、条件次第で幅は変わりそうです。ただ余程のことが無い限り成績が逆転することは無いと思います。

以上の結果になりました。とても驚異的です。



わりに

今回は 2 本のソースでのブレンドをご紹介しましたが、同じ要領で 4 本、8 本と掛け合わせていくと、更にノイズが減り、不純物の少ない良質な映像が生まれます。
一度ブレンドした映像を見てみると、あまりの綺麗さに、癖になってやめられません(汗)

今回ご紹介した記事によって、ノイズの有無が如何に画質やファイルサイズに影響しているかが分かって頂けたかと思います。
ブレンドエンコードに関して、エンコerの皆様に少しでも興味を持っていただけたら幸いです。

私は、ブレンドエンコードをする人が増えてくれると嬉しいと思っているので、もしこの記事が宣伝に良いと思っていただけたら Tweet などで知人に紹介して貰えると嬉しいです。



それでは、良いエンコライフを!






関連記事
ブレンドによる効果の程は?画像を使ってNRとの違いを検証
多少映像に違いがあっても問題なくブレンドするには?



※使用している画像は著作権フリーです

Tag:DTV AviSynth FlexibleMerge ブレンド エンコード

PulldownMerge は、各周期ごとに解除パターンが 2 通りあることを利用して DoubleWeave().Pulldown(x,y) のクリップを Merge する関数です。
Merge には、にわとり遊びさんの FlexibleMerge を使用して高画質化を狙います。

今回の記事では、DoubleWeave().Pulldown(x,y) の端数処理(終端のフレーム)が周期ごとに異なる事を考慮し、補正する為のテストをしたので結果をご紹介します。

まずは、以下が全パターンのテストケースです。

IPPPI = getClip_pulldown23().Trim(103,0)
IIPPP = getClip_pulldown23().Trim(102,0)
PIIPP = getClip_pulldown23().Trim(101,0)
PPIIP = getClip_pulldown23().Trim(100,0)
PPPII = getClip_pulldown23().Trim(104,0)

# mode=1
IPPPI_0=IPPPI.Trim(0,099)#縞
IPPPI_1=IPPPI.Trim(0,100)#重複
IPPPI_2=IPPPI.Trim(0,101)
IPPPI_3=IPPPI.Trim(0,102)
IPPPI_4=IPPPI.Trim(0,103)

# mode=2
IIPPP_0=IIPPP.Trim(0,099)
IIPPP_1=IIPPP.Trim(0,100)#縞
IIPPP_2=IIPPP.Trim(0,101)#重複
IIPPP_3=IIPPP.Trim(0,102)
IIPPP_4=IIPPP.Trim(0,103)

# mode=3
PIIPP_0=PIIPP.Trim(0,099)
PIIPP_1=PIIPP.Trim(0,100)
PIIPP_2=PIIPP.Trim(0,101)#縞
PIIPP_3=PIIPP.Trim(0,102)#重複
PIIPP_4=PIIPP.Trim(0,103)

# mode=4
PPIIP_0=PPIIP.Trim(0,099)
PPIIP_1=PPIIP.Trim(0,100)
PPIIP_2=PPIIP.Trim(0,101)
PPIIP_3=PPIIP.Trim(0,102)#縞
PPIIP_4=PPIIP.Trim(0,103)#重複

# mode=5
PPPII_0=PPPII.Trim(0,099)#重複
PPPII_1=PPPII.Trim(0,100)
PPPII_2=PPPII.Trim(0,101)
PPPII_3=PPPII.Trim(0,102)
PPPII_4=PPPII.Trim(0,103)#縞

return last

function getClip_pulldown23() {
B=BlankClip(300, 1440, 1080, "YV12", 29.970, color=$0000ff)
T=BlankClip(300, 1440, 1080, "YV12", 29.970, color=$ff0000)
Interleave(B,T)
ScriptClip("""SubTitle(String(Current_Frame),size=128)""")
SeparateFields()
SelectEvery(8,0,1,2,3,2,5,4,7,6,7)
Weave()
}



PulldownCheck では、各 mode ごとに終端縞が発生するケースを割り出し、該当のフレームを削除します。
また、重複フレームがあるパターンも存在しているので、こちらも同様に処理します。
図は解除後のフレーム数のマトリクスです。

pulldowncheck_adjustoff.gif



上記を前提とした上で、adjest=true の場合は、フレーム水増しをして、どのパターンでも均一のフレーム数になるよう補正をかけています。

pulldowncheck_adjuston.gif





関連記事
PulldownMerge関数 (11/13 17:28更新)



Tag:PulldownMerge

  PulldownMerge - 5つの周期パターンからプログレッシブクリップを選択

clip テレシネクリップ (2-2-2-4等の変則的な周期は非対応)

mode [default:0] 1 解除パターン IPPPI
2 解除パターン IIPPP
3 解除パターン PIIPP
4 解除パターン PPIIP
5 解除パターン PPPII
0 すべてのパターンを一覧表示(強制 fast モード)

fast [default:false] false FlexibleMergeでフィールドブレンドされた高画質なクリップを返します
true Mergeでブレンドされた低画質なクリップを返します(高速)

adjust [default:true] false 終端の縞と重複フレームを削除し、
すべてのフレームを一意のプログレッシブにします。
フレーム数が完全な 4/5 ではなくなります。
true 終端の縞フレームを削除し、フレーム数をすべて 4/5 に調整します。
終端に重複フレームが発生します。

※11/13 17:28更新

MergeCheckの上位互換関数です。
考え方はMergeCheckと同じですが処理を大幅に変更したので名前を変えます。

 ・MergeCheckよりもノイズの少ないクリップが出来ます。
 ・終端フレームの縞を取り除きます。

>> ダウンロード (2015/11/13 17:28 更新)



必須環境
MaskTools.dll
mt_masktools*.dll

function auto_merge_order()
function FlexibleMerge()
function Combcheck()
function NoiseExclude()

Tag:PulldownMerge

表題のとおり、テストしました。
ソースは BS11 響け!ユーフォニアム OP

ORIGINAL
orig.png

x264 111 MB (117,075,674 バイト)
x264.png

VP9 102 MB (107,194,242 バイト)
vp9.png

x264 core 142 r2431+42 c69a006 tMod [8-bit@all X86]
x264 --crf 18 --crf-max 19.0 --ipratio 1.40 --pbratio 1.30 --qcomp 0.8 --qpmin 5 --qpmax 34 --qpstep 8 --scenecut 30 --min-keyint 24 --keyint 120 --vbv-maxrate 62500 --vbv-bufsize 62500 --fgo 2 --8x8dct --partitions all --bframes 6 --b-bias 0 --b-adapt 2 --ref 9 --b-pyramid normal --mixed-refs --me umh --subme 9 --merange 32 --direct auto --threads auto --deblock -2:-2 --no-dct-decimate --trellis 2 --psy-rd 1.2:0.25 --no-fast-pskip --chroma-qp-offset 2 --deadzone-intra 6  --deadzone-inter 6 --level 4.1 --sar 1:1 --demuxer avs --colorprim "bt709" --transfer "bt709" --colormatrix "bt709" --asm AVX --ssim --psnr --input-csp "i420" --output-csp "i420" --no-mbtree --aq-mode 0 --aq-strength 0.0 --aq-sensitivity 10.0 --aq2-strength 0.0 --aq2-sensitivity 15.0 --aq2-ifactor 1.00 --aq2-pfactor 1.00 --aq2-bfactor 1.0 --aq3-mode 1 --aq3-strength -0.45:0.65 --aq3-sensitivity 15.0 --aq3-ifactor 1.0,1.0 --aq3-pfactor 1.0,1.0 --aq3-bfactor 1.0,1.0 --aq3-boundary 256:160:64

ffmpeg-2.7.1
ffmpeg -i source.avi -vcodec libvpx-vp9 -b:v 0 -acodec libopus -b:a 192k -crf 18 -qmin 0 -qmax 32 -qcomp 0.5 -keyint_min 1 -g 24 -deadline best -quality good -rc_lookahead 25 -arnr_strength 0 -max-intra-rate 0 -arnr-strength 0 -cpu-used -16 -aq-mode 1 -arnr-maxframes 0 -tile-columns 0 -tile-rows 0 -frame-parallel 0 -speed -6 -lag-in-frames 25 -f webm output.webm


x264 のほうは普段の設定を流用していて申し訳ないです。
色々試したのですが、VP9 のほうはまだまだレート制御や AQ のコントロールが不十分で、低周波領域や暗部の品質が低いです。
雨が消えてたり、制服の線が x264 に比べて表現できていませんね。

ただ、高周波領域の圧縮率は流石に圧倒的で、qmin や speed の値を調整してファイル容量を半分くらいにしても、遜色ない画質を出してくれました。

VP9 のこれからに期待。



©武田綾乃・宝島社/『響け!』製作委員会


Tag:VP9

function MergeCheck(clip clip, int "mode") {
mode=default(mode,0)
Assert(0<=mode&&mode<=5, "error.")
clip.SeparateFields()

#############################################################
# 2-3 pulldown
# 4B 4T | [1B][1T] 2B [2T][2B][3T][3B] 4T [4B][4T] | 1B 1T
# 4B 4T | [1B][1T][2B][2T] 2B [3T][3B][4T][4B] 4T | 1B 1T
# -- -- ++ ++ -- -- -- ++ ++ -- -- -- ++ ++
# -2 -1 | 00 +1 +2 +3 +4 +5 +6 +7 +8 +9 | 10 11
v1=SelectEvery(10,00,01,04,03,06,05,08,09).Weave()
v2=SelectEvery(10,00,01,02,03,06,05,08,07).Weave()
A_F=auto_merge_order(v1, v2, nmax=5)
A=Merge(v1, v2)

##############################################################
# 2-3 pulldown ( 1f back shift )
# 4T [1B] | [1T] 2B [2T][2B][3T][3B] 4T [4B][4T] 1B | 1T 2B
# 4T [1B] | [1T][2B][2T] 2B [3T][3B][4T][4B] 4T 1B | 1T 2B
# -- ++ ++ -- -- -- ++ ++ -- -- -- ++ ++ --
# -2 -1 | 00 +1 +2 +3 +4 +5 +6 +7 +8 +9 | 10 11
v1=SelectEvery(10,-1,00,03,02,05,04,07,08).Weave()
v2=SelectEvery(10,-1,00,01,02,05,04,07,06).Weave()
B_F=auto_merge_order(v1, v2, nmax=5)
B=Merge(v1, v2)

##############################################################
# 3-2 pulldown
# 4B 4T | 1B [1T][1B][2T][2B] 3T [3B][3T][4B][4T] | 1B 1T
# 4B 4T | [1B][1T] 1B [2T][2B][3T][3B] 3T [4B][4T] | 1B 1T
# -- -- ++ ++ ++ -- -- ++ ++ ++ -- -- ++ ++
# -2 -1 | 00 +1 +2 +3 +4 +5 +6 +7 +8 +9 | 10 11
v1=SelectEvery(10,02,01,04,03,06,07,08,09).Weave()
v2=SelectEvery(10,00,01,04,03,06,05,08,09).Weave()
C_F=auto_merge_order(v1, v2, nmax=5)
C=Merge(v1, v2)

##############################################################
# 3-2 pulldown ( 1f back shift )
# 4T 1B | [1T][1B][2T][2B] 3T [3B][3T][4B][4T] 1B | 1T 1B
# 4T [1B] | [1T] 1B [2T][2B][3T][3B] 3T [4B][4T] 1B | 1T 1B
# -- ++ ++ ++ -- -- ++ ++ ++ -- -- ++ ++ ++
# -2 -1 | 00 +1 +2 +3 +4 +5 +6 +7 +8 +9 | 10 11
v1=SelectEvery(10,01,00,03,02,05,06,07,08).Weave()
v2=SelectEvery(10,-1,00,03,02,05,04,07,08).Weave()
D_F=auto_merge_order(v1, v2, nmax=5)
D=Merge(v1, v2)

##############################################################
# 3-2 pulldown ( 2f back shift )
#[1B][1T] | 1B [2T][2B][3T][3B] 3T [4B][4T] 1B 1T | 1B 1T
# 1B [1T] | [1B][2T][2B] 3T [3B][3T][4B][4T] 1B 1T | 1B 1T
# -2 -1 | 00 +1 +2 +3 +4 +5 +6 +7 +8 +9 | 10 11
v1=SelectEvery(10,-2,-1,02,01,04,03,06,07).Weave()
v2=SelectEvery(10,00,-1,02,01,04,05,06,07).Weave()
E_F=auto_merge_order(v1, v2, nmax=5)
E=Merge(v1, v2)

return \
mode!=0 ? mode!=1 ? mode!=2 ? mode!=3 ? mode!=4 ? mode!=5 ? \
nop() : E_F : D_F : C_F : B_F : A_F : \
ShowFiveVersions( \
A.CombCheck().SubTitle("[2-3] (mode=1)",size=96), \
B.CombCheck().SubTitle("[2-3]-1 (mode=2)",size=96), \
C.CombCheck().SubTitle("[3-2] (mode=3)",size=96), \
D.CombCheck().SubTitle("[3-2]-1 (mode=4)",size=96), \
E.CombCheck().SubTitle("[3-2]-2 (mode=5)",size=96)).PointResize(1280,720)
}

function auto_merge_order(clip a, clip b, float "weight", float "weight2", int "mode", int "x", int "y", int "thr", int "show", int "exc", int "nmax") {
weight=default(weight,0.5)
weight2=default(weight2,0.9)
thr=default(thr,10)
nmax=default(nmax,5)
exc=default(exc,0)
show=default(show,0)

a=FlexibleMerge(a,b,weight=weight,weight2=weight2,thr=thr,nmax=nmax,exc=exc,show=show)
b=FlexibleMerge(b,a,weight=weight,weight2=weight2,thr=thr,nmax=nmax,exc=exc,show=show)
return ConditionalFilter(interleave(a,b),a,b, \
"AverageChromaV(CombCheck(SelectEven))", "<", "AverageChromaV(CombCheck(SelectOdd))")
}


関連 5 パターンの周期からプログレッシブなクリップを選ぶアレ【軽動作】



たった3つの工程で、インターレースを正しく駆逐します。

スクリプトは以下のとおり。
avspmodpre.png


上記スクリプトで行われていること。
画像は拡大して見てください。
pulldown_image.png

Tag:AviSynth

最初に言っておくと、私はNRフィルタが大嫌いなのですが
必要とあらば使用もやむなしと思っています。
ですが往々にして画質補正フィルターというのは副作用を内包していますので
必要最小限に留めておく努力が必要だと思います。

そこで、ノイズの種類に合った対処法というのを
私なりにまとめてみましたのでご紹介します。

基本的にApplyRangeなどで必要なフレームにしか使いません。




■ カラーノイズ
SmoothUV
1462b.png 1462a.png
ハイモーションエリアなどでよく見かける虹色のノイズです。
フィルタリングの副作用として色褪せが起きるので、必要なフレームにピンポイントでかけたほうが良いと思います。
放置するとビットレート食いの温床になるので、丁寧に取ったほうが良いノイズです。



■ マクロブロックノイズ
Deblock
f3kdb
1466b.png 1466a.png
MBノイズは放置すると非常に目立ち、平滑化するとディテールをぶっ壊すので対処し辛いですが
激しいシーンで一瞬だけ出てくるという場合には、思い切って均すのもアリだと思います。
f3kdbはデバンドフィルタですが、輝度差が少ないブロッキングに対してはそこそこ狙い通りの効果を発揮してくれます。
キャプのBefore/Afterではあまり違いが感じられないかもしれませんが、1倍速で再生したときの違和感はこれでもかなり解消されると思うのでお勧めです。
どうせフラットエリアでの出来事なので、mt_edgeなどでエッジを保護しながら使うと良いかもしれません。



■ コーミングノイズ
Vinverse
fPMD
967b.png 967a.png
ブロックノイズの中に見える縞々のノイズです。
放置すると汚いので対処します。
Vinverseでもいいですが、combmaskで対象エリアを拾ってfPMDをかけるとノイズを狙い撃ちできるのでよく使っています。



■ モスキートノイズ
fPMD(CombMask)
NL-Means
764b.png 764a.png
764a2.png
文字の周りなどで発生しやすいモスキートノイズ対処です。
やりすぎるとディテールを潰すので、fPMDはCombMask使ったほうが良いです。
AviUtlのNL-Meansも手軽でお勧めです。






状況に合わせて適切な対応を。


©sole;viola/Progetto 幻影太陽




WHAT'S NEW?

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。