Mystery Keeper
24th January 2013, 10:38
When dfttestMC came out, I really loved the idea of pure temporal denoising. In fact, it seems the best way to denoise with minimal loss of details. Later I modded dfttestMC to work with new SVP pluging, which is at the very least much faster. I use it like this:
#================================================
c = separatefields()
a = c.selecteven()
b = c.selectodd()
prea=dfttest(a, sigma=16, dither=1)
preb=dfttest(b, sigma=16, dither=1)
thSAD = 150
thSCD1 = 100
thSCD2 = 84
ssxstring = """ "0.0:1.0 1.0:1.0" """
ssystring = """ "0.0:1.0 1.0:1.0" """
sststring = """ "0.0:1.0 0.01:0.0 1.0:0.0" """
sdftparams = ", smode=0, ftype=2, ssx=" + ssxstring + ", ssy=" + ssystring + ", sst=" + sststring
sanalyzeparams = ", block:{w:16, h:16, overlap:3}"
a = a.dfttestSV(pp=prea, mc=5, sbsize=1, sosize=0, pel=4, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2, dfttest_params=sdftparams, gpu=true, analyzeparams=sanalyzeparams)
b = b.dfttestSV(pp=preb, mc=5, sbsize=1, sosize=0, pel=4, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2, dfttest_params=sdftparams, gpu=true, analyzeparams=sanalyzeparams)
#around 530 - strings, fingers, gradient
#3496 - fine curtain
#8954 - shirt blur
#around 12970 - artifacts
interleave(a,b)
weave()
#================================================
QTGMC(Preset="Placebo", EdiMode="NNEDI3", ChromaEdi="", EdiQual=2, NNeurons=4, NNSize=3, NoiseProcess=0, SubPel=4, SubPelInterp=2, TrueMotion=true, Precise=true, ChromaMotion=true, GlobalMotion=true, search=5, searchparam=32).SelectEven()
GradFun3()
The idea is to eliminate all temporal frequencies except the lowest one. It worked, but still couldn't beat the strong noise on dark background. Seems like the lowest frequency is far from zero. So I added the second pass with TemporalSoften to denoising function:
# Based on motion-compensated dfttest by twc
# Aka: Really Really Really Slow
#
# Requirements:
# dfttest
# MVTools2
# SVP >= 1.0.5
#
# Suggested:
# Dither (for stack16 processing)
#
# Description of function parameters:
#
# pp = Clip to calculate vectors from (default input)
# mc = Number of frames in each direction to compensate (default 2, max 5)
# lsb = stack16 output and processing (default false)
#
# dfttest Y, U, V, sigma, sbsize, sosize, tbsize, and dither are supported.
# Extra dfttest parameters may be passed via dfttest_params.
# MVTools2 pel, thSCD, thSAD, blksize, overlap, dct, search, and
# searchparam are also supported.
#
# analyzeparams = SVAnalyze parameters in JSON format. Exclude "vector", "gpu" and "delta"
#
# sigma is the main control of dfttest strength.
# tbsize should not be set higher than mc * 2 + 1.
function dfttestSV(clip input, clip "pp", int "mc", bool "mdg", bool "Y", bool "U", bool "V", float "sigma", int "sbsize", int "sosize", int "tbsize", int "dither", bool "lsb", string "dfttest_params", int "thSAD", int "thSCD1", int "thSCD2", int "pel", bool "gpu", string "analyzeparams")
{
# Set default options. Most external parameters are passed valueless.
mc = default(mc, 2).min(5)
lsb = default(lsb, false)
Y = default(Y, true)
U = default(U, true)
V = default(V, true)
tbsize = default(tbsize, mc * 2 + 1)
dfttest_params = default(dfttest_params, "")
gpu = default(gpu, false)
sgpu = gpu ? "1" : "0"
spel = pel==4 ? "4" : pel==2 ? "2" : "1"
analyzeparams = default(analyzeparams, "")
# Set chroma parameters.
chroma = U || V
# Prepare supersampled clips.
pp_enabled = defined(pp)
sv_super = pp_enabled ? SVSuper(pp,"{gpu:" + sgpu + ", pel:" + spel + "}") : SVSuper(input,"{gpu:" + sgpu + ", pel:" + spel + "}")
pp_super = pp_enabled ? MSuper(pp, pel=pel, chroma=chroma, hpad=0, vpad=0) : MSuper(input, pel=pel, chroma=chroma, hpad=0, vpad=0)
# Motion vector search.
vec1 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:1}" + analyzeparams + "}")
vec2 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:2}" + analyzeparams + "}")
vec3 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:3}" + analyzeparams + "}")
vec4 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:4}" + analyzeparams + "}")
vec5 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:5}" + analyzeparams + "}")
b5vec = vec5.SVConvert(isb=true)
b4vec = vec4.SVConvert(isb=true)
b3vec = vec3.SVConvert(isb=true)
b2vec = vec2.SVConvert(isb=true)
b1vec = vec1.SVConvert(isb=true)
f1vec = vec1.SVConvert(isb=false)
f2vec = vec2.SVConvert(isb=false)
f3vec = vec3.SVConvert(isb=false)
f4vec = vec4.SVConvert(isb=false)
f5vec = vec5.SVConvert(isb=false)
# Motion Compensation.
b5clip = MCompensate(input, pp_super, b5vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b4clip = MCompensate(input, pp_super, b4vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b3clip = MCompensate(input, pp_super, b3vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b2clip = MCompensate(input, pp_super, b2vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b1clip = MCompensate(input, pp_super, b1vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f1clip = MCompensate(input, pp_super, f1vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f2clip = MCompensate(input, pp_super, f2vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f3clip = MCompensate(input, pp_super, f3vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f4clip = MCompensate(input, pp_super, f4vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f5clip = MCompensate(input, pp_super, f5vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
# Create compensated clip.
interleaved = mc >= 5 ? Interleave(b5clip, b4clip, b3clip, b2clip, b1clip, input, f1clip, f2clip, f3clip, f4clip, f5clip) :
\ mc == 4 ? Interleave(b4clip, b3clip, b2clip, b1clip, input, f1clip, f2clip, f3clip, f4clip) :
\ mc == 3 ? Interleave(b3clip, b2clip, b1clip, input, f1clip, f2clip, f3clip) :
\ mc == 2 ? Interleave(b2clip, b1clip, input, f1clip, f2clip) :
\ Interleave(b1clip, input, f1clip)
# Perform dfttest. Exception handling required for official dfttest.
try {
filtered = Eval("dfttest(interleaved, Y=Y, U=U, V=V, sigma=sigma, sbsize=sbsize, sosize=sosize, tbsize=tbsize, lsb=lsb" + dfttest_params + ")")
}
catch(err_msg)
{
filtered = Eval("dfttest(interleaved, Y=Y, U=U, V=V, sigma=sigma, sbsize=sbsize, sosize=sosize, tbsize=tbsize" + dfttest_params + ")")
}
# Second pass.
filtered = SelectEvery(filtered, mc * 2 + 1, mc)
b5clip = MCompensate(filtered, pp_super, b5vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b4clip = MCompensate(filtered, pp_super, b4vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b3clip = MCompensate(filtered, pp_super, b3vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b2clip = MCompensate(filtered, pp_super, b2vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b1clip = MCompensate(filtered, pp_super, b1vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f1clip = MCompensate(filtered, pp_super, f1vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f2clip = MCompensate(filtered, pp_super, f2vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f3clip = MCompensate(filtered, pp_super, f3vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f4clip = MCompensate(filtered, pp_super, f4vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f5clip = MCompensate(filtered, pp_super, f5vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
interleaved = mc >= 5 ? Interleave(b5clip, b4clip, b3clip, b2clip, b1clip, filtered, f1clip, f2clip, f3clip, f4clip, f5clip) :
\ mc == 4 ? Interleave(b4clip, b3clip, b2clip, b1clip, filtered, f1clip, f2clip, f3clip, f4clip) :
\ mc == 3 ? Interleave(b3clip, b2clip, b1clip, filtered, f1clip, f2clip, f3clip) :
\ mc == 2 ? Interleave(b2clip, b1clip, filtered, f1clip, f2clip) :
\ Interleave(b1clip, filtered, f1clip)
filtered = TemporalSoften(interleaved, mc, 7, 7, 15, 2)
return SelectEvery(filtered, mc * 2 + 1, mc)
}
I tried to encode with it. Result was very clear. But another problem came up. Somehow the script holds back small movements, so video becomes jerky. Happens both with and without second pass. What am I doing wrong?
#================================================
c = separatefields()
a = c.selecteven()
b = c.selectodd()
prea=dfttest(a, sigma=16, dither=1)
preb=dfttest(b, sigma=16, dither=1)
thSAD = 150
thSCD1 = 100
thSCD2 = 84
ssxstring = """ "0.0:1.0 1.0:1.0" """
ssystring = """ "0.0:1.0 1.0:1.0" """
sststring = """ "0.0:1.0 0.01:0.0 1.0:0.0" """
sdftparams = ", smode=0, ftype=2, ssx=" + ssxstring + ", ssy=" + ssystring + ", sst=" + sststring
sanalyzeparams = ", block:{w:16, h:16, overlap:3}"
a = a.dfttestSV(pp=prea, mc=5, sbsize=1, sosize=0, pel=4, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2, dfttest_params=sdftparams, gpu=true, analyzeparams=sanalyzeparams)
b = b.dfttestSV(pp=preb, mc=5, sbsize=1, sosize=0, pel=4, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2, dfttest_params=sdftparams, gpu=true, analyzeparams=sanalyzeparams)
#around 530 - strings, fingers, gradient
#3496 - fine curtain
#8954 - shirt blur
#around 12970 - artifacts
interleave(a,b)
weave()
#================================================
QTGMC(Preset="Placebo", EdiMode="NNEDI3", ChromaEdi="", EdiQual=2, NNeurons=4, NNSize=3, NoiseProcess=0, SubPel=4, SubPelInterp=2, TrueMotion=true, Precise=true, ChromaMotion=true, GlobalMotion=true, search=5, searchparam=32).SelectEven()
GradFun3()
The idea is to eliminate all temporal frequencies except the lowest one. It worked, but still couldn't beat the strong noise on dark background. Seems like the lowest frequency is far from zero. So I added the second pass with TemporalSoften to denoising function:
# Based on motion-compensated dfttest by twc
# Aka: Really Really Really Slow
#
# Requirements:
# dfttest
# MVTools2
# SVP >= 1.0.5
#
# Suggested:
# Dither (for stack16 processing)
#
# Description of function parameters:
#
# pp = Clip to calculate vectors from (default input)
# mc = Number of frames in each direction to compensate (default 2, max 5)
# lsb = stack16 output and processing (default false)
#
# dfttest Y, U, V, sigma, sbsize, sosize, tbsize, and dither are supported.
# Extra dfttest parameters may be passed via dfttest_params.
# MVTools2 pel, thSCD, thSAD, blksize, overlap, dct, search, and
# searchparam are also supported.
#
# analyzeparams = SVAnalyze parameters in JSON format. Exclude "vector", "gpu" and "delta"
#
# sigma is the main control of dfttest strength.
# tbsize should not be set higher than mc * 2 + 1.
function dfttestSV(clip input, clip "pp", int "mc", bool "mdg", bool "Y", bool "U", bool "V", float "sigma", int "sbsize", int "sosize", int "tbsize", int "dither", bool "lsb", string "dfttest_params", int "thSAD", int "thSCD1", int "thSCD2", int "pel", bool "gpu", string "analyzeparams")
{
# Set default options. Most external parameters are passed valueless.
mc = default(mc, 2).min(5)
lsb = default(lsb, false)
Y = default(Y, true)
U = default(U, true)
V = default(V, true)
tbsize = default(tbsize, mc * 2 + 1)
dfttest_params = default(dfttest_params, "")
gpu = default(gpu, false)
sgpu = gpu ? "1" : "0"
spel = pel==4 ? "4" : pel==2 ? "2" : "1"
analyzeparams = default(analyzeparams, "")
# Set chroma parameters.
chroma = U || V
# Prepare supersampled clips.
pp_enabled = defined(pp)
sv_super = pp_enabled ? SVSuper(pp,"{gpu:" + sgpu + ", pel:" + spel + "}") : SVSuper(input,"{gpu:" + sgpu + ", pel:" + spel + "}")
pp_super = pp_enabled ? MSuper(pp, pel=pel, chroma=chroma, hpad=0, vpad=0) : MSuper(input, pel=pel, chroma=chroma, hpad=0, vpad=0)
# Motion vector search.
vec1 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:1}" + analyzeparams + "}")
vec2 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:2}" + analyzeparams + "}")
vec3 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:3}" + analyzeparams + "}")
vec4 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:4}" + analyzeparams + "}")
vec5 = SVAnalyse(sv_super, "{vectors:3, gpu:" + sgpu + ", special:{delta:5}" + analyzeparams + "}")
b5vec = vec5.SVConvert(isb=true)
b4vec = vec4.SVConvert(isb=true)
b3vec = vec3.SVConvert(isb=true)
b2vec = vec2.SVConvert(isb=true)
b1vec = vec1.SVConvert(isb=true)
f1vec = vec1.SVConvert(isb=false)
f2vec = vec2.SVConvert(isb=false)
f3vec = vec3.SVConvert(isb=false)
f4vec = vec4.SVConvert(isb=false)
f5vec = vec5.SVConvert(isb=false)
# Motion Compensation.
b5clip = MCompensate(input, pp_super, b5vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b4clip = MCompensate(input, pp_super, b4vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b3clip = MCompensate(input, pp_super, b3vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b2clip = MCompensate(input, pp_super, b2vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b1clip = MCompensate(input, pp_super, b1vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f1clip = MCompensate(input, pp_super, f1vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f2clip = MCompensate(input, pp_super, f2vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f3clip = MCompensate(input, pp_super, f3vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f4clip = MCompensate(input, pp_super, f4vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f5clip = MCompensate(input, pp_super, f5vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
# Create compensated clip.
interleaved = mc >= 5 ? Interleave(b5clip, b4clip, b3clip, b2clip, b1clip, input, f1clip, f2clip, f3clip, f4clip, f5clip) :
\ mc == 4 ? Interleave(b4clip, b3clip, b2clip, b1clip, input, f1clip, f2clip, f3clip, f4clip) :
\ mc == 3 ? Interleave(b3clip, b2clip, b1clip, input, f1clip, f2clip, f3clip) :
\ mc == 2 ? Interleave(b2clip, b1clip, input, f1clip, f2clip) :
\ Interleave(b1clip, input, f1clip)
# Perform dfttest. Exception handling required for official dfttest.
try {
filtered = Eval("dfttest(interleaved, Y=Y, U=U, V=V, sigma=sigma, sbsize=sbsize, sosize=sosize, tbsize=tbsize, lsb=lsb" + dfttest_params + ")")
}
catch(err_msg)
{
filtered = Eval("dfttest(interleaved, Y=Y, U=U, V=V, sigma=sigma, sbsize=sbsize, sosize=sosize, tbsize=tbsize" + dfttest_params + ")")
}
# Second pass.
filtered = SelectEvery(filtered, mc * 2 + 1, mc)
b5clip = MCompensate(filtered, pp_super, b5vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b4clip = MCompensate(filtered, pp_super, b4vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b3clip = MCompensate(filtered, pp_super, b3vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b2clip = MCompensate(filtered, pp_super, b2vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
b1clip = MCompensate(filtered, pp_super, b1vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f1clip = MCompensate(filtered, pp_super, f1vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f2clip = MCompensate(filtered, pp_super, f2vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f3clip = MCompensate(filtered, pp_super, f3vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f4clip = MCompensate(filtered, pp_super, f4vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
f5clip = MCompensate(filtered, pp_super, f5vec, thSAD=thSAD, thSCD1=thSCD1, thSCD2=thSCD2)
interleaved = mc >= 5 ? Interleave(b5clip, b4clip, b3clip, b2clip, b1clip, filtered, f1clip, f2clip, f3clip, f4clip, f5clip) :
\ mc == 4 ? Interleave(b4clip, b3clip, b2clip, b1clip, filtered, f1clip, f2clip, f3clip, f4clip) :
\ mc == 3 ? Interleave(b3clip, b2clip, b1clip, filtered, f1clip, f2clip, f3clip) :
\ mc == 2 ? Interleave(b2clip, b1clip, filtered, f1clip, f2clip) :
\ Interleave(b1clip, filtered, f1clip)
filtered = TemporalSoften(interleaved, mc, 7, 7, 15, 2)
return SelectEvery(filtered, mc * 2 + 1, mc)
}
I tried to encode with it. Result was very clear. But another problem came up. Somehow the script holds back small movements, so video becomes jerky. Happens both with and without second pass. What am I doing wrong?