Didée
3rd March 2013, 18:06
Yeah, that sort of "static grain" is a very common issue when the source starts with really strong grain, and the main denoising process is temporal filtering. It's hard to come by, unless some sort of spatial denoising/smoothing is thrown into the chain. But with spatial denoising in the game, it is very likely to cause blurring real detail where you don't want to have it.
Another approach:
-edit-
(Buggy script) -- Split_slowdenoise-3c_CRF18.mkv (http://www46.zippyshare.com/v/15469608/file.html) (31 MB)
(Correct script) -- Split_slowdenoise-3d_CRF18.mkv (http://www50.zippyshare.com/v/81622533/file.html) (29 MB)
This issues mainly temporal filtering, with additional spatial pre-filtering, masked to target by brightness/chroma masking.
Compressibility is somewhat lower than before (now 14500 13570 kbit/s @ CRF18/slow/film, compared to 36000 without filtering). Detail retention is different than before - a little less here, a little more there. In overall balance, I think it is better than before.
The used script. It is very slow, and it's possible that you cannot use it in a direct script-->x264 chain when using x264 with "exhaustive" settings (in particular high mbtree lookahead). :)
edit: corrected vector bug (delta value)
SetMemoryMax(1000)
# LoadPlugin( ...
#
# MVTools2.dll
# mt_masktools-25.dll
# RemoveGrain.dll
# Repair.dll
# MedianBlur.dll
pel1 = 1 # you can use pel=2,
pel2 = 1 # but with pel=1 the script is already slow & memory-hungry enough ...
dgsource("G:\Split.dgi")
changefps(last,last,true)
o = last ox=o.width() oy=o.height()
pre01 = o.sbr()
pre02 = pre01.medianblur(2,0,0)
pre03 = o.mt_makediff(mt_makediff(pre01,pre01.removegrain(4,-1)),U=2,V=2).sbr()
msk = mt_lutxy(o.utoy(),o.vtoy(),"x 128 - 0 1 - * 128 + y + 2 / 148 - 16 *").greyscale()
brite = pre02. levels(80,1.0,160,0,255,false).greyscale()
brite = brite.bicubicresize(ox/2,oy/2)
brite2 = brite.repair(brite.repair(brite.mt_inpand().mt_inpand().mt_inpand().mt_inpand().mt_expand().mt_expand().mt_expand().mt_expand(),1,0),12,0)
bmask = mt_lutxy(brite2.mt_inpand(),msk.mt_expand(),"x y -").mt_expand().removegrain(20).greyscale()
\ .bicubicresize(ox,oy,1,0)
sss1 = mt_lutxy(pre02,o,"x x y - abs 1 1.22 / ^ 0.51 * x y - x y - abs 0.001 + / * -",U=2,V=2)
sss2 = sss1.temporalsoften(2,12,12,20,2).merge(pre02,0.14)
sss3 = sss1.mt_merge(sss2,bmask,luma=true,U=3,V=3)
sup0 = sss3.msuper(pel=pel1)
sup1 = o.msuper(pel=pel1,levels=1)
bv02 = sup0.manalyse(isb=true, delta=2,blksize=16,overlap=8 , search=5)#,searchparam=8,DCT=5)
bv01 = sup0.manalyse(isb=true, delta=1,blksize=16,overlap=8 , search=5)#,searchparam=8,DCT=5)
fv01 = sup0.manalyse(isb=false,delta=1,blksize=16,overlap=8 , search=5)#,searchparam=8,DCT=5)
fv02 = sup0.manalyse(isb=false,delta=2,blksize=16,overlap=8 , search=5)#,searchparam=8,DCT=5)
mdg1 = o.mdegrain2(sup1,bv01,fv01,bv02,fv02,thsad=400)
mdg1a = mdg1.mt_makediff(mt_makediff(mdg1,o).bicubicresize(ox/4,oy/4).bicubicresize(ox,oy,1,0),U=2,V=2)
mdg1aD = mt_makediff(o,mdg1)
pre02oD= mt_makediff(o,pre02)
xDD = pre02oD.repair(mdg1aD,12)
spat2 = o.mt_makediff(xDD,U=2,V=2).minblur(0,2)
spat2 = mt_lutxy(spat2,o,"x 1 + y < x 2 + x 1 - y > x 2 - y ? ?",U=2,V=2)
spat2 = o.mt_merge(spat2,bmask,luma=true,U=3,V=3)
sup10 = mdg1.msuper(pel=pel2)
sup11 = spat2.FSx(mode=-1,sstr=2.0,cstr=-2.0,xstr=0.0).msuper(pel=pel2,sharp=1,levels=1)
bv4 = sup0.manalyse(isb=true, delta=4,blksize=16,overlap=8 , search=4,searchparam=1,DCT=5)
bv3 = sup0.manalyse(isb=true, delta=3,blksize=16,overlap=8 , search=5,searchparam=8,DCT=5)
bv2 = sup0.manalyse(isb=true, delta=2,blksize=16,overlap=8 , search=5,searchparam=8,DCT=5)
bv1 = sup0.manalyse(isb=true, delta=1,blksize=16,overlap=8 , search=5,searchparam=8,DCT=5)
fv1 = sup0.manalyse(isb=false,delta=1,blksize=16,overlap=8 , search=5,searchparam=8,DCT=5)
fv2 = sup0.manalyse(isb=false,delta=2,blksize=16,overlap=8 , search=5,searchparam=8,DCT=5)
fv3 = sup0.manalyse(isb=false,delta=3,blksize=16,overlap=8 , search=5,searchparam=8,DCT=5)
fv4 = sup0.manalyse(isb=false,delta=4,blksize=16,overlap=8 , search=4,searchparam=1,DCT=5)
spat2.removegrain(11,0).mdegrain3(sup11,bv1,fv1,bv2,fv2,bv4,fv4,thsad=800)
mdg23 = last
mt_makediff(mt_makediff(last,spat2).bicubicresize(ox/4,oy/4).bicubicresize(ox,oy,1,0),U=2,V=2)
mt_lutxy(o,"x 4 + y < x 3 + x 4 - y > x 3 - x 0.49 * y 0.51 * + ? ?",U=3,V=3)
last.mt_merge(mdg23,bmask,luma=true,U=3,V=3)
mt_lutxy(sbr(),"x 4 + y < x 3 + x 4 - y > x 3 - x 0.51 * y 0.49 * + ? ?",U=2,V=2)
return(last)
# =========================================
# =========================================
# Helper functions
function sbr(clip o)
{
rg11=o.removegrain(11)
rg11D=mt_makediff(o,rg11)
rg11DD=mt_makediff(rg11D,rg11D.removegrain(11)).mt_lutxy(rg11D,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?")
o.mt_makediff(rg11DD,U=2,V=2)
}
function MinBlur(clip clp, int r, int "uv")
{
uv = default(uv,3)
uv2 = (uv==2) ? 1 : uv
rg4 = (uv==3) ? 4 : -1
rg11 = (uv==3) ? 11 : -1
rg20 = (uv==3) ? 20 : -1
medf = (uv==3) ? 1 : -200
RG11D = (r==0) ? mt_makediff(clp,clp.sbr(),U=uv2,V=uv2)
\ : (r==1) ? mt_makediff(clp,clp.removegrain(11,rg11),U=uv2,V=uv2)
\ : (r==2) ? mt_makediff(clp,clp.removegrain(11,rg11).removegrain(20,rg20),U=uv2,V=uv2)
\ : mt_makediff(clp,clp.removegrain(11,rg11).removegrain(20,rg20).removegrain(20,rg20),U=uv2,V=uv2)
RG4D = (r==1) ? mt_makediff(clp,clp.repair(clp.removegrain(4,rg4),14),U=uv2,V=uv2)
\ : (r==2) ? mt_makediff(clp,clp.medianblur(2,2*medf,2*medf),U=uv2,V=uv2)
\ : mt_makediff(clp,clp.medianblur(3,3*medf,3*medf),U=uv2,V=uv2)
DD = mt_lutxy(RG11D,RG4D,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=uv2,V=uv2)
clp.mt_makediff(DD,U=uv,V=uv)
return(last)
}
function FSx(clip c, int "mode", float "sstr", float "cstr", float "xstr", float "lstr", float "pstr")
{
mode = default(mode, 1 ) # 1 to 3, weakest to strongest. When negative -1 to -3, a broader kernel for equalisation is used.
sstr = default(sstr, 2.0 ) # strength of sharpening, 0.0 up to ??
_cstr = spline(sstr, 0,0, 0.5,0.1, 1.0,0.6, 2.0,0.9, 2.5,1.09, 3.0,1.15, 3.5,1.19, 4.0,1.249, 8.0,1.5, 255.0,2.0)
cstr = default(cstr, _cstr)
xstr = default(xstr, 0.19 )
lstr = default(lstr, 4.0 )
pstr = default(pstr, 1.6)
str1 = sstr
str2 = cstr
SSTR = string(abs(sstr))
CSTR = string(abs(cstr))
LSTR = string(abs(lstr))
PSTR = string(abs(pstr))
rg=mode>0?11:20
b = (abs(mode)==1) ? c.removegrain(11,-1).removegrain(4,-1)
\ : (abs(mode)==2) ? c.removegrain(4,-1).removegrain(11,-1)
\ : (abs(mode)==3) ? c.removegrain(4,-1).removegrain(11,-1).removegrain(4,-1) : c
shrpD = mt_lutxy(c,b,"x y - abs "+LSTR+" / 1 "+PSTR+" / ^ "+LSTR+" * "+SSTR+" * x y - x y - abs 0.001 + / * x y - 2 ^ x y - 2 ^ "+SSTR+" 4.0 * + / * 128 +")
shrp = (str1<0.01) ? c : c.mt_adddiff(shrpD,U=2,V=2)
bzzD = (str2>0.0) ? shrpD.mt_lut("x 128 - "+CSTR+" * 128 +").removegrain(rg,-1)
\ : shrpD.mt_lut("x 128 - "+CSTR+" * 128 +").removegrain(11,-1).removegrain(20*1,-1)
shrp = (abs(str2)<0.01) ? shrp : shrp.mt_makediff(bzzD,U=2,V=2)
shrp = (xstr<0.01) ? shrp
\ : mt_lutxy(shrp,shrp.removegrain(20,-1),"x x y - 9.9 * +").repair(shrp,12,0).mergeluma(shrp,1.0-xstr)
return(shrp)
}
I think I like the result for the most part ... but at THAT speed, it would be out-of-question for me to use it. 1080p simply is not what you want to make any complicated MVTools-denoising with.
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.