Log in

View Full Version : TemporalDegrain_ChromaMod


onesloth
4th June 2009, 19:56
#####################################################################################
#
# TemporalDegrain_ChromaMod V1.1 (7/1/2009) by Onesloth
#
# Mod of Temporal Degrain V1.23 by Didee and Sagekilla
#
# When fed chroma=false will disable all processing of chroma in TemporalDegrain()
# giving big speed boost for greyscale sources. Includes optimized adjustment of
# MTModes for scripts using SetMTMode for multithreading.
#
# Requires:
# http://avisynth.org/mediawiki/Temporal_Degrain
#
# Required for use of SetMTMode:
# http://avisynth.org/mediawiki/MT
#
# Syntax:
# chroma, SMTM, and flatsigma parameters are only syntax differences from TemporalDegrain()
# see above link for syntax explanation
#
######################################################################################

######################################################################################
#
# changelog:
#
# v1.0.1 (6/4/2009) -Changed prefilter block width and height default
# to 32 when GPU=true. Runs at same speed as 16 on my system.
# -Changed FFT3DGPU bt to 3. bt=4 appears to be broken.
# bt=3 gives much stronger denoising.
#
# v1.1 (7/1/2009) +Added optimized SetMTMode() settings. When SetMTMode is enabled -- in the
# script that calls TemporalDegrain_ChromaMod -- TD_CM will change the MTmode
# automatically for best settings. The new SMTM parameter is not neccesary to
# enable this but can be used to force the use of SetMTMode() on or off.
# +Added flatsigma parameter. Makes FFT3D prefilter use only a single sigma
# parameter equal to flatsigma value if flatsigma > 0.
# +Added switching of FFT3D plane parameter when disabling chroma processing.
#
######################################################################################


function TemporalDegrain_ChromaMod( clip input, clip "denoise", bool "GPU", int "sigma", int "bw", int "bh",
\ int "pel", int "blksize", int "ov", int "degrain", int "limit",
\ int "SAD1", int "SAD2", int "HQ", bool "chroma", bool "SMTM",
\ float "flatsigma")
{
o = input
GPU = default( GPU, false ) # Use FFT3DGPU -- helpful if you have a fast GPU
sigma = default( sigma, 16 ) # Default seems to work fine -- Higher values don't help much
bw = default( bw, ((GPU==false) ? 16 : 32) ) # FFT3D block width
bh = default( bh, ((GPU==false) ? 16 : 32) ) # FFT3D block height
pel = default( pel, 2 ) # Higher values increase motion vector quality at the cost of speed
blksize = default( blksize, 8 ) # use 16 for more speed, or for HD resolutions like 1080p
ov = default( ov, blksize/2) # Increase for better motion vectors but slower speed. Max is blksize/2
degrain = default( degrain, 2 ) # MVDegrain 1, 2 or 3
limit = default( limit, 255 ) # Limits maximum change of a pixel. Default means no limit
SAD1 = default( SAD1, 400 ) # Threshold for degraining. Decrease if you suffer from ghosting
SAD2 = default( SAD2, 300 ) # See above
HQ = default( HQ, 1 ) # How much to clean up clip for motion vector searching
s2 = floor ( sigma * 0.625 ) # See sigma
s3 = floor ( sigma * 0.375 ) # See sigma
s4 = floor ( sigma * 0.250 ) # See sigma
ow = bw / 2 # Don't adjust unless you need speed
oh = bh / 2 # See above
ov = (ov*2>blksize) ? blksize/2 : ov
chroma = default( chroma, true ) # Causes only Luma to be processed when false.
plane = (chroma) ? 4 : 0
flatsigma = default( flatsigma, 0 ) # when set > 0 will use value as only sigma when calling FFT3D

# Checks for both installation of MT.dll and use of SetMTMode() in current script.
# If MT.dll is installed, but SetMTMode() is not in use in the calling script, GetMTMode
# will return 0 and all SetMTMode() calls will be disabled.
# SMTMdefaultmode will be used to reset the MTMode to the mode of the calling script before returning.
try {
SMTMdefaultmode = GetMTMode()
SMTM = (SMTMdefaultmode!=0)
} catch(err_msg) {SMTM = false}


(SMTM) ? SetMTMode(5) : NOP()

# "filter" is a prefiltered clip on which the motion search is done.
# Here, we simply use FFT3DFilter. You can also use your own. Basically, you shouldn't use
# a clip with "a tiny bit of filtering". The search clip should ideally be "dead calm."
filter = defined(denoise)
\ ? denoise
\ : (flatsigma > 0)
\ ? (GPU)
\ ? o.FFT3DGPU(sigma=flatsigma, bt=3, bw=bw, bh=bh, ow=ow, oh=oh, plane=plane)
\ : o.FFT3DFilter(sigma=flatsigma, bt=4, bw=bw, bh=bh, ow=ow, oh=oh, plane=plane)
\ : (GPU)
\ ? o.FFT3DGPU(sigma=sigma, sigma2=s2 , sigma3=s3, sigma4=s4, bt=3, bw=bw, bh=bh, ow=ow, oh=oh, plane=plane)
\ : o.FFT3DFilter(sigma=sigma, sigma2=s2, sigma3=s3, sigma4=s4, bt=4, bw=bw, bh=bh, ow=ow, oh=oh, plane=plane)

filter = (HQ>=1)
\ ? (chroma==false)
\ ? filter.HQdn3D(4,0,6,0)
\ : filter.HQdn3D(4,3,6,3)
\ : filter


# "spat" is a prefiltered clip which is used to limit the effect of the 1st MV-denoise stage.
# For simplicity, we just use the same FFT3DFilter. There's lots of other possibilities.
spat = filter
spatD = mt_makediff(o,spat)


# Motion vector search (With very basic parameters. Add your own parameters as needed.)
srch_super = filter.MSuper(pel=pel, chroma=chroma)

(SMTM) ? SetMTMode(2) : NOP()

bvec3 = (degrain==3) ?
\ srch_super.MAnalyse(isb=true, delta=3, blksize=blksize, overlap=ov, chroma=chroma) : NOP()
bvec2 = (degrain>=2) ?
\ srch_super.MAnalyse(isb=true, delta=2, blksize=blksize, overlap=ov, chroma=chroma) : NOP()
bvec1 = srch_super.MAnalyse(isb=true, delta=1, blksize=blksize, overlap=ov, chroma=chroma)
fvec1 = srch_super.MAnalyse(isb=false, delta=1, blksize=blksize, overlap=ov, chroma=chroma)
fvec2 = (degrain>=2) ?
\ srch_super.MAnalyse(isb=false, delta=2, blksize=blksize, overlap=ov, chroma=chroma) : NOP()
fvec3 = (degrain==3) ?
\ srch_super.MAnalyse(isb=false, delta=3, blksize=blksize, overlap=ov, chroma=chroma) : NOP()


(SMTM) ? SetMTMode(5) : NOP()

# First MV-denoising stage. Usually here's some temporal-medianfiltering going on.
# For simplicity, we just use MVDegrain.
o_super = o.MSuper(pel=2, levels=1, chroma=chroma)
NR1 = (degrain==3) ? o.MDegrain3(o_super, bvec1, fvec1, bvec2, fvec2, bvec3, fvec3, thSAD=SAD1, limit=limit, plane=plane) :
\ (degrain==2) ? o.MDegrain2(o_super, bvec1, fvec1, bvec2, fvec2, thSAD=SAD1, limit=limit, plane=plane) :
\ o.MDegrain1(o_super, bvec1, fvec1, thSAD=SAD1, limit=limit, plane=plane)
NR1D = mt_makediff(o,NR1)


# Limit NR1 to not do more than what "spat" would do.
DD = mt_lutxy(spatD,NR1D,"x 128 - abs y 128 - abs < x y ?")
NR1x = (chroma==false) ? o.mt_makediff(DD) : o.mt_makediff(DD,U=2,V=2)


# Second MV-denoising stage. We use MDegrain.
NR1x_super = NR1x.MSuper(pel=2, levels=1, chroma=chroma)
NR2 = (degrain==3) ? NR1x.MDegrain3(NR1x_super, bvec1, fvec1, bvec2, fvec2, bvec3, fvec3, thSAD=SAD2, limit=limit, plane=plane) :
\ (degrain==2) ? NR1x.MDegrain2(NR1x_super, bvec1, fvec1, bvec2, fvec2, thSAD=SAD2, limit=limit, plane=plane) :
\ NR1x.MDegrain1(NR1x_super, bvec1, fvec1, thSAD=SAD2, limit=limit, plane=plane)


# Temporal filter to remove last bits of dancing pixels, YMMV.
NR2 = (HQ>=2)
\ ? (chroma==false)
\ ? NR2.HQDn3D(0,0,4,0)
\ : NR2.HQDn3D(0,0,4,1)
\ : NR2


# Contra-sharpening: sharpen the denoised clip, but don't add more than what was removed previously.
# Here: A simple area-based version with relaxed restriction. The full version is more complicated.
s = NR2.minblur(1,1) # Damp down remaining spots of the denoised clip.
allD = mt_makediff(o,NR2) # The difference achieved by the denoising.
ssD = mt_makediff(s,s.removegrain(11,-1)) # The difference of a simple kernel blur.
ssDD = ssD.repair(allD,1) # Limit the difference to the max of what the denoising removed locally.
ssDD = ssDD.mt_lutxy(ssD,"x 128 - abs y 128 - abs < x y ?") # abs(diff) after limiting may not be bigger than before.

# Apply the limited difference. (Sharpening is just inverse blurring.)
(chroma==false) ? NR2.mt_adddiff(ssDD) : NR2.mt_adddiff(ssDD,U=2,V=2)


# reset to the calling script's MTMode
(SMTM) ? SetMTMode(SMTMdefaultmode) : NOP()

output = last
return(output)
}

Would certainly appreciate hearing from anyone that sees an inappropriate change in the code.

Adub
5th June 2009, 01:55
Have you considered adding all of you mods to the Avisynth Wiki (http://avisynth.org/mediawiki/Temporal_Degrain)?

onesloth
5th June 2009, 04:44
Will do. :stupid: Probably sometime tonight.

onesloth
1st July 2009, 10:09
New version 1.1

I tested pretty much every function call in the script with SetMTModes 1, 2, and 5 and I ended up with settings that have about the same performance as a MT(TemporalDegrain()). So I'm pretty sure these are the best SetMTMode settings.

Keep in mind that TemporalDegrain is a memory hog. When I use TemporalDegrain_ChromaMod(degrain=3) in SetMTMode with 4 threads I need to use at least SetMemoryMax(768).