スポンサーサイト

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

差分ブレンド関数まとめ

 13, 2015 00:35
この記事は 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 ブレンド エンコード

COMMENT - 0



WHAT'S NEW?

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