Log in

View Full Version : Motion Compensated Sharpening


Pages : 1 [2]

*.mp4 guy
15th January 2011, 13:33
Yeah that script is quite old (4 years? to lazy to find the original thread) at the time I was still not so great at the mechanics of avisynth (hence the silliness with spline36). The temporal component of fft3d/degrainmedian however was intentional, iirc it was because at the time I was having trouble with low frequency flicker in areas that mvtools didn't want to work on, so I had to use temporal filtering in the fallback "spatial" method.

I have generally avoided posting the version of that script I actually use now because it is both excessive and dependent on bulky custom functions... but as long as my my work is being impugned :p

script:
str=1#strength of predictionfilter, don't change
source = last
pred_ = Source.fft3dfilter(bw=6, bh=6, ow=3, oh=3, bt=1, sigma=str, plane=4).fft3dfilter(bw=216, bh=216, ow=108, oh=108, bt=1, sigma=str/8, sigma2=str/4, sigma3=str/2, sigma4=str, plane=4).TblurNL(rad=2, thresh=4)#comment out tblurnl if you don't have residual low frequency blotchiness which fft3d loves to leave on everything
pred = pred_.ttempsmooth(maxr=7).gradfun2db(1.01)#hqdn3d(0.1, 0.1, 1.5, 1.5).gradfun2db(1.01) is faster and nearly as good, except on scene changes

backward_vec2 = pred.MVAnalyse(isb = true, delta = 2, pel = 4, overlap=4, sharp=2, idx = 1, truemotion=true, dct=5)
backward_vec1 = pred.MVAnalyse(isb = true, delta = 1, pel = 4, overlap=4, sharp=2, idx = 1, truemotion=true, dct=5)
forward_vec1 = pred.MVAnalyse(isb = false, delta = 1, pel = 4, overlap=4, sharp=2, idx = 1, truemotion=true, dct=5)
forward_vec2 = pred.MVAnalyse(isb = false, delta = 2, pel = 4, overlap=4, sharp=2, idx = 1, truemotion=true, dct=5)

maskp1 = mvmask(kind=1, vectors=forward_vec1, ysc=255).UtoY()
maskp2 = mvmask(kind=1, vectors=forward_vec2, ysc=255).UtoY()
maskp3 = mvmask(kind=1, vectors=backward_vec1, ysc=255).UtoY()
maskp4 = mvmask(kind=1, vectors=backward_vec2, ysc=255).UtoY()
maskf = average(maskp1, 0.25, maskp2, 0.25, maskp3, 0.25, maskp4, 0.25).spline36resize(source.width, source.height)

smooth = pred_.gradfun2db(1.01)
source2 = MT_Merge(source, smooth, maskf)

source3 = source2.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400,idx=2)
source3
VagueDenoiser(method=4, nsteps=10, wavelet=2, Wiener=true, auxclip=pred, percent=95, chromaT=1.0, wratio=0.75, threshold=0.5)#remove temporally blurred high frequency crud, can cause blocking upon reencode
gradfun2db(1.01)

required functions:
Function TblurNL(Clip c, int "thresh", float "thresh2", float "thresh3", int "rad")
{
Rad = Default(Rad, 1)

B1 = C.NLLH(1*Rad)
B2 = B1.NLLV(1*Rad)
B3 = B2.NLLH(2*Rad)
B4 = B3.NLLV(2*Rad)
B5 = B4.NLLH(3*Rad)
B6 = B5.NLLV(3*Rad)


Thresh = Default(Thresh, 8)
Thresh2 = Default(Thresh2, Thresh/4)
Thresh3 = Default(Thresh3, Thresh/9)

Thresh1 = Thresh
Thresh2 = Thresh
Thresh3 = Thresh2
Thresh4 = Thresh2
Thresh5 = Thresh3
Thresh6 = Thresh3


Mt_LutXY(b5, b6, " X Y - abs 1 + X Y - abs 1 + * X Y - * X Y - abs 1 + X Y - abs 1 + * "+string(thresh6)+" + / 128 +", u=1, v=1)
Mt_AddDiff(last, b6, u=1, v=1)
b5 = last

Mt_LutXY(b4, b5, " X Y - abs 1 + X Y - abs 1 + * X Y - * X Y - abs 1 + X Y - abs 1 + * "+string(thresh5)+" + / 128 +", u=1, v=1)
Mt_AddDiff(last, b5, u=1, v=12)
b4 = last

Mt_LutXY(b3, b4, " X Y - abs 1 + X Y - abs 1 + * X Y - * X Y - abs 1 + X Y - abs 1 + * "+string(thresh4)+" + / 128 +", u=1, v=1)
Mt_AddDiff(last, b4, u=1, v=1)
b3 = last


Mt_LutXY(b2, b3, " X Y - abs 1 + X Y - abs 1 + * X Y - * X Y - abs 1 + X Y - abs 1 + * "+string(thresh3)+" + / 128 +", u=1, v=1)
Mt_AddDiff(last, b3, u=1, v=1)
b2 = last

Mt_LutXY(b1, b2, " X Y - abs 1 + X Y - abs 1 + * X Y - * X Y - abs 1 + X Y - abs 1 + * "+string(thresh2)+" + / 128 +", u=1, v=1)
Mt_AddDiff(last, b2, u=1, v=1)
b1 = last

Mt_LutXY(C, b1, " X Y - abs 1 + X Y - abs 1 + * X Y - * X Y - abs 1 + X Y - abs 1 + * "+string(thresh1)+" + / 128 +", u=1, v=1)
Mt_AddDiff(last, b1, u=1, v=1)
}

Function NLLH(Clip C, int "rad")
{


Rad = Default(Rad, 1)

B1 = C.BlurH(1*rad, 0.439)
B2 = C.BlurH(3*rad, 0.833)
B3 = C.BlurH(5*rad, 0.934)
B4= C.BlurH(7*rad, 0.983)

B1_D = Mt_Makediff(B1, C, u=1, v=1)
B2_D = Mt_MakeDiff(C, B2, u=1, v=1)
B3_D = Mt_MakeDiff(B3, C, u=1, v=1)
B4_D = Mt_MakeDiff(C, B4, u=1, v=1)

B2_DT = Mt_LutXY(B1_D, B2_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 1.915 * X 128 - abs - 0 > Y 128 - abs 1.915 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
B3_DT = Mt_LutXY(B2_DT, B3_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.025 * X 128 - abs - 0 > Y 128 - abs 2.025 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
B4_DT = Mt_LutXY(B3_DT, B4_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.077 * X 128 - abs - 0 > Y 128 - abs 2.077 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)

Mt_AddDiff(B4_DT, C)

Return(last)
}

Function NLLV(Clip C, int "rad")
{


Rad = Default(Rad, 1)

B1 = C.BlurV(1*rad, 0.439)
B2 = C.BlurV(3*rad, 0.833)
B3 = C.BlurV(5*rad, 0.934)
B4= C.BlurV(7*rad, 0.983)

B1_D = Mt_Makediff(B1, C, u=1, v=1)
B2_D = Mt_MakeDiff(C, B2, u=1, v=1)
B3_D = Mt_MakeDiff(B3, C, u=1, v=1)
B4_D = Mt_MakeDiff(C, B4, u=1, v=1)

B2_DT = Mt_LutXY(B1_D, B2_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 1.915 * X 128 - abs - 0 > Y 128 - abs 1.915 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
B3_DT = Mt_LutXY(B2_DT, B3_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.025 * X 128 - abs - 0 > Y 128 - abs 2.025 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)
B4_DT = Mt_LutXY(B3_DT, B4_D, " X 128 - Y 128 - X 128 - abs Y 128 - abs * 1 + * X 128 - abs Y 128 - abs * Y 128 - abs 2.077 * X 128 - abs - 0 > Y 128 - abs 2.077 * X 128 - abs - 0 ? X 128 - abs 0 > X 128 - abs -1 X 128 - abs 0 > X 128 - 1 ? / ^ 1 ? / 1 * + 1 + / + 128 + ", u=1, v=1)

Mt_AddDiff(B4_DT, C)

Return(last)
}

This script is much more aggressive then the old one, this happened because I generally apply sharpening before denoising, and because x264 has hated noise, still hates noise, and noise will always be expensive to encode. I decided it was better to lose a bit of detail to denoising then to lose it to artifacts later, or be stuck with an encode that is barely smaller then the source.

[edit] this looks really wide on the forums...but I have a widescreen monitor and /lazy/

Vitaliy Gorbatenko
16th January 2011, 09:27
This is a valid change for mvtools2?

function MCSharpening(clip source)
{
str=1#strength of predictionfilter, don't change
#source = last
pred_ = Source.fft3dfilter(bw=6, bh=6, ow=3, oh=3, bt=1, sigma=str, plane=4).fft3dfilter(bw=216, bh=216, ow=108, oh=108, bt=1, sigma=str/8, sigma2=str/4, sigma3=str/2, sigma4=str, plane=4).TblurNL(rad=2, thresh=4)#comment out tblurnl if you don't have residual low frequency blotchiness which fft3d loves to leave on everything
pred = pred_.ttempsmooth(maxr=7).gradfun2db(1.01)#hqdn3d(0.1, 0.1, 1.5, 1.5).gradfun2db(1.01) is faster and nearly as good, except on scene changes

super = pred.MSuper(pel=2, hpad=16, vpad=16, sharp=2)

backward_vec2 = MAnalyse(super, isb = true, delta = 2, overlap=4, truemotion=true, dct=5)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, overlap=4, truemotion=true, dct=5)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, overlap=4, truemotion=true, dct=5)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, overlap=4, truemotion=true, dct=5)

maskp1 = Source.mmask(forward_vec1 ,kind=1, ysc=255).UtoY()
maskp2 = Source.mmask(forward_vec2 ,kind=1, ysc=255).UtoY()
maskp3 = Source.mmask(backward_vec1,kind=1, ysc=255).UtoY()
maskp4 = Source.mmask(backward_vec2,kind=1, ysc=255).UtoY()
maskf = average(maskp1, 0.25, maskp2, 0.25, maskp3, 0.25, maskp4, 0.25).spline36resize(source.width, source.height)

smooth = pred_.gradfun2db(1.01)
source2 = MT_Merge(source, smooth, maskf)

source3 = source2.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400)
source3
VagueDenoiser(method=4, nsteps=10, wavelet=2, Wiener=true, auxclip=pred, percent=95, chromaT=1.0, wratio=0.75, threshold=0.5)#remove temporally blurred high frequency crud, can cause blocking upon reencode
return gradfun2db(1.01)
}

Didée
16th January 2011, 15:06
Almost. To port that script 1:1 to MVTools2, you need one more super clip:

...
smooth = pred_.gradfun2db(1.01)
source2 = MT_Merge(source, smooth, maskf)

super2 = source2.MSuper(pel=2,sharp=2,levels=1)
source3 = source2.MDegrain2(super2, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400)
source3
...


However, you should not name this script "MCSharpening". There is only denoising/smoothing going on, but not one yota of sharpening.

SilaSurfer
16th January 2011, 16:40
I meant the script for removing MPEG-2 blocks in post #38, which you modified in post #41, the very last scripts discussed. I think it was originally *.mp4 guy's. So these can cause smearing. Thanks.

~zee944~

Didée already answered your question. There must be some bad characteristic in your source which throws ME engine off. This can not only reduce the effectivness of denoising but can also result in creation of artifacts like smearing. You need to filter those out before you feed your source in motion analysis of Mdegrain.

~Mp4Guy~

So I see you have been busy for the last four years. ;) Need to test it soon as possible. Just a few questions, please correct me if I'm wrong:

1. FFt3d prefiltering is meant for removal of LF flicker?

2. Ttempsmooth or Hqdn3d - Temporal stabilization?

3. VagueDenoiser for removing dct blocks?

If the script does reduce some details maybe Didée's contrasherpening script could come in handy.

zee944
16th January 2011, 22:19
This can not only reduce the effectivness of denoising but can also result in creation of artifacts like smearing. You need to filter those out before you feed your source in motion analysis of Mdegrain.

Filter out smearing? How? :) I'm a little dubious about removing smearing. It may be possible, but not for most of us.

*.mp4 guy
18th January 2011, 06:34
So I see you have been busy for the last four years. ;) Need to test it soon as possible. Just a few questions, please correct me if I'm wrong:

1. FFt3d prefiltering is meant for removal of LF flicker?

2. Ttempsmooth or Hqdn3d - Temporal stabilization?

3. VagueDenoiser for removing dct blocks?

1. fft3d is serving double duty, both reducing overall noise levels enough that ttempsmooth can lock down stationary areas, and later being used to reduce noise in areas that are difficult for mvtools to denoise .

2 they are used to remove noise from featureless static or semi-static areas.

3. vaguedenoiser is used to reduce the "looking through a dusty window" effect that mvdegrain produces in varying amounts.

I've also been fiddling with a different method of translating the motionmask into spatial denoiser limiting, but I'm not sure its better yet.

Filter out smearing? How? :) I'm a little dubious about removing smearing. It may be possible, but not for most of us.Smearing is the result of badly predicted motion, particularly caused by noise in featureless areas, removing said noise can reduce the amount of smearing in those areas.

Vitaliy Gorbatenko
18th January 2011, 07:11
fft3dfilter is very slow. Can it be replaced by FFT3dGPU ?
Direct change don't give 1:1 result.

SilaSurfer
19th January 2011, 13:28
Thank you for your explenation Mp4guy. So your script still does some deblocking on the way like your older script? I hate dct blocks in Mpeg2 steams especially after the encode when those get amplified.

*.mp4 guy
20th January 2011, 00:55
Yes it still does that. This is my "make dvds still look good after being re-encoded with x264" script (which is what the old one was as well).

zee944
20th January 2011, 20:03
Smearing is the result of badly predicted motion, particularly caused by noise in featureless areas, removing said noise can reduce the amount of smearing in those areas.

I thought smearing is nearly impossible to remove. I don't know what "featureless" means in video processing (flat areas?), but I gave Ttempsmooth() and Hqdn3d() a few tries, but they didn't have effect on the smearing on my source. Are you sure THIS (http://www.mediafire.com/file/a3apm5royusj93a/TD_UNI_smearing_sample.zip) smearing is fixable?

Yes it still does that. This is my "make dvds still look good after being re-encoded with x264" script (which is what the old one was as well).

I'm testing your new script (MaskTools2 version though), but it doesn't seem to be sporting heavier noisefiltering; it removes certain noises better but leaves other noises unscathed which the old one used to eliminate. After a quick look, your 4-year-old script looks better to my eyes, but I have to add, I've been very happy with that. Most times it works like magic :)

*.mp4 guy
21st January 2011, 05:22
I thought smearing is nearly impossible to remove. I don't know what "featureless" means in video processing (flat areas?), but I gave Ttempsmooth() and Hqdn3d() a few tries, but they didn't have effect on the smearing on my source. Are you sure THIS (http://www.mediafire.com/file/a3apm5royusj93a/TD_UNI_smearing_sample.zip) smearing is fixable?
You misunderstand. I was saying it is possible to reduce the amount of smearing produced by mvtools, not that it is possible to remove smearing from your source.


I'm testing your new script (MaskTools2 version though), but it doesn't seem to be sporting heavier noisefiltering; it removes certain noises better but leaves other noises unscathed which the old one used to eliminate. After a quick look, your 4-year-old script looks better to my eyes, but I have to add, I've been very happy with that. Most times it works like magic :)
New script is intended to either remove noise, or leave it alone, because I don't like how partially removed noise looks and the main purpose of the script has always been to make mpeg2 video more amenable to re-encoding; this mainly involves removing low level noise that will not survive encoding. If you want the old look back, ditch dct=5, lower pel and sharpness, and the result will be a more aggressive version of the old script.

fft3dfilter is very slow. Can it be replaced by FFT3dGPU ?
Direct change don't give 1:1 result.
If your gpu has enough ram, it should be close enough.

zee944
21st January 2011, 17:46
If you want the old look back, ditch dct=5, lower pel and sharpness, and the result will be a more aggressive version of the old script.

You mean turn off dct (dct=0), and use pel=1 and sharp=1 or sharp=0 for the super clip? I've tried, but it still leaves extra noise compared to the old script.

BTW, when I try to use your new script in its original form, VirtualDub fails to open: "MVAnalyse: pel has to be 1 or 2". Why's that? Perhaps it needs newer or older than MVTools 1.6.2?

Didée
21st January 2011, 18:09
MVTools's pel=4 <=> x264's placebo.

Tempter57
21st January 2011, 19:07
Originally Posted by Vitaliy Gorbatenko
fft3dfilter is very slow. Can it be replaced by FFT3dGPU ?
Direct change don't give 1:1 result.
variant with fft3dgpu:
setmemorymax(640)

blksize = 8
overlap = blksize/2
lambda = 768
thSAD = 300
thSADC = thSAD
thSCD1 = 320
thSCD2 = 104
chroma = true
planes = chroma?4:0
ch31 = chroma?3:1
ch21 = chroma?2:1
search = 5

str = 1.0 # strength of predictionfilter, don't change
KEEP = "0.23" # strength HiFreq-grain
source = last

# ==== DENOICED ====
setmtmode(5)
pre = source.fft3dgpu(bw=8, bh=8, ow=4, oh=4, bt=1, sigma=str, plane=planes)
setmtmode(2)
pred = pre.fft3dfilter(bw=216, bh=216, ow=108, oh=108, bt=1, sigma=str/8, sigma2=str/4, sigma3=str/2, sigma4=str, plane=planes,ncpu=1)
\. TblurNL(rad=2, thresh=4) # comment out tblurnl if you don't have residual low frequency blotchiness which fft3d loves to leave on everything

preNR = pred.ttempsmooth(maxr=7).gradfun2db(1.01)
# preNR = pred.hqdn3d(0.1, 0.1, 1.5, 1.5).gradfun2db(1.01) # is faster and nearly as good, except on scene changes
psuper = preNR.MSuper(pel=2, sharp=2, rfilter=2, chroma=chroma)
ssuper = source.MSuper(pel=2, sharp=2, levels=1, chroma=chroma)
vb2 = MAnalyse(psuper, isb=true, truemotion=true, delta=2, blksize=blksize, overlap=overlap, lambda=lambda, search=5, dct=5, chroma=chroma)
vb1 = MAnalyse(psuper, isb=true, truemotion=true, delta=1, blksize=blksize, overlap=overlap, lambda=lambda, search=5, dct=5, chroma=chroma)
vf1 = MAnalyse(psuper,isb=false, truemotion=true, delta=1, blksize=blksize, overlap=overlap, lambda=lambda, search=5, dct=5, chroma=chroma)
vf2 = MAnalyse(psuper,isb=false, truemotion=true, delta=2, blksize=blksize, overlap=overlap, lambda=lambda, search=5, dct=5, chroma=chroma)

maskp1 = MMask(vf1, kind=1, ysc=255).UtoY()
maskp2 = MMask(vf2, kind=1).UtoY()
maskp3 = MMask(vb1, kind=1, ysc=255).UtoY()
maskp4 = MMask(vb2, kind=1).UtoY()
tmask = average(maskp1, 0.25, maskp2, 0.25, maskp3, 0.25, maskp4, 0.25).spline36resize(source.width, source.height)

smooth = pred.gradfun2db(1.01)
source2 = mt_merge(source,smooth,tmask,Y=3,U=ch31,V=ch31)
NR = source2.MDegrain2(ssuper,vb1,vf1,vb2,vf2,thSAD=thSAD,thSADC=thSADC,thSCD1=thSCD1,thSCD2=thSCD2,plane=planes)
\. VagueDenoiser(method=4, nsteps=10, wavelet=2, Wiener=true, auxclip=preNR, percent=95, chromaT=1.0, wratio=0.75, threshold=0.5)
\. mt_adddiff(mt_makediff(source,smooth,U=ch31,V=ch31).mt_lut("x 128 - abs 1 < x x 128 - abs 1 - "+KEEP+" * x 128 - x 128 - abs 0.001 + / * 128 + ?",U=ch21,V=ch21),U=ch31,V=ch31)

Diff = mt_makediff(source, NR, U=ch31, V=ch31)
denoiced = source.mt_makediff(Diff, U=ch31, V=ch31)

# ==== SHARPENING ====
Contrasharpening(denoiced, source)

# ==== DEBANDING ====
GradFun2DBmod(thr=1.4,thrC=1.4,mode=2,str=0.3,strC=0.0,temp=50,adapt=64)
YlevelsS(0,1.0,255,0,255,false)

# -- visualisations --
# stackvertical(source,last)
# interleave(source,last)

Didée
21st January 2011, 19:31
Welcome to Doom9, Tempter57. - And to make it a warm welcome, I'll smack your bottom a little. :D

Instead of exchanging FFT3DFilter with FFT3DGPU, this script uses both of them.

Also, "sharp = source2.TblurNL()" is somewhat funny.


You guys know I'm inclined with mo-comp denoisers, but ... denoising is not the topic of this thread.

Vitaliy Gorbatenko
22nd January 2011, 06:44
Tempter57:
pred1 = source.fft3dgpu(bw=6,bh=6,ow=3,oh=3,bt=1,sigma=str,plane=4,precision=2) # precision=0 or precision=1

setmtmode(2)
pred = pred1.fft3dfilter(bw=216,bh=216,ow=108,oh=108,bt=1,sigma=str/8,sigma2=str/4,sigma3=str/2,sigma4=str,plane=4)

??? Why ??? Speed increase not very good.

Tempter57
22nd January 2011, 10:30
Didйe & Vitaliy Gorbatenko
If used fft3gpu in both cases, the my videocard crashes. For increase in speed of processing placed in parameters fft3dgpu precision=0 and\or bw=12,bh=12,ow=6,oh=6

Didée
22nd January 2011, 15:48
Ah, indeed, my bad. FFT3dGPU can be used only one single time within a script.

Anyway, *mp4guy's script seems to do a few "special purpose" things - those fft3d settings don't look that awfully useful from a "general purpose" perspective. Overall that seems like a really strrrrong smoothing script - even more so with your TblurNL modification.


That script does nothing but smoothing, blurring, blurring, smoothing.

This thread is about sharpening.

Vitaliy Gorbatenko
23rd January 2011, 08:15
Why? I't inser FFT3dGPU two times and don't have a crash.... W7 + GTX480

Didée
23rd January 2011, 12:29
Ah, yes, its a bit ambigous. Some poking-into-the-blue testing showed this behaviour:

a) several instances of FFT3dGPU are possible when the script is strictly single-threaded (i.e. no SetMTmode is used at all)

b) when the script uses SetMTmode somewhere, then only one instance of FFT3dGPU is guaranteed to work correctly. Additional instances might work, or might fail. (This is with FFT3dGPU running in SetMTmode(5), of course.)

That's what I gathered from some experimenting. Don't ask me for the how's and why's, I don't know.

SilaSurfer
26th January 2011, 22:16
Didée I think after testing that your variant 1 of MC sharpening is great for DVD sources. With SeeSaw it works like a charm. With others it seems sharpening is to powerfull even with lowered settings for SeeSaw.

Nephilis
27th January 2011, 12:21
Hi,
Here is an advanced variant#2: "spatial sharpen, temporally averaged" based script. Have fun :) Thanx to Didée and LaTo.


########################################################################################################################
### ###
### Motion Compansated Grain Remover ###
### with Sharpening and Debanding Features ###
### **SPECIAL EDITION** ###
### By NEPHILIS ###
### @2011 ###
### ###
########################################################################################################################

##########################################################
## ##
## Requirements : - MVTools (v2.5.11.1) ##
## ----------------- - Masktools (v2.0a48) ##
## - Removegrain (v1.0) package ##
## - Gradfun2db (v1.0) ##
## - Some Brain :P ##
## ##
##########################################################

########################################################################################################################
# #
# Usage : MCGRMultiSE(clip input, float"ssx", float"ssy", float"Sstr", int"Tlimit", int"Slimit", #
# ---------- int"radius", int"search", int"thSAD", int"thSADC", #
# bool"DeBanding", float"thr", float"thrC") #
# #
########################################################################################################################

#################
# ------------- #
# PARAMETERS #
# ------------- #
#################

###############
# #
# SHARPEN : #
# ---------- #
#######################################################################################################################
#
# ----------
# Ssx,Ssy : -- Supersampling factor.
# ----------
#
# ----------
# Sstr : -- Sharpening strength.
# ----------
#
# ----------
# SLimit : -- Spatial Limiting value.
# ----------
#
# ----------
# TLimit : -- Temporal Limiting value. (Motion Compesated Temporal Limiting)
# ----------
#
#######################################################################################################################

###############
# #
# DENOISE : #
# ---------- #
#######################################################################################################################
#
# ----------
# Radius : -- Temporal radius, to use MDeGrain1/2 or 3 as denoiser
# ----------
#
# ----------
# Search : -- MVTools search
# ----------
#
# ----------
# thSAD,
# thSADC : -- MVTools thSAD and thSADC
# ----------
#
#######################################################################################################################

###############
# #
# DEBANDING : #
# ---------- #
#######################################################################################################################
#
# ----------
# DeBanding : -- To activate DeBanding feature use "DeBanding=true". Default(=false)
# ----------
#
# ----------
# thr,
# thrC : -- Gradfun2db's "thr" and "thrC" options.
# ----------
#
######################################################################################################################


Function MCGRMultiSE(clip input, float"ssx", float"ssy", float"Sstr", int"Tlimit", int"Slimit",
\ int"radius", int"search", int"thSAD", int"thSADC",
\ bool"DeBanding", float"thr", float"thrC")

{

ssx = default( ssx , 1.0 )
ssy = default( ssy , ssx )
Sstr = default( Sstr , 1.0 )
Tlimit = default( Tlimit , 2 )
Slimit = default( Slimit , 6 )
radius = default( radius , 2 )
search = default( search , 5 )
thSAD = default( thSAD , 125 )
thSADC = default( thSADC , thSAD )
DeBanding = default( DeBanding , false )
thr = default( thr , 1.2 )
thrC = default( thrC , thr )

Assert( isYV12(input) == True ? true : false, chr(10) + " Input is not YV12 clip. Convert to YV12 first " + chr(10))
Assert(( radius>= 1 && radius<= 3 ) ? true : false, chr(10) + " 'Radius' value should be between [1-3] " + chr(10))
Assert(( search>= 0 && search<= 5 ) ? true : false, chr(10) + " 'Search' value should be between [0-5] " + chr(10))

ox = input.width()
oy = input.height()
HD = (ox== 1920 || oy>= 800) ? true : false
xss = mod4(ox*ssx)
yss = mod4(oy*ssy)
Str = string(Sstr)
shrp = mt_lutxy(input,input.RemoveGrain(11,-1,-1),\
yexpr="x y == x x x y - abs 16 / 1 4 / ^ 16 * "+Str+" * x y - x y - abs / * x y - 2 ^ 16 2 ^ "+Str+\
" 4 * + * x y - 2 ^ "+Str+" 4 * + 16 2 ^ * / * 1 1 3 / 4 ^ + 1 x y - abs 48 / 4 ^ + / * + ?",U=1,V=1)
EE = input.Spline36resize(xss,yss).mt_edge("prewitt",0,255,0,0,u=1,v=1).mt_expand(U=1,V=1).\
mt_inflate(U=1,V=1).removegrain(20,-1).Spline36resize(ox,oy)
EEDS = mt_merge(input,shrp,EE,chroma="copy first")
repaired = repair(shrp,EEDS,1,-1,-1)
shrpdiff = mt_makediff(input,repaired)
Limited = mt_lutxy(repaired,shrpdiff,yexpr=" y 128 "+string(Slimit)+" + > x "+string(Slimit)+" - y 128 "+string(Slimit)+\
" - < x "+string(Slimit)+" + x y 128 - - ? ?",chroma="copy first")

blksize = (HD==true) ? 16:8
overlap = blksize/2

src = input
src_super = MSuper(src,hpad=4,vpad=4,pel=2,sharp=2)

bwv1 = MAnalyse(src_super, blksize=blksize, search=search, isb=true, delta=1, overlap=overlap, truemotion=true, lambda=1000)
fwv1 = MAnalyse(src_super, blksize=blksize, search=search, isb=false, delta=1, overlap=overlap, truemotion=true, lambda=1000)
bwv2 = (radius>=2) ? \
MAnalyse(src_super, blksize=blksize, search=search, isb=true, delta=2, overlap=overlap, truemotion=true, lambda=1000) : Blankclip()
fwv2 = (radius>=2) ? \
MAnalyse(src_super, blksize=blksize, search=search, isb=false, delta=2, overlap=overlap, truemotion=true, lambda=1000) : Blankclip()
bwv3 = (radius==3) ? \
MAnalyse(src_super, blksize=blksize, search=search, isb=true, delta=3, overlap=overlap, truemotion=true, lambda=1000) : Blankclip()
fwv3 = (radius==3) ? \
MAnalyse(src_super, blksize=blksize, search=search, isb=false, delta=3, overlap=overlap, truemotion=true, lambda=1000) : Blankclip()

bcomp = MCompensate(input,src_super,bwv1,thSAD=512)
fcomp = MCompensate(input,src_super,fwv1,thSAD=512)
max = mt_logic(bcomp,fcomp,"max").mt_logic(input,"max")
min = mt_logic(bcomp,fcomp,"min").mt_logic(input,"min")
LSharp = mt_clamp(Limited,max,min,Tlimit,Tlimit,U=2,V=2)
FSharp = LSharp.MergeChroma(src)

shrp_super = MSuper(FSharp,hpad=4,vpad=4,pel=2,sharp=2,levels=1)

MCNR = (radius==1) ? MDegrain1(input,shrp_super,bwv1,fwv1,thSAD=thSAD,thSADC=thSADC) \
: (radius==2) ? MDegrain2(input,shrp_super,bwv1,fwv1,bwv2,fwv2,thSAD=thSAD,thSADC=thSADC) \
: MDegrain3(input,shrp_super,bwv1,fwv1,bwv2,fwv2,bwv3,fwv3,thSAD=thSAD,thSADC=thSADC)

DB = (DeBanding==True) ? DeBand(MCNR,thr,thrC) : MCNR

Return (DB)

}

Function DeBand(clip clp, float thr, float thrC)

{
w = clp.width() + 32
h = clp.height() + 32

RDY = clp.pointresize(w,h,-16,-16,w,h)

LUM = RDY.gradfun2db(thr).Crop(16,16,-16,-16)
CHR = RDY.gradfun2db(thrC).Crop(16,16,-16,-16)

Dither = thr==1.0 && thrC==1.0 ? CLP
\ : thr==thrC ? LUM
\ : thr!=1.0 && thrC==1.0 ? LUM.mergechroma(CLP)
\ : thr==1.0 && thrC!=1.0 ? CLP.mergechroma(CHR)
\ : LUM.mergechroma(CHR)

Mask = mt_luts(clp,clp,mode="range",pixels=mt_square(2),expr="y",u=1,v=1).\
mt_lut(expr="255 x 1 2 / * 2 ^ /",u=1,v=1).removegrain(19,-1)

Output = mt_merge(clp,Dither,Mask,luma=true,u=3,v=3)

Return (Output)

}

function mod4(float"x")
{
return(x<16 ? 16 : int(round(x/4.0)*4))
}

Didée
27th January 2011, 12:32
Syntax error in line 122. :D
oy = input.height(

Nephilis
27th January 2011, 12:44
Syntax error in line 122. :D
oy = input.height(

Oh, thanx again Didée. :) fixed.

Vitaliy Gorbatenko
27th January 2011, 13:32
Very good and fast! But visual effect between Sst=1.0 and Sstr=100.0 close to zero.

Didée
27th January 2011, 14:00
In a hurry .....

In practice, this function allows sharpening only in "non-edge" areas. In "edge" areas, sharpening will be almost zero, because of the very small thSAD=125.


EE = input.Spline36resize(xss,yss).mt_edge("prewitt",0,255,0,0,u=1,v=1).mt_expand(U=1,V=1).\
mt_inflate(U=1,V=1).removegrain(20,-1).Spline36resize(ox,oy,0.5,-0.5,xss,yss)
No big harm in practice, but it's not good. There's no need to shift the mask diagonally by half a pixel. (I told you before.)


EEDS = mt_merge(input,shrp,EE,chroma="copy first")
repaired = repair(shrp,EEDS,1,-1,-1)
This is problematic. It will cause clipping on the sharpened parts in non-edge areas. (If Sstr is set big enough to actually do some sharpening. The default of 1.0 does very, very little sharpening.)

-----

A nice function, but it could be better balanced. :)

mandarinka
27th January 2011, 14:40
Seeing this, I wonder: would a motion-compensated daa() be viable? I assume such process could in theory get rid of some shimmering that is left after anti-aliasing if there is a pan, zoom or rotation (or local motion as well). I'm specifically talking about anime, but it probably is similar with live action.

Or is it a better choice to just wait for 3d nnedi to (maybe) happen? :)

SilaSurfer
27th January 2011, 20:05
Nephilis I think that supersampling (ssx and ssy) should be used to prevent aliasing. From 1.25 to 1.5. Using it I got some impressive results.

Nephilis
28th January 2011, 13:26
Nephilis I think that supersampling (ssx and ssy) should be used to prevent aliasing. From 1.25 to 1.5. Using it I got some impressive results.

In LSF and SeeSaw, SS is serving to prevent aliasing but here SS is used to better edge detecting..

SilaSurfer
28th January 2011, 13:52
So what are you using in your function as a sharpener?

Didée
29th January 2011, 01:26
It's using non-linear sharpening based on RemoveGrain(11). Seems it's fairly similar to SeeSaw's nonlinear sharpening ... the damping terms are a bit different.

SilaSurfer
6th February 2011, 16:17
Thanks Didée! While talking about SeeSaw, settings which you proposed in this post

http://forum.doom9.org/showpost.php?p=1465424&postcount=35

I found that it is too powerfull at least for Dvd sources but I like the sharpening effect so thinking and looking into SeeSaw function script I found this setting called Slimit. Lowering that from 99 reduced overall sharpening effect to reasonoble amount but still enhancment kept was great. :p

Jenyok
22nd December 2011, 10:07
This is a valid change for mvtools2?


function MCSharpening(clip source)
{
str=1#strength of predictionfilter, don't change
#source = last

# comment out tblurnl if you don't have residual low frequency blotchiness which fft3d loves to leave on everything
pred_ = Source.fft3dfilter(bw=6, bh=6, ow=3, oh=3, bt=1, sigma=str, plane=4). \
fft3dfilter(bw=216, bh=216, ow=108, oh=108, bt=1, sigma=str/8, sigma2=str/4, sigma3=str/2, sigma4=str, plane=4).TblurNL(rad=2, thresh=4)
pred = pred_.ttempsmooth(maxr=7).gradfun2db(1.01)#hqdn3d(0.1, 0.1, 1.5, 1.5).gradfun2db(1.01) is faster and nearly as good, except on scene changes

super = pred.MSuper(pel=2, hpad=16, vpad=16, sharp=2)

backward_vec2 = MAnalyse(super, isb = true, delta = 2, overlap=4, truemotion=true, dct=5)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, overlap=4, truemotion=true, dct=5)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, overlap=4, truemotion=true, dct=5)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, overlap=4, truemotion=true, dct=5)

maskp1 = Source.mmask(forward_vec1 ,kind=1, ysc=255).UtoY()
maskp2 = Source.mmask(forward_vec2 ,kind=1, ysc=255).UtoY()
maskp3 = Source.mmask(backward_vec1,kind=1, ysc=255).UtoY()
maskp4 = Source.mmask(backward_vec2,kind=1, ysc=255).UtoY()
maskf = average(maskp1, 0.25, maskp2, 0.25, maskp3, 0.25, maskp4, 0.25).spline36resize(source.width, source.height)

smooth = pred_.gradfun2db(1.01)
source2 = MT_Merge(source, smooth, maskf)

source3 = source2.MDegrain2(super, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400)
source3

# remove temporally blurred high frequency crud, can cause blocking upon reencode
VagueDenoiser(method=4, nsteps=10, wavelet=2, Wiener=true, auxclip=pred, percent=95, chromaT=1.0, wratio=0.75, threshold=0.5)

return gradfun2db(1.01)
}


.
Very interesting result (for me) is achieved using following code in following sequence (not another).
.

MCSharpening()
ReCon(str=4, rad=4, lmode=4) # various parameters

.
ReCon(str=4, rad=4, lmode=4) # various parameters
http://forum.doom9.org/showthread.php?t=155030

*.mp4 guy
22nd December 2011, 17:46
The function "MCSharpening" does not apply any type of sharpening. It is purely a denoiser. Also, lmode=4 is non-limited, so artifacts are likely, additionally, rad=4 is slow. You might want to consider a simple unsharp mask in place of ReCon under these circumstances.

Overdrive80
27th December 2011, 15:46
Hi all, *.mp4 guy, would you be so kind as to give some examples of unsharp mask? I have yet to learn to manage masktools.

Thanks

bmb
3rd May 2012, 15:54
does anyone reccommend a decent mvtools denoising script, i have 1 im using at the moment.. but it still produces slight blocks and noise and thats not what im after

EuropeanMan
3rd May 2012, 16:24
^ post the script you have as a comparison to one you "eventually" need...denoising depends always on the source, so post a sample as well.

bmb
3rd May 2012, 18:52
i currently am using this

ConverttoYV12
a = last
b=a
SeeSaw(a,b, NRlimit=4, NRlimit2=5, Sstr=1.9, Slimit=4, Spower=3, Sdamplo=6, Szp=5, sootheS=20)
super = MSuper(pel=2,chroma=false)
backward_vec1 = super.MAnalyse(isb = true, blksize=16, delta = 1, overlap=8,chroma=false,search=5,searchparam=4,temporal=true)
forward_vec1 = super.MAnalyse(isb = false, blksize=16, delta = 1, overlap=8,chroma=false,search=5,searchparam=4,temporal=true)
MDegrain1(super, backward_vec1,forward_vec1,thSAD=50,plane=0)


i want to be able to compress the output size alot more aswell im encoding using XVID... also is their sometihng i can add to reduce noise in another form of technique that will keep the encode looking clean and sharp

bmb
4th May 2012, 16:02
any thoughts ? ideas? suggestions? anyone ?

hartford
8th May 2012, 02:37
It would be best to post a link to a segment of the video of concern (about 10M)

Also, some scripts that you have tried in vain.

This might result in more interest.

bmb
12th May 2012, 07:49
theirs no specific video, its for Bluray editing, i compress full bluray sources to about 2-6 gig .. the script im using which posted above has done a great job at dealing with noise generated by compressing to such a small size.. how ever im interested to no what people think, is their anything that can be added to it, or any script to help increase compression? ... thanks :D

matfra
30th October 2012, 18:57
McSharp.avsi

function McSharp(clip clip,int "sharp")
{ # Based on MCDegrain By Didee, http://forum.doom9.org/showthread.php?t=161594
# Also based on DiDee observations in this thread: http://forum.doom9.org/showthread.php?t=161580
# "Denoise with MDegrainX, do slight sharpening where motionmatch is good, do slight blurring where motionmatch is bad"
sharp = Default(sharp, 1)
sharp0 = clip.sharpen(sharp)
sharpD = mt_makediff(clip,sharp0)
zeroD = sharpD.mt_lut("x",Y=-128)

sup1 = clip.MSuper(pel=2,sharp=2)
sup2 = sharpD.MSuper(pel=2,sharp=2,levels=1)
bv1 = sup1.MAnalyse(isb = true, delta = 1, blksize=8, overlap=4, search=3, searchparam=4)
fv1 = sup1.MAnalyse(isb = false, delta = 1, blksize=8, overlap=4, search=3, searchparam=4)
bv2 = sup1.MAnalyse(isb = true, delta = 2, blksize=8, overlap=4, search=3, searchparam=4)
fv2 = sup1.MAnalyse(isb = false, delta = 2, blksize=8, overlap=4, search=3, searchparam=4)

zeroD.MDegrain2(sup2,bv1,fv1,bv2,fv2)

clip.mt_makediff(last,U=2,V=2)

return(last)
}

function McDegrainSharp(clip c, int "frames", float "bblur", float "csharp", bool "bsrch")
{ # Based on MCDegrain By Didee, http://forum.doom9.org/showthread.php?t=161594
# Also based on DiDee observations in this thread: http://forum.doom9.org/showthread.php?t=161580
# "Denoise with MDegrainX, do slight sharpening where motionmatch is good, do slight blurring where motionmatch is bad"
# In areas where MAnalyse cannot find good matches, the blur() will be dominant.
# In areas where good matches are found, the sharpen()'ed pixels will overweight the blur()'ed pixels
# when the pixel averaging is performed.
frames = default(frames, 2)
bblur = default(bblur, 0.0)
csharp = default(csharp, 1.0)
bsrch = default(bsrch, False)
bs = (c.width>960) ? 16 : 8

c2 = c.blur(bblur)
super = bsrch ? c2.MSuper(pel=2, sharp=1) : c.MSuper(pel=2, sharp=1)
super_rend = c.sharpen(csharp).MSuper(pel=2, sharp=1,levels=1)
backward_vec3 = MAnalyse(super, isb = true, delta = 3, blksize=bs, overlap=bs/2)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, blksize=bs, overlap=bs/2)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, blksize=bs, overlap=bs/2)
forward_vec1 = MAnalyse(super, isb = false, delta = 1, blksize=bs, overlap=bs/2)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, blksize=bs, overlap=bs/2)
forward_vec3 = MAnalyse(super, isb = false, delta = 3, blksize=bs, overlap=bs/2)
(frames<=0) ? c :\
(frames==1) ? c2.MDegrain1(super_rend, backward_vec1,forward_vec1,thSAD=400) :\
(frames==2) ? c2.MDegrain2(super_rend, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=400) :\
c2.MDegrain3(super_rend, backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=400)
return(last)
}