Log in

View Full Version : Simple MDegrain - SMDegrain() - To make your scripts shorter and less geeky


Caroliano
24th January 2010, 20:18
For new versions, see Dogway's SMDegrain() Mod (http://doom10.org/index.php?topic=2178.0). Below the original post:

I was bothered by the copy-cola needed everytime I used MDeGrainX(), and also by the need to look often at the long and scary MVtools (http://avisynth.org.ru/mvtools/mvtools2.html) documentation. Additionaly, it was inconvenient to swich between MDegrain 1, 2 and 3, to see wich one was the best speed/quality trade-off, the same with overlap and blksize parameters. First I searched in the forums, but I saw nothing similar made for MVtools2. So I made an simple function to shorten this.


################################################################################################
### ###
### Simple MDegrain - SMDegrain() ###
### ###
### By Caroliano ###
### ###
### Special Thanks: Sagekilla, Didée and MVtools people ###
### ###
### v0.2 - 24 Jan 2010 ###
### ###
################################################################################################
###
### +-----------+
### | CHANGELOG |
### +-----------+
###
### v0.2 : - Added this introductory section
### - Added more parameters
###
### v0.1 : - Basic working version
### - Not released
###
###
### +--------------+
### | DEPENDENCIES |
### +--------------+
###
### -> MVtools2 (v2.5.8.1 or higher)
### -> MVtools depends on anything?? If yes, those things.
###
###
###
### +------------------+
### | BASIC PARAMETERS |
### +------------------+
###
###
### tr [int: 1, 2, 3]
### --------------
### Temporal radius. Select between MDegrain 1, 2 or 3. Higher is better, but also much slower.
### Default is 2.
###
###
### thSAD [int]
### --------------
### Strenght of denoising. Low values can result in staggered denoising,
### large values can result in ghosting and artefactes. Default is 400.
###
###
### plane [int: 1, 2, 3, 4]
### --------------
### Select the color planes you wish to process:
### 0 - luma only, 1 - chroma U, 2 - chroma V, 3 - both chromas, 4 - all.
### Default is 4 - all.
###
###
###
### +---------------------+
### | ADVANCED PARAMETERS |
### +---------------------+
###
###
### limit [int: 1 - 255]
### --------------
### Maximal change of pixel luma (post-process like DeGrainMedian plugin
### and LimitChange function of SSETools plugin, to prevent some artefactes).
### Default is 255 (no limit).
###
###
### limitc [int: 1 - 255]
### --------------
### Maximal change of pixel chroma. Default value = limit.
###
###
### pel [int: 1, 2, 4]
### --------------
### Accuracy of the motion estimation. 1 means a precision to the pixel.
### 2 means a precision to half a pixel. 4 means a precision to quarter a pixel, produced by
### spatial interpolation (more accurate but slower and not always better due to big level scale step).
### Default is 2.
###
###
### sharp [int: 0, 1, 2]
### --------------
### Subpixel interpolation method for pel=2,4.
### Use 0 for soft interpolation (bilinear), 1 for bicubic interpolation (4 tap Catmull-Rom),
### 2 for sharper Wiener interpolation (6 tap, similar to Lanczos. Default is 2.
###
###
### blksize [int: 4, 8, 16]
### --------------
### Size of a block (horizontal). Default is 8.
### Larger blocks are less sensitive to noise, are faster, but also less accurate.
###
###
### overlap [int]
### --------------
### Must be *even* and *less* than block size. Try use overlap value from blksize/4 to blksize/2.
### The greater overlap, the more blocks number, and the lesser the processing speed.
### Default is 2
###
###
### Search [int= 0, 1, 2, 3, 4, 5]
### --------------
### 0= 'OneTimeSearch', 1 = 'NStepSearch', 2= Logarithmic, 3= Exhaustive, 4= Hexagon, 5= Uneven Multi Hexagon
### Default is 4. See details at MVtools documentation.
### http://avisynth.org.ru/mvtools/mvtools2.html
###
###
###
###
### +-------------+
### | FINAL NOTES |
### +-------------+
###
### If there is an important parameter not implemented, please ask.
### Or better yet, implement it yourself and post in the Doom9 thread.
###
### Many paremeters will likely never be implemented,
### and you are better off using the original MVtools way.
###
################################################################################################



function SMDegrain ( clip input, int "tr", int "thSAD", int "plane", int "limit", int "limitc",
\ int "pel", int "sharp", int "blksize", int "overlap", int "search")
{
o = input
tr = default( tr, 2 )
thSAD = default( thSAD, 400 )
plane = default( plane, 4 )
limit = default( limit, 255 )
limitc = default( limitc,limit)

pel = default( pel, 2 )
sharp = default( sharp, 2 )

blksize = default( blksize, 8 )
overlap = default( overlap, 2 )
search = default( search, 4 )




# Motion vector search

super = o.MSuper(pel=pel, sharp=sharp)
bv3 = (tr > 2) ?
\ super.MAnalyse(isb = true, delta = 3, overlap=overlap, blksize=blksize, search=search) : BlankClip
bv2 = (tr > 1) ?
\ super.MAnalyse(isb = true, delta = 2, overlap=overlap, blksize=blksize, search=search) : BlankClip
bv1 = super.MAnalyse(isb = true, delta = 1, overlap=overlap, blksize=blksize, search=search)
fv1 = super.MAnalyse(isb = false, delta = 1, overlap=overlap, blksize=blksize, search=search)
fv2 = (tr > 1) ?
\ super.MAnalyse(isb = false, delta = 2, overlap=overlap, blksize=blksize, search=search) : BlankClip
fv3 = (tr > 2) ?
\ super.MAnalyse(isb = false, delta = 3, overlap=overlap, blksize=blksize, search=search) : BlankClip



# Finally, MDegrain

output = (tr == 3) ? o.MDegrain3(super, bv1, fv1, bv2, fv2, bv3, fv3, thSAD=thSAD, limit=limit, limitc=limitc) :
\ (tr == 2) ? o.MDegrain2(super, bv1, fv1, bv2, fv2, thSAD=thSAD, limit=limit, limitc=limitc) :
\ o.MDegrain1(super, bv1, fv1, thSAD=thSAD, limit=limit, limitc=limitc)

return(output)
}

Copy to an .txt document, rename it to .avsi and put it in the Plugins folder.

This is my first function with more than 5 lines, and I'm no programer. I gathered some code from many functions here at the forum and glued with what I know about avisynth grammar, so if there are things wrong, please correct-me.

Some things interesting to implement would be MT() suport, interlacing and YUV2 suport, error/invalid input handling, etc. But those seems not so easy to implement. Latter I plan to document it better and add some more parameters.

I'm also open to sugestions about the function's and parameters's names. In special, I don't know if the "tr" name, as abreviation to Temporal Radius, is the most adequate. Other names may be "mode" or "method".

rkalwaitis
24th January 2010, 22:45
Thanks for sharing.

LaTo
25th January 2010, 07:19
http://avisynth.org/mediawiki/upload/7/7d/FastDegrain.avs

:)

Vitaliy Gorbatenko
25th January 2010, 07:23
This is a copy of Killer function. Killer.avsi can be found on this forum.

rkalwaitis
25th January 2010, 17:22
I did a search on killer.avsi and can not find it, can anyone point me in the correct direction.

Caroliano
25th January 2010, 20:59
I also could not find the killer.avsi. On the FastDegrain(), I never looked inside it, nor it is very quoted here at doom9, so I totally missed it. I tought that it was more like TemporalDegrain() than an simple wrapper of MDegrain() with sharpening on by default... mine is simpler, still... I will continue to use it, now that I had this work..

Didée
25th January 2010, 21:29
This is a copy of Killer function. Killer.avsi can be found on this forum.
it can not be found via forum search function, and it can not be found via Google. Also, I can only ever find one single person who is talking about Killer() function, and this one single person is YOU.

Vitaliy, can you please give information about that Killer() function. IIRC I stumbled over that name in another thread of you, and it is an unknown function to me, too. I do know about "FizzKiller", but not about "Killer()". Also, Google does only find this thread here, and another thread that seems to have locked or deleted by now. Though, that thread only contained an >>Import("Killer.avsi")<<, nothing more that could help tracing it.

It seems you are the only one who knows about this function. So, either you give evidence what it is and where to get it, or keep it as your big elitaire secret and don't mention it anymore.

See ... If everyone would start posting scripts with "BigSecretFunctionOfUserXYZ_ThatNobodyMayKnowAbout()", we could as well close the Avisynth forum completely. It just makes no sense this way.

rkalwaitis
25th January 2010, 21:38
Caroliano,

Ive tried simple scripts similar to yours before and I also tried this one. They always seem to give me a problem with blocking, especially in dark areas. Do you run into this problem. I added contrasharpening by Didee to your script if you like sharpening, but no more than what was originally on your source. It does not slow down your script any and the only paramaters besides setting the strength if you want is true to use or false to not use.

Here it goes. I hope I remembered how to put it correctly in the script, (it works). Didee told me once so Im hoping he will tell me if I ganked it up to bad. :)

################################################################################################
### ###
### Simple MDegrain - SMDegrain() ###
### ###
### By Caroliano ###
### ###
### Special Thanks: Sagekilla, Didée and MVtools people ###
### ###
### v0.2 - 24 Jan 2010 ###
### ###
################################################################################################
###
### +-----------+
### | CHANGELOG |
### +-----------+
###
### v0.2 : - Added this introductory section
### - Added more parameters
###
### v0.1 : - Basic working version
### - Not released
###
###
### +--------------+
### | DEPENDENCIES |
### +--------------+
###
### -> MVtools2 (v2.5.8.1 or higher)
### -> MVtools depends on anything?? If yes, those things.
###
###
###
### +------------------+
### | BASIC PARAMETERS |
### +------------------+
###
###
### tr [int: 1, 2, 3]
### --------------
### Temporal radius. Select between MDegrain 1, 2 or 3. Higher is better, but also much slower.
### Default is 2.
###
###
### thSAD [int]
### --------------
### Strenght of denoising. Low values can result in staggered denoising,
### large values can result in ghosting and artefactes. Default is 400.
###
###
### plane [int: 1, 2, 3, 4]
### --------------
### Select the color planes you wish to process:
### 0 - luma only, 1 - chroma U, 2 - chroma V, 3 - both chromas, 4 - all.
### Default is 4 - all.
###
###
###
### +---------------------+
### | ADVANCED PARAMETERS |
### +---------------------+
###
###
### limit [int: 1 - 255]
### --------------
### Maximal change of pixel luma (post-process like DeGrainMedian plugin
### and LimitChange function of SSETools plugin, to prevent some artefactes).
### Default is 255 (no limit).
###
###
### limitc [int: 1 - 255]
### --------------
### Maximal change of pixel chroma. Default value = limit.
###
###
### pel [int: 1, 2, 4]
### --------------
### Accuracy of the motion estimation. 1 means a precision to the pixel.
### 2 means a precision to half a pixel. 4 means a precision to quarter a pixel, produced by
### spatial interpolation (more accurate but slower and not always better due to big level scale step).
### Default is 2.
###
###
### sharp [int: 0, 1, 2]
### --------------
### Subpixel interpolation method for pel=2,4.
### Use 0 for soft interpolation (bilinear), 1 for bicubic interpolation (4 tap Catmull-Rom),
### 2 for sharper Wiener interpolation (6 tap, similar to Lanczos. Default is 2.
###
###
### blksize [int: 4, 8, 16]
### --------------
### Size of a block (horizontal). Default is 8.
### Larger blocks are less sensitive to noise, are faster, but also less accurate.
###
###
### overlap [int]
### --------------
### Must be *even* and *less* than block size. Try use overlap value from blksize/4 to blksize/2.
### The greater overlap, the more blocks number, and the lesser the processing speed.
### Default is 2
###
###
### Search [int= 0, 1, 2, 3, 4, 5]
### --------------
### 0= 'OneTimeSearch', 1 = 'NStepSearch', 2= Logarithmic, 3= Exhaustive, 4= Hexagon, 5= Uneven Multi Hexagon
### Default is 4. See details at MVtools documentation.
### http://avisynth.org.ru/mvtools/mvtools2.html
###
###
###
###
### +-------------+
### | FINAL NOTES |
### +-------------+
###
### If there is an important parameter not implemented, please ask.
### Or better yet, implement it yourself and post in the Doom9 thread.
###
### Many paremeters will likely never be implemented,
### and you are better off using the original MVtools way.
###
################################################################################################



function SMDegrain ( clip input, int "tr", int "thSAD", int "plane", int "limit", int "limitc", int "frames", int "strength", \
int "pel", int "sharp", int "blksize", int "overlap", int "search", \
bool "contrasharp")

{

clip = input
tr = default( tr, 2 )
thSAD = default( thSAD, 400 )
plane = default( plane, 4 )
limit = default( limit, 255 )
limitc = default( limitc,limit)

pel = default( pel, 2 )
sharp = default( sharp, 2 )

blksize = default( blksize, 8 )
overlap = default( overlap, 2 )
search = default( search, 4 )
contrasharp = default(contrasharp, false) # contrasharpening off by default.


FUNCTION ContraSharpening(denoised, clip)
{

# contra-sharpening: sharpen the denoised clip, but don't add more to any pixel than what was removed previously.
# script function from Didee from the VERY GRAINY thread
s = denoised.minblur(1,1) # Damp down remaining spots of the denoised clip.
allD = mt_makediff(clip,denoised) # 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.

denoised.mt_adddiff(ssDD,U=2,V=2) # Apply the limited difference. (Sharpening is just inverse blurring.)

RETURN (last)
}

# Motion vector search

super = input.MSuper(pel=pel, sharp=sharp)
bv3 = (tr > 2) ?
\ super.MAnalyse(isb = true, delta = 3, overlap=overlap, blksize=blksize, search=search) : BlankClip
bv2 = (tr > 1) ?
\ super.MAnalyse(isb = true, delta = 2, overlap=overlap, blksize=blksize, search=search) : BlankClip
bv1 = super.MAnalyse(isb = true, delta = 1, overlap=overlap, blksize=blksize, search=search)
fv1 = super.MAnalyse(isb = false, delta = 1, overlap=overlap, blksize=blksize, search=search)
fv2 = (tr > 1) ?
\ super.MAnalyse(isb = false, delta = 2, overlap=overlap, blksize=blksize, search=search) : BlankClip
fv3 = (tr > 2) ?
\ super.MAnalyse(isb = false, delta = 3, overlap=overlap, blksize=blksize, search=search) : BlankClip



# Finally, MDegrain

output= (tr == 3) ? input.MDegrain3(super, bv1, fv1, bv2, fv2, bv3, fv3, thSAD=thSAD, limit=limit, limitc=limitc) :
\ (tr == 2) ? input.MDegrain2(super, bv1, fv1, bv2, fv2, thSAD=thSAD, limit=limit, limitc=limitc) :
\ input.MDegrain1(super, bv1, fv1, thSAD=thSAD, limit=limit, limitc=limitc)

output = contrasharp ? ContraSharpening(output,clip) : output

return (output)
}
I saw another version of Contrasharpening that was a bit more complex than this one. This is varily simple and straightforward.

Just put SMDegrain(contrasharp=true) to use it. I was wondering if there was away to us MCSharpening with your script as you are using 1 two or three frames.

Caroliano
25th January 2010, 23:49
Please put the script inside: [code] */code] (instead of * put [)

About blocking/banding, in my experience MDegrainx() is very effective agains it, leaving lots of dither, as it is an temporal-only filter. You may need to check your encoder setings or the calibration of your monitor.... I very rarelly get banding using it + x264 with adequate psy options and CRF 18~21.

Oh, and thanks for the contra-sharpening version. I will test it latter. It only adds masktools dependency? What version?

rkalwaitis
26th January 2010, 00:17
Caroliano

I used masktools v1.5.8, I believe you will also need removegrain.

As far as my blocking goes, I usually try to use CRF 20 w/264.

Contrasharpening is Didee's creation. He may have an idea of a tweak or two suited for your script.

Caroliano
26th January 2010, 00:32
Repair is also needed, isn't?

Also, the "strenght" and "frame" parameters are not conected with anything. A less generic name for those sharpening parameters would also be good...

rkalwaitis
26th January 2010, 00:42
Yes it also requires the repair.dll in the removegrain package.

Vitaliy Gorbatenko
26th January 2010, 06:38
Found this forum for sure.

function Killer(clip source, int temporal, int "blksize", int "overlap", int "sharp", int "thSAD", bool "RefineMotion")
{ # Motion compensated denoiser for progressive source clip with prefiltering for strength and repair for de-artefacting
# Uses MVTools2, ReduceFlicker and RemoveGrain/Repair

blksize = default(blksize,16) # blksize value (4, 8 or 16)
overlap = default(overlap,blksize/2) # overlap value (0 to half blksize)
sharp = default(sharp,2) # 0=bilinear softest, 1=bicubic, 2=Wiener sharpest
thSAD = default(thSAD,300) # higher risks motion ghosting and swimming, lower risks blotchy denoising
RefineMotion = default(RefineMotion,true) # true means MRecalculate will be used to improve motion vectors

halfblksize = blksize/2 # MRecalculate works with half block size
halfoverlap = overlap/2 # Halve the overlap to suit the halved block size
halfthSAD = thSAD/2 # MRecalculate uses a more strict thSAD, which defaults to 150 (half of function's default of 300)

dct=5

source = source.assumeframebased() # MSuper pel=2 is faster with this

# Prefilter the clip
calm = source.reduceflicker(strength=3,aggressive=true)
calm = calm.repair(source,mode=1)
calm = calm.removegrain(mode = 17)
calm = calm.removegrain(mode = 17)
calm = calm.removegrain(mode = 17)

calm_super = calm.MSuper(pel=2, hpad=blksize, vpad=blksize, sharp=sharp)
source_super = source.MSuper(pel=2, hpad=blksize, vpad=blksize, sharp=sharp,levels=1)
recalculate = calm.MSuper(pel=2, hpad=blksize, vpad=blksize, sharp=sharp,levels=1)

backward_vec3 = MAnalyse(calm_super, blksize=blksize, isb = true, delta = 3, overlap=overlap, dct=dct)
backward_vec3 = RefineMotion ? MRecalculate(recalculate, backward_vec3, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD) : backward_vec3
backward_vec2 = MAnalyse(calm_super, blksize=blksize, isb = true, delta = 2, overlap=overlap, dct=dct)
backward_vec2 = RefineMotion ? MRecalculate(recalculate, backward_vec2, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD) : backward_vec2
backward_vec1 = MAnalyse(calm_super, blksize=blksize, isb = true, delta = 1, overlap=overlap, dct=dct)
backward_vec1 = RefineMotion ? MRecalculate(recalculate, backward_vec1, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD) : backward_vec1

forward_vec1 = MAnalyse(calm_super, blksize=blksize, isb = false, delta = 1, overlap=overlap, dct=dct)
forward_vec1 = RefineMotion ? MRecalculate(recalculate, forward_vec1, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD) : forward_vec1
forward_vec2 = MAnalyse(calm_super, blksize=blksize, isb = false, delta = 2, overlap=overlap, dct=dct)
forward_vec2 = RefineMotion ? MRecalculate(recalculate, forward_vec2, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD) : forward_vec2
forward_vec3 = MAnalyse(calm_super, blksize=blksize, isb = false, delta = 3, overlap=overlap, dct=dct)
forward_vec3 = RefineMotion ? MRecalculate(recalculate, forward_vec3, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD) : forward_vec3

temporal == 3 ? MDegrain3(source, source_super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, backward_vec3, forward_vec3, thSAD=thSAD) : \
temporal == 2 ? MDegrain2(source, source_super, backward_vec1, forward_vec1, backward_vec2, forward_vec2, thSAD=thSAD) : \
MDegrain1(source, source_super, backward_vec1, forward_vec1, thSAD=thSAD)
repair(source,mode=17)
}

Didée
26th January 2010, 11:28
Vitaliy - yes, you are right. And I feel like an idiot now. "Killer()" is by the same author as "FizzKiller()", namely by Jawed. The thread where it appears is here (http://forum.doom9.org/showthread.php?p=1266572#post1266572) - and to make the joke complete, I even had personally tested and commented that function! :o

I apologize for the unfriendly tone I had spoken in.

Caroliano
26th January 2010, 14:34
One thing that would be handy is an searchable database of .avsi scripts. Searching things like "killer" or "MDegrain2" in the forum has an signal to noise ratio too low... If searched only inside .avsi scripts, then we would have much more usefull hits.

(an option to ignore #ed lines on search might also help)

osgZach
26th January 2010, 17:06
Or more precisely, what we need is an independent, actively maintained script/plugin/filter database. Perhaps something that allows ratings or other scorings too. Would really help people find that one script for that one job they need to do.

I know we have the Avisynth Wiki.. but aside from always being slow (for me anyway) its scripts listing is huge and iffy to search through, much less if you want to find a good tool you can rely on to be maintained.

Caroliano
3rd September 2011, 03:17
Well, I have been improving it, and adding new things, but never quite finished it up for releasing an new version. It is past time for it, so:

################################################################################################
### ###
### Simple MDegrain - SMDegrain() ###
### ###
### By Caroliano ###
### ###
### Special Thanks: Didée, Jawed, onesloth, rkalwaitis, Sagekilla and MVtools people ###
### ###
### v0.3 - 02 Sep 2011 ###
### ###
################################################################################################
###
### +-----------+
### | CHANGELOG |
### +-----------+
###
### v0.3 : - Added external prefilted clip option for motion-search (thanks onesloth)
### - Added contrasharpening option (thanks rkalwaitis) <-- new dependencies
### - Shamelesly copied some parts from Jawed's Killer.avsi:
### Added "Refine Motion" (MRecalculate), for possibly improved speed/quality
### Added experimental fake "MDegrain5" with tr = 5
### - Added chroma option for motion-search
### - Experimental SETMOD() support (copied from onesloth mod on fastdegrain())
### - Fix: Plane parameter now works
### - Attention: Changed the defaults for thSAD and overlap.
### - Misc: Cosmetics changes on the source code
### - Misc: A bit more fool-proof
###
### v0.2 : - Added this introductory section
### - Added more parameters
###
### v0.1 : - Basic working version
### - Not released
###
###
### +--------------+
### | DEPENDENCIES |
### +--------------+
###
### -> MVtools2 (v2.5.8.1 or higher)
### -> Masktools (only for contrasharpening=true)
### -> Repair (only for contrasharpening=true)
### -> MVtools depends on anything?? If yes, those things.
###
###
###
### +------------------+
### | BASIC PARAMETERS |
### +------------------+
###
###
### tr [int: 1, 2, 3, 5]
### --------------
### Temporal radius. Select between MDegrain 1, 2 or 3. Higher is better, but also much slower.
### tr = 5 is an "fake MDegrain5", and is experimental.
### Default is 2.
###
###
### thSAD [int]
### --------------
### Strenght of denoising. Low values can result in staggered denoising,
### large values can result in ghosting and artefactes.
### Default is 200.
###
###
### plane [int: 1, 2, 3, 4]
### --------------
### Select the color planes you wish to process:
### 0 - luma only, 1 - chroma U, 2 - chroma V, 3 - both chromas, 4 - all.
### Default is 4 - all.
###
###
###
### +---------------------+
### | ADVANCED PARAMETERS |
### +---------------------+
###
###
### limit [int: 1 - 255]
### --------------
### Maximal change of pixel luma (post-process like DeGrainMedian plugin
### and LimitChange function of SSETools plugin, to prevent some artefactes).
### Default is 255 (no limit).
###
###
### limitc [int: 1 - 255]
### --------------
### Maximal change of pixel chroma. Default value = limit.
###
###
### pel [int: 1, 2, 4]
### --------------
### Accuracy of the motion estimation. 1 means a precision to the pixel.
### 2 means a precision to half a pixel. 4 means a precision to quarter a pixel, produced by
### spatial interpolation (more accurate but slower and not always better due to big level scale step).
### Default is 2.
###
###
### sharp [int: 0, 1, 2]
### --------------
### Subpixel interpolation method for pel=2,4.
### Use 0 for soft interpolation (bilinear), 1 for bicubic interpolation (4 tap Catmull-Rom),
### 2 for sharper Wiener interpolation (6 tap, similar to Lanczos.
### Default is 2.
###
###
### blksize [int: 4, 8, 16]
### --------------
### Size of a block (horizontal).
### Larger blocks are less sensitive to noise, are faster, but also less accurate.
### Use 16 for more speed, or for HD resolutions like 1080p. Default is 8.
###
###
### overlap [int]
### --------------
### Must be *even* and *less* than block size. Try use overlap value from blksize/4 to blksize/2.
### The greater overlap, the more blocks number, and the lesser the processing speed.
### Default is half the blksize (4).
###
###
### RefineMotion [bool]
### --------------
### Use MRecalculate to refine motion estimation, improving quality at a given blksize (8 or 16 only).
### Using blksize=16 should give quality very similar to blksize 8 but with performance that's somewhat faster.
### Default: false (but recomended)
###
###
### Search [int: 0, 1, 2, 3, 4, 5]
### --------------
### 0= 'OneTimeSearch', 1 = 'NStepSearch', 2= Logarithmic, 3= Exhaustive, 4= Hexagon, 5= Uneven Multi Hexagon
### Default is 4. See details at MVtools documentation.
### http://avisynth.org.ru/mvtools/mvtools2.html
###
###
### Dark [bool: true, false]
### --------------
### Tweaks scene change detection, to be more sensitive, but can erroneously trigger scene change during
### bright/complex scenery with lots of motion.
### Default: false
###
###
###
### I added some other parameters not documented here.
###
###
### +-------------+
### | FINAL NOTES |
### +-------------+
###
### If there is an important parameter not implemented, please ask.
### Or better yet, implement it yourself and post in the Doom9 thread.
###
### Many paremeters will likely never be implemented,
### and you are better off using the original MVtools way.
###
################################################################################################



function SMDegrain ( clip input, clip "pre", int "tr", int "thSAD", int "plane", int "limit", int "limitc", int "pel",
\ int "sharp", int "blksize", int "overlap", int "search", bool "RefineMotion", bool "dark", bool "chroma",
\ bool "contrasharp")
{
o = input
tr = default( tr, 2 )
thSAD = default( thSAD, 200 )
plane = default( plane, 4 )
limit = default( limit, 255 )
limitc = default( limitc, limit)

pel = default( pel, 2 )
sharp = default( sharp, 2 )
chroma = default( chroma, true )


dark = default( dark , false )
RefineMotion = default(RefineMotion, false) # true means MRecalculate will be used to improve motion vectors

blksize = default( blksize, 8 )
overlap = default( overlap, blksize/2 )
search = default( search, 4 )

contrasharp = default(contrasharp, false) # contrasharpening off by default.


Assert( (blksize >= 8 && RefineMotion == true) || RefineMotion == false , "For RefineMotion you need a blksize of 8 or 16")

halfblksize = blksize/2 # MRecalculate works with half block size
halfoverlap = overlap/2 # Halve the overlap to suit the halved block size
halfthSAD = thSAD/2 # MRecalculate uses a more strict thSAD, which defaults to 150 (half of function's default of 300)

#Also, the default values thSCD1=400, thSCD2=130 often do not reckognize some scenechanges,
#especially in dimmed/dark scenery. lowering to sth like 350,90 is more safe in reckognizing scenechanges ...
#however, the more you lower these values, the more there is danger that the detection
#erroneously triggers during bright/complex scenery with lots of motion.
thSCD1 = (dark == true) ? 350 : 400
thSCD2 = (dark == true) ? 90 : 130

pel = (tr > 3) ? 1 : pel
o = o.assumeframebased() # MSuper pel=2 is faster with this


# See if SetMTMode is used. If yes, change it to the most adequate (?) for the script.
try {
SMTMdefaultmode = GetMTMode()
SMTM = (SMTMdefaultmode!=0)
} catch(err_msg) {SMTM = false}

# Motion vector search

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

super = o.MSuper(pel=pel, hpad=blksize, vpad=blksize, sharp=sharp, chroma=chroma)
search_super = (defined(pre)) ? pre.MSuper(pel=pel, hpad=blksize, vpad=blksize, sharp=sharp, chroma=chroma) : super

recalculate = (defined(pre)) ? pre.MSuper(pel=pel, hpad=blksize, vpad=blksize, sharp=sharp, chroma=chroma, levels = 1) :
\ o.MSuper(pel=pel, hpad=blksize, vpad=blksize, sharp=sharp, chroma=chroma, levels = 1)


bv5 = search_super.MAnalyse(isb = true, delta = 5, overlap=overlap, blksize=blksize, search=search, chroma=chroma)
bv4 = search_super.MAnalyse(isb = true, delta = 4, overlap=overlap, blksize=blksize, search=search, chroma=chroma)
bv3 = search_super.MAnalyse(isb = true, delta = 3, overlap=overlap, blksize=blksize, search=search, chroma=chroma)
bv2 = search_super.MAnalyse(isb = true, delta = 2, overlap=overlap, blksize=blksize, search=search, chroma=chroma)
bv1 = search_super.MAnalyse(isb = true, delta = 1, overlap=overlap, blksize=blksize, search=search, chroma=chroma)

fv1 = search_super.MAnalyse(isb = false, delta = 1, overlap=overlap, blksize=blksize, search=search, chroma=chroma)
fv2 = search_super.MAnalyse(isb = false, delta = 2, overlap=overlap, blksize=blksize, search=search, chroma=chroma)
fv3 = search_super.MAnalyse(isb = false, delta = 3, overlap=overlap, blksize=blksize, search=search, chroma=chroma)
fv4 = search_super.MAnalyse(isb = false, delta = 4, overlap=overlap, blksize=blksize, search=search, chroma=chroma)
fv5 = search_super.MAnalyse(isb = false, delta = 5, overlap=overlap, blksize=blksize, search=search, chroma=chroma)

# MRecalculate, if higher quality motion estimation is wanted. It can also be used to speedup, by using higher blksizes

bv5 = RefineMotion ? MRecalculate(recalculate, bv5, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : bv5
bv4 = RefineMotion ? MRecalculate(recalculate, bv4, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : bv4
bv3 = RefineMotion ? MRecalculate(recalculate, bv3, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : bv3
bv2 = RefineMotion ? MRecalculate(recalculate, bv2, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : bv2
bv1 = RefineMotion ? MRecalculate(recalculate, bv1, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : bv1

fv1 = RefineMotion ? MRecalculate(recalculate, fv1, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : fv1
fv2 = RefineMotion ? MRecalculate(recalculate, fv2, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : fv2
fv3 = RefineMotion ? MRecalculate(recalculate, fv3, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : fv3
fv4 = RefineMotion ? MRecalculate(recalculate, fv4, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : fv4
fv5 = RefineMotion ? MRecalculate(recalculate, fv5, blksize=halfblksize, overlap=halfoverlap, thSAD=halfthSAD, search=search, chroma=chroma) : fv5



# Finally, MDegrain

output = (tr == 5) ? Eval("""
mdg3 = o.MDegrain3(super, bv1, fv1, bv2, fv2, bv3, fv3, thSAD=thSAD, limit=limit, limitc=limitc, plane=plane, thSCD1=thSCD1, thSCD2=thSCD2)
mdg3.MDegrain2(super,bv4,fv4,bv5,fv5,thSAD=thSAD, limit=limit, limitc=limitc, plane= plane, thSCD1=thSCD1, thSCD2=thSCD2)
\ .Merge(mdg3, 0.455) # correct weightings (hopefully)
""") :
\ (tr == 3) ? o.MDegrain3(super, bv1, fv1, bv2, fv2, bv3, fv3, thSAD=thSAD, limit=limit, limitc=limitc, plane=plane, thSCD1=thSCD1, thSCD2=thSCD2) :
\ (tr == 2) ? o.MDegrain2(super, bv1, fv1, bv2, fv2, thSAD=thSAD, limit=limit, limitc=limitc, plane= plane, thSCD1=thSCD1, thSCD2=thSCD2) :
\ o.MDegrain1(super, bv1, fv1, thSAD=thSAD, limit=limit, limitc=limitc, plane=plane, thSCD1=thSCD1, thSCD2=thSCD2)

(SMTM) ? SetMTMode(SMTMdefaultmode) : NOP()


output = contrasharp ? ContraSharpening(output, o) : output

return(output)
}



FUNCTION ContraSharpening(denoised, clip)
{

# contra-sharpening: sharpen the denoised clip, but don't add more to any pixel than what was removed previously.
# script function from Didee from the VERY GRAINY thread
s = denoised.minblur(1,1) # Damp down remaining spots of the denoised clip.
allD = mt_makediff(clip,denoised) # 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.

denoised.mt_adddiff(ssDD,U=2,V=2) # Apply the limited difference. (Sharpening is just inverse blurring.)

RETURN (last)
}



Changelog above. MT support can't be disabled for those in Avisynth MT. I don't have it, so I couldn't test it there. It may fail if the setmtmode is wrong.

Besides that, all the new funcionality is optional. But I changed some defaults:

- I lowered the default thSAD from 400 to 200. More adequate for tr = 2.
- Overlap is now half the block size by default. That means 4. You can freely change it, but not lower than that if using RefineMotion.

Dogway
3rd September 2011, 04:12
You can have a look at my smdegrain mod in my signature. I also added refinemotion and prefilter, but the main change is the inclusion of LSB support.

Caroliano
3rd September 2011, 16:43
Hum, intertesting. I was planing to add suport to LSB lattter, but as it wasn't trivial I decided to relase first. Good choice ^^". I will try to merge your changes in my script now, if you don't mind.

By the way, yours 'hpad' and 'vpad' options are not working, as you don't pass those to the msuper. I will fix that also in my script. And I don't know if I should add built-in prefilter option like you did...

Caroliano
3rd September 2011, 22:38
Merge complete. But the script became too big to fit one forum post. So you can download the script from the mediafire url or below in an .zip atachment to this post (when approved).


################################################################################################
### ###
### Simple MDegrain - SMDegrain() ###
### ###
### By Caroliano ###
### ###
### Special Thanks: Didée, Jawed, onesloth, rkalwaitis, Sagekilla and MVtools people ###
### ###
### v0.4 - 03 Sep 2011 ###
### ###
################################################################################################
###
### General purpose pure temporal denoiser, not targeted to a specific source. It is a
### simple wrapper for MDegrain1/2/3, to facilitate using and experimenting with it, with
### minimal dependencies. But it also offers many optional optimizations, plus an internal
### contra-sharpener to make things easier.
###
### Doom9 topic: http://forum.doom9.org/showthread.php?p=1523412
###
### +-----------+
### | CHANGELOG |
### +-----------+
###
###
### v0.4: - Merged changes by Dogway:
### Added parameters "lsb" and "lsb_out", for MVtools2 mod version from cretindesalpes' Dither
### (http://forum.doom9.org/showthread.php?p=1386559#post1386559)
### - Added parameters "hpad" and "vpad"
### - Misc: Fully updated the documentation, copying part of Dogway's updated documentation.
### - Misc: Cosmetics changes on the source code
###
### v0.3 : - Added external prefilted clip option for motion-search (thanks onesloth)
### - Added contrasharpening option (thanks rkalwaitis) <-- new dependencies
### - Shamelesly copied some parts from Jawed's Killer.avsi:
### Added "Refine Motion" (MRecalculate), for possibly improved speed/quality
### Added experimental fake "MDegrain5" with tr = 5
### - Added chroma option for motion-search
### - Experimental SETMOD() support (copied from onesloth mod on fastdegrain())
### - Fix: Plane parameter now works
### - Attention: Changed the defaults for thSAD and overlap.
### - Misc: Cosmetics changes on the source code
### - Misc: A bit more fool-proof
###
### v0.2 : - Added this introductory section
### - Added more parameters
###
### v0.1 : - Basic working version
### - Not released
###
###
### +--------------+
### | DEPENDENCIES |
### +--------------+
###
### Required:
### ------------
### -> MVtools2 (v2.5.11.2 or higher)
### (http://avisynth.org.ru/mvtools/mvtools2.html)
### *or*
###
### -> Dither (1.9.5 or higher) (MVtools2 v2.5.11.2mod included)
### (http://forum.doom9.org/showthread.php?p=1386559#post1386559)
### Optional:
### ------------
### -> MaskTools (v2a48 or higher for lsb=true and/or contrasharp=true) (http://manao4.free.fr/)
### -> Repair (only for contrasharpening=true)
###
###


Download SMDegrain.avsi - v0.4 (http://www.mediafire.com/file/jj294fje0c8k8no/SMDgrain.avsi)

I left out the built-in prefilter options. I'm not sure if there is any agreement on good default pre-filters over here. It seems everyone has his preference, and the strenght should be tweaked for each source. It also adds a bit of complexity, being one more SMDegrain-specific setting that you should remember what each number means. Still, I may change my opinion and add in the future. Or one can add for himself.

I'm still kinda noob with dither and LSB, so I just copied dogway's implementation. It works.

Dogway
4th September 2011, 01:24
Yeah, that's the intention, I kept the nomenclature smdegrain and respected the original script because I liked the idea. I just added things for my tastes, I will still keep using and updating my script with the "mod" suffix to differentiate from yours, and borrow a few changes if you dont mind : )

I chose to have built-in prefilters to keep it "simple mdegrain", but still I added a pre_custom option, so everyone's happy. It seems that in your script you are storing motion vectors and recalculated vectors even when you don't use them, for example in tr=1, or 2. I also didn't understand the preout option.

Thanks for the hpad tip, I missed it. Im also thinking on adding lsb_in option, it would be a "fake" lsb_in, but Im still discussing it in the Dither's "color banding" thread.

Caroliano
4th September 2011, 06:34
It seems that in your script you are storing motion vectors and recalculated vectors even when you don't use them, for example in tr=1, or 2. I also didn't understand the preout option.
I saw that in other scripts using mvtools, and then I tested the script with and without the conditional calculation for motion vectors, and the script ran at the same speed. I therefore assumed that they are calculated only when called by mdegrain. It would be good if someone could confirm or deny it.

The preout was a leftover from debuging. Ignore it. I will erase it latter.

-Vit-
4th September 2011, 11:56
I saw that in other scripts using mvtools, and then I tested the script with and without the conditional calculation for motion vectors, and the script ran at the same speed. I therefore assumed that they are calculated only when called by mdegrain. It would be good if someone could confirm or deny it.
Filters that are ultimately not used will be removed from the filter chain and will have no impact on processing speed. However, any filter that is not guarded by a conditional will be initialized. Some filters allocate memory when they are initialized, so having large numbers of exposed filters that are not used can eat up memory. This was a problem at one point in QTGMC, which explains why it has conditions everywhere.

Dogway
4th September 2011, 18:42
Sorry if a bit offtopic here. Actually there are 2 things I'm not sure about functions... Is it really necessary the return statement at the end of the function?
a = myfunction()
a # instead of "return a"

And also is it really worth conditionals in literal variables? Like:

a = var ? "1" : nop

Gavino
4th September 2011, 21:48
Is it really necessary the return statement at the end of the function?
a = myfunction()
a # instead of "return a"
A bare expression as the final statement in a function is treated as if the return keyword is present. So it's not strictly necessary and is really a matter of personal preference/style.

Personally, I tend to omit 'return' for functions that return a clip and use it in other functions. Not sure why, but it seems more natural that way.

And also is it really worth conditionals in literal variables? Like:
a = var ? "1" : nop
Usually not, but it might help to catch a logic error in your function. If 'a' was expected to be used as a string only when 'var' is true, then setting it conditionally might produce an error if 'a' is later used when unintended.

matfra
12th September 2011, 11:17
Can I compare Smdegrain to McTemporalDenoise ?

matfra
14th September 2011, 13:47
any one lol ?

naoan
14th September 2011, 17:00
Can I compare Smdegrain to McTemporalDenoise ?

any unseen force preventing you to do so?

AzraelNewtype
15th September 2011, 20:26
Can I compare Smdegrain to McTemporalDenoise ?

Apparently not, or we'd have results instead of you waiting for an answer to the question that you probably didn't mean to ask.

gyth
9th October 2011, 13:45
There is a missing dependency, contrasharpen=true needs minblur (http://avisynth.org/mediawiki/MinBlur).

Dogway
9th October 2011, 14:05
@gyth: I updated the script to v.1.45d. Anyway I really would like to see the full version of the contrasharpening function (http://forum.doom9.org/showthread.php?p=1076491#post1076491) after so many years.

Didée
10th October 2011, 10:28
@Dogway - that comment in the posted function is misleading. The "full version" doesn't really exist - it was a theoretical mind game that didn't work out too well in practice.
For what it's supposed to do, the existing contrasharp function is close to the max of possibilities. Possibly, one could expose a few more parameters to offer more fine-control. But from the general method-of-operation, there is hardly anything to improve.

Dogway
10th October 2011, 11:02
Thanks for the note, I was feeling bad thinking I was using everyday a half powered version of a sharpener :o

nibus
28th February 2012, 23:42
is there a limit on thSAD values? I don't notice any changes after about thSAD=1200. This is with contra-sharpening on... does that limit the denoising limit?

Caroliano
29th February 2012, 01:22
I don't know. There is nothing on MVtools documentation about that, and I never went that high. The contra-sharpening kinda puts back some of the noise removed, so for more extreme reductions you may want to turn it off, but I don't know. If your source is very noisy, it may be a good idea to add a prefilter, that will help denoise more and better. Be sure to use tr=3 too.

You may also go for TemporalDegrain(), that is another function using Mdgrain by Didée, for strong moving grain, like the one in 300's from Sparta.

I was going to recomend Dogway's version of the script, but now I don't know where to find it.

thebigmunch
29th February 2012, 02:09
I was going to recomend Dogway's version of the script, but now I don't know where to find it.Thread: http://forum.doom9.org/showthread.php?t=163604

Latest Download: http://www.mediafire.com/?p6w5ndpdag9obym

nibus
29th February 2012, 02:34
Thanks, I'll give that one a shot.

cretindesalpes
29th February 2012, 07:01
is there a limit on thSAD values? I don't notice any changes after about thSAD=1200. This is with contra-sharpening on... does that limit the denoising limit?

The normalised weight applied to a block in the MDegrain averaging is given by this formula:

w = max( 0, 1 - 2*blockSAD² / (thSAD² + blockSAD²) )

So when the block SAD is small (good match) compared to thSAD, w becomes close to 1 and raising thSAD has almost no effect on its value. thSAD basically helps to discard bad blocks, but cannot increase the overall denoising strength if all blocks are already good. For more strength, you'll have to increase the temporal radius to include more frames in the sum.

mastrboy
29th February 2012, 12:18
Excellent explanation cretindesalpes, just wanted to mention that you can affect denoising strength a little by using a prefiltered clip if you don't want to increase radius for some reason. (This off course also depends on the source and prefilter used)

Caroliano
29th February 2012, 15:02
Thread: http://forum.doom9.org/showthread.php?t=163604

Latest Download: http://www.mediafire.com/?p6w5ndpdag9obym
Thanks. I updated the first post.