分页: 1 / 1

ALMerge v1.3 - Luma自适应merge(支持16-bit)

发表于 : 2012-03-04 0:40
06_taro
Luma Adaptive Merge

新基基說16bit下luma自適應的加噪點只有擼馬碉堡了
想了想好像確實如此,不爽。
於是寫了這個東西。
不過這是一個通用的luma自適應merge,
任何需要luma自適應的濾鏡都可以往裡面塞,
不一定僅僅用於加噪點什麼的。
當然也不僅僅限於16-bit,8-bit也可以正常用。

用法:
ALMerge(clip clip_a, clip clip_b, clip "clip_l",
\ int "adapt", bool "mblur",
\ bool "lsb_a", bool "lsb_b", bool "lsb_l"
\ int "Y", int "U", int "V" )

如果用於merge的clip_a與clip_b兩個clip都是8-bit,則輸出為8-bit。
當二者有至少一個為16-bit層疊時,輸出為16-bit層疊。
lsb_a/lsb_b/lsb_l可以設定輸入的clip_a/clip_b/clip_l是否為16-bit層疊。
一般來說即使不設置也可以根據分辨率自動判定,除非三個clip都是16-bit層疊的,具體見下面參數說明中的邏輯結構。
► 显示剧情透露 參數說明
► 显示剧情透露 使用舉例
► 显示剧情透露 需要的插件
Download: ALMerge_v1.4.avsi
OR
[syntax lang="avisynth" lines="f" filename="ALMerge_v1.4.avsi"]###################################################
### ###
### ALMerge.avsi ###
### ###
### By 06_taro ( astrataro@gmail.com ) ###
### ###
### v1.4 - 05 July 2012 ###
### ###
###################################################
###
###
### Merge with Luma mask
### Support both 8-bit precision and stacked 16-bit precision
###
###
### +-------------+
### | CHANGELOG |
### +-------------+
###
### v1.4 - 05 July 2012:
### - Re-use RemoveGrain, as it is still faster than blur or GaussResize
### - Fix potential regression when handling Y8
###
### v1.3 - 12 April 2012:
### - Added support for Y8/YV16/YV24 and removed RemoveGrain requirement, by replacing RemoveGrain with GaussResize
###
### v1.2 - 27 March 2012:
### - Adjusted merge16_8 usage to latest version of dither package
###
### v1.1 - 13 March 2012:
### - Fully support Y/U/V in -65535~5 of 16-bit merge
### - Change default U/V to 2, which is correct for merge, previous 1 generated garbage if used as final result
###
### v1.0 - 03 March 2012:
### - First script
###
###
### +----------------+
### | REQUIREMENTS |
### +----------------+
###
### -> Masktools2 (v2a48)
### -> RemoveGrain (v1.0pre)
### -> dither (dll only, v1.18.1)
###
###
### +-------+
### | USAGE |
### +-------+
###
### ALMerge(clip clip_a, clip clip_b, clip "clip_l",
### \ int "adapt", bool "mblur",
### \ bool "lsb_a", bool "lsb_b", bool "lsb_l"
### \ int "Y", int "U", int "V" )
###
### Takes luma value from clip_l to make luma mask,
### then merge clip_a and clip_b as mt_merge does.
###
### If both clip_a and clip_b are normal 8-bit clips, output is normal 8-bit clip.
### Otherwise output is stacked 16-bit clip.
###
### Example(Luma adaptive deband):
### ALMerge(f3kdb(output_depth=16), last, U=3, V=3)
###
###
### +-----------+
### | GENERAL |
### +-----------+
###
### clip_a, clip_b [clip, not named arguments, cannot be omitted]
### ------------------
### The two clips to be merged
###
### clip_l [clip, default=clip_b]
### ------------------
### The clip where luma value is taken from
###
### adapt [int(0~255), default=64]
### -------------------
### luma-adaptative threshold ( value in 8-bit precision )
### 0 = source, the brighter the more taken from clip_b, and the darker the more taken from clip_a
### ..
### 255 = invert, the brighter the more taken from clip_a, and the darker the more taken from clip_b
###
### mblur [bool, default=true]
### ------------------
### Apply blurring to luma mask or not
###
### lsb_a, lsb_b, lsb_l [bool]
### ------------------
### Input clip is stacked 16-bit if set to true, normal 8-bit if set to false
### Should be automatically set correctly, unless all three clips are stacked 16-bit
### Default:
### lsb_a = (clip_a.height==2*clip_b.height || clip_a.height==2*clip_l.height) ? true :
### (clip_a.width / clip_a.height > 1.2) ? false :
### true
### lsb_b = (clip_b.height==2*clip_a.height || clip_b.height==2*clip_l.height) ? true :
### (clip_b.height==clip_a.height) ? lsb_a :
### (clip_b.width / clip_b.height > 1.2) ? false :
### true
### lsb_l = (clip_l.height==2*clip_a.height || clip_l.height==2*clip_b.height) ? true :
### (clip_l.height==clip_b.height) ? lsb_b :
### (clip_l.height==clip_a.height) ? lsb_a :
### (clip_l.width / clip_l.height > 1.2) ? false :
### true
###
### Y, U, V [int]
### ------------------
### Same as mt_merge if both clip_a and clip_b are normal 8-bit clips, otherwise same as Dither_merge16_8
### Default:
### Y=3
### U=2
### V=2
###
###


Function ALMerge(clip clip_a, clip clip_b, clip "clip_l",
\ int "adapt", bool "mblur",
\ bool "lsb_a", bool "lsb_b", bool "lsb_l",
\ int "Y", int "U", int "V" ) {

clip_l = Default( clip_l, clip_b )
adapt = Default( adapt, 64 )
mblur = Default( mblur, true )

width_a = clip_a.width
width_b = clip_b.width
width_l = clip_l.width

height_a = clip_a.height
height_b = clip_b.height
height_l = clip_l.height

lsb_a = ( height_a == height_b * 2 || height_a == height_l * 2 ) ? Default( lsb_a, true ) :
\ ( width_a > height_a * 1.2 ) ? Default( lsb_a, false ) :
\ Default( lsb_a, true )

lsb_b = ( height_b == height_a * 2 || height_b == height_l * 2 ) ? Default( lsb_b, true ) :
\ ( height_b == height_a ) ? Default( lsb_b, lsb_a ) :
\ ( width_b > height_b * 1.2 ) ? Default( lsb_b, false ) :
\ Default( lsb_b, true )

lsb_l = ( height_l == height_a * 2 || height_l == height_b * 2 ) ? Default( lsb_l, true ) :
\ ( height_l == height_b ) ? Default( lsb_l, lsb_b ) :
\ ( height_l == height_a ) ? Default( lsb_l, lsb_a ) :
\ ( width_l > height_l * 1.2 ) ? Default( lsb_l, false ) :
\ Default( lsb_l, true )

Y = Default( Y, 3 )
U = Default( U, 2 )
V = Default( V, 2 )

Assert( adapt>=0 && adapt<=255, "ALMerge: invalid value for adapt(0~255)!" )

high_p = ( lsb_a || lsb_b ) ? true : false

clip_a = ( high_p && !lsb_a ) ? clip_a.ALM_convert_8_to_16 : clip_a
clip_b = ( high_p && !lsb_b ) ? clip_b.ALM_convert_8_to_16 : clip_b

clip_l = lsb_l ? clip_l.DitherPost(mode=0, ampn=0, U=1, V=1) : clip_l
height_l = lsb_l ? height_l / 2 : height_l

Lmask = adapt==0 ? clip_l
\ : adapt==255 ? clip_l.mt_invert(U=1, V=1)
\ : clip_l.mt_lut("x "+string(adapt)+" - abs 255 * "+string(adapt)+" 128 - abs 128 + /", U=1, V=1)

Lyv12 = Lmask.IsYV12

try {
Lmask = mblur ? Lyv12 ? Lmask.RemoveGrain(19, -1)
\ : Eval( """Lmask.ConvertToYV12(chromaresample="point").RemoveGrain(19, -1).ConvertTo"""
\ + ALM_GetCSP(Lmask)
\ + """(chromaresample="point")""" )
\ : Lmask
} catch ( e ) {
Lmask = mblur ? Lyv12 ? Lmask.RemoveGrain(19, -1)
\ : Eval( "Lmask.ConvertToYV12.RemoveGrain(19, -1).ConvertTo"
\ + ALM_GetCSP(Lmask) )
\ : Lmask
}

### luma=true cannot be used with Y8/YV16/YV24 in mt_merge, and luma=true always overrides U/V
### +--------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
### | U == 3 | True | True | True | True | True | True | True | True | False | False | False | False | False | False | False | False |
### | V == 3 | True | True | True | True | False | False | False | False | True | True | True | True | False | False | False | False |
### | IsYV12 | True | True | False | False | True | True | False | False | True | True | False | False | True | True | False | False |
### | high_p | True | False | True | False | True | False | True | False | True | False | True | False | True | False | True | False |
### +--------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
### | luma | True | True | True | False | False | False | False | False | False | False | False | False | False | False | False | False |
### | copy | False | False | False | True | True | True | True | True | True | True | True | True | False | False | False | False |
### +--------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
### luma: "luma" in mt_merge / ALM_merge16_8
### copy: copy luma plane to chroma planes in Lmask or not

luma = U==3 && V==3 && ( Lyv12 || high_p ) ? True : False
Lmask = !luma && ( U==3 || V==3 ) && ALM_GetCSP(Lmask) != "Y8" ? Lmask.MergeChroma( Lmask.YToUV(Lmask).BilinearResize(width_l, height_l) )
\ : Lmask

return high_p ? ALM_merge16_8(clip_a, clip_b, Lmask, luma=luma, Y=Y, U=U, V=V)
\ : mt_merge(clip_a, clip_b, Lmask, luma=luma, Y=Y, U=U, V=V)
}


# ------- Support functions for stacked high bit depth -------

Function ALM_get_msb(clip src){ return src.Crop(0, 0, src.Width, src.Height/2) }
Function ALM_get_lsb(clip src){ return src.Crop(0, src.Height/2, src.Width, src.Height/2) }
Function ALM_convert_8_to_16(clip src){ return StackVertical(src, BlankClip(src, color_yuv=0)) }

Function ALM_merge16_8(clip src1, clip src2, clip mask, bool "luma", int "y", int "u", int "v"){
luma = Default(luma, false)

y = Default(y, 3)
u = Default(u, 2)
v = Default(v, 2)

mask16 = StackVertical(mask, mask)
Dither_merge16(src1, src2, mask16, luma=luma, y=y, u=u, v=v)
}

FUNCTION ALM_GetCSP(clip c) {
return c.IsPlanar ? c.IsYV12 ? "YV12" :
\ c.IsYV16 ? "YV16" :
\ c.IsYV24 ? "YV24" : c.ALM_Separate_Y8_YV411 :
\ c.IsYUY2 ? "YUY2" :
\ c.IsRGB32 ? "RGB32" :
\ c.IsRGB24 ? "RGB24" : "Unknown"
}

FUNCTION ALM_Separate_Y8_YV411(clip c) {
try {
c.UtoY
csp = "YV411"
} catch ( error_msg ) {
csp = "Y8"
}
return csp
}
[/syntax]

Re: ALMerge - Luma自适应merge(支持16-bit)

发表于 : 2012-03-04 7:54
msg7086
\泰罗碉堡了/

Re: ALMerge - Luma自适应merge(支持16-bit)

发表于 : 2012-03-14 8:03
06_taro
1.1
完全支持Y/U/V=-65535~5的標準mt_merge樣式的值域。默認U/V改為2,防止用1在U/V上得到的是garbage。

Re: ALMerge v1.3 - Luma自适应merge(支持16-bit)

发表于 : 2012-04-14 7:08
06_taro
v1.2
ALM_merge16_8隨dither package更新

v1.3
支持Y8/Y16/Y24,不再需要RemoveGrain