# LTSLP(): "LimitedTemporalSoften, LowPass-protected" # # Basically a normal TemporalSoften(), with some additional twists. # Normal TemporalSoften(), with low thresholds, doesn't catch all noise. With high thresholds, it kills # detail, and creates smearing & banding. # LTSLP allows *much* higher thresholds, thus catching all noise, while keeping more detail, and # creating very little smearing or banding. (High limits will flatten down moving parts, though.) # # Requires: - MaskTools >= v1.5.6 (at time of writing this: http://manao4.free.fr/ ) # - RemoveGrain >= v0.6 (at time of writing this: http://www.removegrain.de.tf/ ) # # Fiddled together by Didée, for your pleasure ;-) function LTSLP( clip clp, int "frames", int "threshY", int "threshC", int "maxvar", int "TSmode", \ int "limitY", int "limitC", float "radius", int "cl1", int "cl2") { frames = default( frames, 2 ) # \ threshY = default( threshY,23 ) # | threshC = default( threshC,23 ) # |- exactly the same parameters as in normal TemporalSoften(). maxvar = default( maxvar, 23 ) # | (thresh's & maxvar may be this high and even more, because of the TSmode = default( TSmode, 2 ) # / limiting and the lowpass protection) limitY = default( limitY, 2 ) # - maximum pixel change to luma plane (but: plus 'cl2') limitC = default( limitC, 2 ) # - maximum pixel change to chroma plane radius = default( radius,2.0 ) # - lowpass protection: radius for gaussian blur # (smaller radius -> less smearing, but less NR / and vice versa) cl1 = default( cl1, 0 ) # - pre-calming (luma only) by limited clense(). This is also lowpass protected. cl2 = default( cl2, 0 ) # - post-calming (luma only) by limited clense(). This is NOT lowpass protected, hence may smear.! ox = clp.width oy = clp.height uv = (limitC==0 || limitC==255) ? 1 : 3 uv2 = (limitC==0 || limitC==255) ? 2 : 3 LLy = string(limitY) LLc = string(limitC) CL1y= string(cl1) CL2y= string(cl2) pre = (cl1==0) ? clp \ : yv12lutxy(clp,clp.clense(),"x "+CL1y+" + y < x "+CL1y+" + x "+CL1y+" - y > x "+CL1y+" - y ? ?",U=2,V=2) ts = pre.temporalsoften( frames,threshY,threshC,maxvar,TSmode) d = yv12lutxy(clp, ts, \ "x y - abs "+LLy+" < x y - 128 + 128 "+LLy+" x y - x y - abs / * + ?", \ "x y - abs "+LLc+" < x y - 128 + 128 "+LLc+" x y - x y - abs / * + ?", \ "x y - abs "+LLc+" < x y - 128 + 128 "+LLc+" x y - x y - abs / * + ?", U=uv2,V=uv2) d2 = yv12lutxy(d, d.RemoveGrain(4) .BicubicResize( m4(ox/radius), m4(oy/radius)) \ .RemoveGrain(4) .BicubicResize( ox, oy, 1,0),"x y - 128 +","x y - 128 +","x y - 128 +", U=uv,V=uv) yv12lutxy(clp,d2,"x y 128 - -","x y 128 - -","x y 128 - -",U=uv2,V=uv2) (cl2==0) ? last : yv12lutxy(last,last.clense(),"x "+CL2y+" + y < x "+CL2y+" + x "+CL2y+" - y > x "+CL2y+" - y ? ?",U=2,V=2) return(last) } #------- function m4(float x) {return( x<16?16:int(round(x/4.0)*4)) }