View Full Version : Dogway's Filters Packs
Julek
11th May 2022, 23:11
I try to find ex_occlusion() but I cannot find it, in which pack is it?
rebranded as MotionMask() (https://github.com/Dogway/Avisynth-Scripts/blob/3ff93a06fb641afc7f712efe54929e03bb1f2fa3/MasksPack.avsi#L345)
anton_foy
12th May 2022, 09:48
rebranded as MotionMask() (https://github.com/Dogway/Avisynth-Scripts/blob/3ff93a06fb641afc7f712efe54929e03bb1f2fa3/MasksPack.avsi#L345)
Oh I see, thanks!
LeXXuz
14th May 2022, 11:52
EDIT: Looks like it was a simple swap of clip variables. I'd swear I had fixed that before, but anyways check now, updated LSFplus and ExTools.
Oops. Totally missed your edit in that post. :o
Just wanted to tell my findings with the (now obsolete) old version. But I'll do it anyway. :D
Did a couple of tests with Blu-ray and DVD sources.
- there was not much of a difference between cs=50 and cs=100 in filesize
- cs=5 however resulted in a notably bigger file than cs=100/50 (setting too low or out of range maybe?)
- LSFplus with CS=50 & limitS=false produced filesizes about equal to cs=true setting
- limitS=true produced much bigger files than limitS=false (that really confused me, thought the limiter should reduce sharpen strength? Or is this because of the swap error in the code?)
However, I'll get the new versions and redo those encodes. Let's see how filesizes will behave. :)
Dogway
14th May 2022, 12:45
Just wanted to tell my findings with the (now obsolete) old version. But I'll do it anyway. :D
Yes sorry, retest if you can as the output made no sense. I think I had been working with another 'secure' optimization with that order and got them mixed up.
Now it should behave as expected (I hope). At the time I recall I preferred contrasharp=true rather than LSF, but now I don't know, specially with the limiters.
LeXXuz
14th May 2022, 13:04
Yes sorry, retest if you can as the output made no sense. I think I had been working with another 'secure' optimization with that order and got them mixed up.
Now it should behave as expected (I hope). At the time I recall I preferred contrasharp=true rather than LSF, but now I don't know, specially with the limiters.
No worries. ;)
Can't run the new LSFplus version though. Get an error upon avs import. See pic:
https://abload.de/thumb/screenshot2022-05-141y5j0f.jpg (https://abload.de/image.php?img=screenshot2022-05-141y5j0f.jpg)
My script has not been changed. Just replaced LSFPlus and Extools with newer versions.
Dogway
14th May 2022, 15:19
Thanks, you are using EX mod right? sometimes some bug might sneak in there as I don't hammer test them as much as MIX mods. Did a 'mode' remap in ExTools so it should work now. Update also LSFplus EX.
LeXXuz
14th May 2022, 15:27
Once again shame on me. :o
Just realized there are 2 different mods.
Yes, I downloaded the Ex mods.
But if you recommend Mix mods for max. speed I'd better switch to those.
Dogway
14th May 2022, 15:37
Yes no prob, just depends what suits you best. EX mods is there for legacy reasons and also max support for those out of Windows.
By the way I was playing a bit and came up with a faster method for corner masks.
removegrain(12)
a=removegrain(17)
removegrain(26)
ex_makediff(a, metric="none", aug=5, dif=true, show=3)
Yes, it's a bit hacky and not as good as CornerMask() but it's much faster.
I cobbled it up into one call for a 18% speed increase:
removegrain(12)
ex_lut("
x[-1,1] A@ x[1,-1] H@ dup1 dup1 min swap2 max
x[0,1] B@ x[0,-1] G@ dup1 dup1 min swap2 max
x[1,1] C@ x[-1,-1] F@ dup1 dup1 min swap2 max
x[-1,0] D@ x[1,0] E@ dup1 dup1 min swap2 max
swap3 max swap2 min
swap3 swap1 swap5 max swap3 min
min swap2 max
dup1 dup1 max swap2 min
x swap2 clip
A B dup1 dup1 min swap2 max
B C dup1 dup1 min swap2 max
C E dup1 dup1 min swap2 max
E H dup1 dup1 min swap2 max
swap7 swap1 swap5 max swap1 swap4 swap2 max max LO^
swap1 swap2 min min min HI^
G H dup1 dup1 min swap2 max
F G dup1 dup1 min swap2 max
D F dup1 dup1 min swap2 max
A D dup1 dup1 min swap2 max
swap7 swap1 swap5 max swap1 swap4 swap2 max max LO max LO^
swap1 swap2 min min min HI min HI@ LO
x swap2 min LO HI max clip
- abs 5 *")
# ex_luts(mode="max",pixels=ex_shape(3,mode="disk"),exprf=" ymin 2 * - 5 * 0 max") # (augmenting the dots)
Compared to CornerMask() (36fps) it's about 3 times faster, including the dot augmentation (101fps).
LeXXuz
14th May 2022, 22:19
Okay I did a few encodes with the new version. Source was an old movie on DVD in black & white.
This is roughly the filtering I used:
#
AssumeFPS(25)
CTelecine()
CPostProcessing()
crop(4, 0, 0, 0)
ConvertBits(16)
PRE=(sneo_dfttest(Y=3, U=1, V=1, tbsize=1, slocation="0.0:2 0.5:12 0.9:24 1.0:48"))
SMDegrain(tr=3, thSAD=600, thSADC=0, LFR=false, contrasharp=25, limitS=true, refinemotion=true, truemotion=true, DCTFlicker=true, Str=5.0, pel=2, subpixel=2, prefilter=PRE, chroma=false, plane=0)
neo_f3kdb(range=30, Y=64, Cb=0, Cr=0, grainY=32, grainC=0, sample_mode=4)
Greyscale()
Prefetch(16,16)
Return(Last)
Results (old faulty version in brackets):
contrasharp=25, limitS=false: 1.42GB (/)
contrasharp=25, limitS=true: 1.66GB (/)
contrasharp=50, limitS=false: 1.42GB (1.62GB)
contrasharp=50, limitS=true: 1.68GB (2.07GB)
contrasharp=100, limitS=false: 1.41GB (1.61GB)
contrasharp=100, limitS=true: 1.70GB (2.07GB)
contrasharp=true, limitS=false: 1.73GB
contrasharp=true, limitS=true: 1.65GB
Encoding speed with limitS=true was slightly faster than with limitS=false.
Conclusion:
- with limitS=false there is no difference in filesize between contrasharp=25/50/100
- with limitS=true the difference in filesize is quite small
- files with limitS=true are bigger than with false.
==>
If all this is correct I clearly misunderstand the 'limit' in limitS-parameter. I expected it to be the other way round. Maybe you can explain a little.
The value for contrasharp (strength of LSFplus) has little to no effect.
Is this what is to be expected with these settings or is there still something wrong maybe?
Dogway
15th May 2022, 01:21
That makes total sense to me, with limitS=false you are using temporal limiting, therefore having more temporal coherence and easier for the codec to compress interframe.
Also I understand you are using limitS=true with contrasharp=true right?
LeXXuz
15th May 2022, 07:35
with limitS=false you are using temporal limiting, therefore having more temporal coherence
Ah now I get it. Yes of course, that makes sense.
Also I understand you are using limitS=true with contrasharp=true right?
EDIT: Yes. I updated the results above and added:
contrasharp=true, limitS=false: 1.73GB
contrasharp=true, limitS=true: 1.65GB
I swear I double checked those numbers. It acts the other way round as with LSFplus. I'm confused again.
And the question remains why has the strength of LSFplus so little to no effect.
And what better to choose from. Contrasharp or LSFplus? Speed is of no concern. Quality is.
Okay I did a few encodes with the new version. Source was an old movie on DVD in black & white.
This is roughly the filtering I used:
SMDegrain(tr=3, thSAD=600,
Is this what is to be expected with these settings or is there still something wrong maybe?
If you need more degraining with quality you need to use as high tr value as possible (memory/threads/speed may limit) and as low thX values as possible. thSAD 600 may be too high for all-frame processing even in the DVD medium grain footage and cause more detail blurring. Typical mvtools builds support tr up to 128 with MDegrainN. It is not physical but some old programming limit like 'as high as never used value' being too slow at old CPUs. Unfortunately it is static array allocation limit so it is good to make dynamic in some new versions to remove this limit. Typically visible effect makes doubling of tr-value like 2,4,8,16,... Changing from 10 to 11 may be close to invisible.
Typically you adjust th-values just above starting to catch noise levels in the footage (and as high as allow to keep valueable details for example at skin textures) and next adjust tr-value to get the most practical degraining (if you not limited by hardware and time to process it have some bitdeph + encoder settings limit: after some high enough value the MPEG output speed and file size almost stop to decrease).
The new alt versions of MDegrain have motion-adaptive th-settings - https://forum.doom9.org/showthread.php?p=1962762#post1962762 . To increase th-values at static and large coherent moving patches and to use 'base' th-value at other blocks to decrease blurring and to increase degraining at static areas.
Theoretically yes, maybe for true static like anime, but for live action half a pixel is the difference between sharp and blurry, MAnalyse might have a hard time picking half a pixel change more so in noisy clips and the higher the 'tr' the blurrier the output.
To decrease noise-affected false movement in MAnalyse output for noisy footages the new MVLPF processing is added in the latest builds of MDegrainN - https://forum.doom9.org/showthread.php?p=1968988#post1968988
Currently 2 filter kernels available - hard cut-off sinc-based and some 'LPF-too' gauss kernel. I currently use gauss as it simple to control and not create over-under shoots in any setting. But I hope some day will read DSP filter design book and will finish filter design with definition both cut-off frequency and some controllable roll-off in pass-band to make it non over/under shooting and ringy. After filtering of MVs the SAD of new positions is re-checked again so too bad SAD-wise new positions are skipped and replaced with original from MAnalyse.
In theory any movie/source is different and needs special adjustment on its own for optimum results.
Practically every cutscene in a movie require its own best settings. It may be shot with different film ISO roll or different camera gain or other noise-reduction manual or auto settings in camera.
"What about the temporal radius? "
Theoretical limit of tr-value for 'ideal engine' sit between typical cutscene duration (several seconds to dozens of seconds X FPS/2 = 100..1000+) to total movie length (about 100000). This theoretical engine must find all occurrences of patch in the cutscene or total movie, perform compensation for all possible transforms and reconstruct patch looking in every frame removing random component that is typically noise. It is really sort of total rebuilding of movie using object-oriented approach. Practically the MPEG encoder makes something close to it but with encoding of residual noise as additional component that can not be compensated using current very limited and poor computing capabilities. So the 'ideal engine' do not have tr-param at all - it analyse all input frames to find all possible occurrences of object. And to prevent blurring (and other distortions like colour) it simply have 'ideal protection' from applying not ideally compensated transforms. Currently all protection from passing to blending operation too badly back-transformed block is based on simple SAD-checking. So to make protection better - we need to set thSAD as low as possible.
Also the protection from too bad blending based on 2 parts:
1. Hard limit by thSAD for total skipping too bad by SAD block from blending.
2. Some soft function for weighting of block's weight in blending for range of SAD in 0..thSAD. The shape of this function is hardcoded in old MDegrain* and some controllable by wpow param in new builds. Old hardcoded default of wpow=2. New builds allow to use 1 to 7 where 7 is simple equal weighting below thSAD (fastest). The actual shape of this weighting function is also subject to big research for some types of footages. Setting wpow above 2 allow to use more weight inside thSAD range and get more degraining, but may cause more distortions in some cases. In my encodings I typically use wpow=4.
Also planned but still not finally debugged some statistical analysis based on idea to check not SAD of current ref block vs current src in tr-scope but make first relative statistical analysis of all frames in tr scope to found most likely looking block in tr-scope and check thSAD of current ref block relative to most likely block. This should help not skip some ref blocks with SAD close to the edges of normal SAD distribution if current source block is located on the other side of normal distribution and SAD-distance close to 2x of the width of distribution. So with successful implementation will allow to set lower 'base' thSAD value with same degraining level and better protection from blurring.
Currently the mvtools makes very limited part of this - it find occurrences of some patch in tr-scope of frames around current and compensate of translate (shift) transform only. But for static parts of cutscene it already works very well so tr-scope for static parts of the frame may cover all cutscene duration.
For scripting it is possible to create motion-mask using mvtools may be too like MMask and process static and moving parts of cutscene with different tr-value (and th-values) to have less blurring of moving (complex transformed) areas of a frame. Though this sometime create effect of very clean static background and still noised moving areas. It still make MPEG average speed lower but some users may prefer evenly covered by noise image. Though in better case required noise should be added at playback.
Dogway
15th May 2022, 12:15
@DTL, a simple low-pass is going to distort edges too much you want to invert the the gauss weighting, just like I pointed with IQM, similar but more complex filters are MinBlur, guidedblur, ANguidedblur and of course bilateral (with some slight blur on top).
AFAIK whatever filtering you apply in the spectrum domain translates to the spatial domain but with less required radius (hence faster), so convert with FFT, apply gaussian LPF and convert back. Gaussian (or binomial) roll-off is smooth so that translates well to the image. For prefiltering I don't know if it's worth it at all, for things like Retinex it does because you apply high sigma radius.
That's unless you want to do passband filtering, in that case have a look at the ex_MFR() diagram in ExTools, since you do substraction spectrum energy is maintained.
The problem with high temporal radius is that the further frames are rarely correlated, since MDegrain performs a temporal mean average this looks risky. Maybe it might be worth to test a weighted average instead, it would lead to less denoising by default so some higher 'tr' should be used.
Did you mention before that 'pzero' or 'pnew' were not relevant for higher than tr=1? I tried to find your post without luck.
@LeXXuz: Yes, those numbers are suprising, but in any case they are two different monsters, I would try to visually compare them and see what they do and don't. If I recall correctly temporal limiting required a bit more sharpening, although some places are never going to sharpen due to the temporal nature.
After LSFplus v5.0 I would say that LSFplus should give more quality, as I chained the Smode algorithm directly to the LSFplus contrasharpening code block, but check visually anyway. I think the lower effect of the strength is because you are contrasharpening, that's totally different than plain LSFplus() sharpening, I also set over/undershoot to 0 to avoid ringing at any cost, so the sharpening is conservative. If you want stronger or very strong sharpening add it post SMDegrain().
"a simple low-pass is going to distort edges too much"
It is filtering of a sequence of MVs in 'time' domain. Not in 2D spatial. The 'ringing or over/under shoot' distortions of the edges values will decrease its efficiency and system just fallback to 'old MAnalyse output MVs' if SAD of the new expected-filtered position is too bad (hard above thSAD, but new filtered position is accepted if its SAD higher in compare with MAnalyse output because it may be distorted by noise). So I not like hard-cutoff sinc-based LPF without some smoothing and use gauss kernel now (with not as sharp cutoff of noise frequencies but easier in implementation and control and possibly better keeps the edges values from running away of good positions because of filtering issues). The actual noise-affected MVs coordinates of static blocks really jumps as hell here and there and their sequence definitely not follow any Nyquist-limiting or anti-gibbs conditioning so all nice developed filtering practices for 2D good images is not applicable to this type of input data to filter. To see how it jumps you can see MShow output in consecutive frames.
" so convert with FFT"
Currently it uses simple C-based convolution and runs fast enough with kernel size about 10. I do not think making FFT with too small size will make speed better. The only good thing of FFT-filtering is a way to apply required curve in 'graphical' form. Not create impulse kernel of filter with desired response.
"The problem with high temporal radius is that the further frames are rarely correlated"
It greatly depends on content - the static background with static lighting is about ideally correlated at the total cutscene duration. Example - static camera and static lighting and small narrator - https://imageban.ru/show/2022/05/13/931e829b35a87b3811aa82e872601c0c/png . About 90..90+% of blocks are close to ideally correlated at the all cutscene duration. In theory it is possible to mix MShow functions with MDegrain to enable 'debug output' text overlay of some statistics to help adjust parameters. For example % of totally skipped blocks in current tr-scope for each frame.
Also with slow enough camera pan we have lots of frames for translate-only compensation and again got very good correlation until block is still in camera visibility. This creates the effect of uneven degraining of static and slow moving areas without other transforms and other fast transformed areas with 'high enough' tr-value.
"Did you mention before that 'pzero' or 'pnew' were not relevant for higher than tr=1? "
I do not think so. They are applicable to every pair of current+ref pairs of frames sent to MAnalyse to process and these pairs processed completely independent (if temporal predictor is disabled). These penalties are about searching steps inside each level inside frames pair. Not about anything inbetween different pairs of frames to analyse. So influence of penalty values should not be any interconnected with tr-value.
"Maybe it might be worth to test a weighted average instead, it would lead to less denoising by default so some higher 'tr' should be used."
MDegrainN already in the 'old' 2.7.45 version create weighted blending based both on tr-distance and SAD value. For tr-distance it is controlled by thSAD2 param interpolation is something about cosine-shaped https://github.com/DTL2020/mvtools/blob/f0da1d9174e65867486d1321ba330471b3e4ee64/Sources/ClipFnc.cpp#L171 and for SAD value it is not user-controllable hardcoded weighting function https://github.com/pinterf/mvtools/blob/d8bdff7e02c15a28dcc6e9ef2ebeaa9d16cc1f56/Sources/MVDegrain3.h#L880 . In the newer builds SAD-weighting is controlled by wpow param.
LeXXuz
15th May 2022, 13:45
Thank you very much DTL and Dogway for your valued input.
I did a lot of encodes with SMDegrain 3.5.0.d recently before I started to test out Dogways current build. And I really mean A LOT.
My findings with that old build clearly backed up what you just wrote DTL. I had presets from (tr=2 & thSAD=150) up to (tr=16
and/or thSAD up to 600) for really really bad sources. Depending on the kind of grain/noise I had to deal with.
And of course you're right, technically every scene can be different. Some scenes looked awesome while others felt worse to the eye than their original counterpart. So it was/is always a compromise to use filtering. I kept some encodes to replace their originals. But I also discarded many encodes because I was not satisfied with the results. I have to admit I'm picky and if the results look (even just partially) bad in any way, I'd rather stay with the untouched source.
Adjusting the filtering for every movie anew already is tiresome work if you plan to transcode a vast collection. Adjust filtering on scene basis clearly exceeds the time I would and could spend on my hobby. I just want to reduce the size of my movie collection and optimize the visuals a little in the process so I have a smaller file with equal or even better visual quality in the end.
However, with Dogways current build my old presets don't work anymore. With his build there has been some great improvement on tricky scenes or objects with much less ghosting or smearing. From what I can see so far, I can use much higher thSAD values than before without destroying detail that would've been with the old version. Right now I'm very happy on that part. All I need now is to find a good setting for the sharpener as the cleaned output is a little softer without it, than the original. It's also funny how noise can be perceived as detail which really isn't there. So the cleaned picture 'feels' dull and a little blury, but it isn't in direct comparison.
I didn't really bother with transcoding in years. With storage space being dead cheap I just remuxed the movies I bought onto my NAS and be done with it.
But through other circumstances I now have quite a lot of CPU power at my disposal which made me revive my old hobby, very much to the burden of my electrical bill. :D
Dogway
15th May 2022, 14:07
Yeah, actually I don't know why I still develop SMDegrain lol. I do like my films grainy, but I still use it when grain is blocky or uneven/dirty, then add grain back.
You can automate scene based SMDegrain filtering with SceneStats, you need to enclose it in a ScriptClip block and tune your values according to the stats.
tormento
15th May 2022, 14:12
You can automate scene based SMDegrain filtering with SceneStats, you need to enclose it in a ScriptClip block and tune your values according to the stats.
Show us. :)
And please don't stop developing. GPU MVTools are arriving and perhaps a new native CUDA BM3D.
LeXXuz
15th May 2022, 14:49
Yeah, actually I don't know why I still develop SMDegrain lol.
Don't you dare and stop your amazing work! :eek::D
Looking at the early days of this forum and the filters/tools available back then, it's amazing how these evolved over the past two decades thanks to each and everyone involved in this process. :thanks:
And with filters like these some movie gems finally get the treatment they deserve. :)
Dogway
15th May 2022, 15:42
By the way Asd-g just released AGM (for AdaptiveGrainMask) plugin. I didn't know what it did until I read it's some kind of exposure reading so there is less overall grain on bright scenes, as it would happen naturally on film.
I'm tempted to try this with cretindesalpes plugin, haven't had time to check it.
Now that I think about it... it only looks for averageluma. Maybe I can implement the '_SceneExposure' algo described here (https://forum.doom9.org/showthread.php?p=1967432#post1967432) on a per frame basis, and use that for modulation in GrainFactory3mod. I mean, AGM is just an opacity mask, it won't tune grain size (among other) based on pixel value.
Scene based SMDegrain:
SceneStats(mode="Range+Stats+Motion+Detail+EV", interval=0.5, th=0.5, dFactor=3.7, show=false)
ScriptClip(function [] () {
sts = propGetAsArray("_SceneStats")
mo = propGetFloat ("_SceneMotion")
de = propGetFloat ("_SceneDetail")
ev = propGetInt ("_SceneExposure")
mo1 = min(6,round(exp(0.54*pow(mo,-0.44)+0.7)-2.9))
mo2 = round(-125*mo+112)
ev1 = ev==5?0:max(0,round(7.7*pow(ev,-0.44)-2.7))
SMDegrain(mo1, 400, prefilter=-1, ContraSharp=mo2, Str=ev1, RefineMotion=true)
} )
Probably for performance reasons it would be better to precompute prefilter clip outside ScriptClip.
Here I only plugged motion and exposure variables but you are free to use other stats or mix them to configure SMDegrain settings.
LeXXuz
15th May 2022, 17:10
And he just pulls that out of the hat. Just like that. :D
However integrating that succesfully into my scripts exceeds a little my Avisynth knowledge which is not much more than loading filters and setting parameters here and there. :o
tormento
16th May 2022, 07:26
However integrating that succesfully into my scripts exceeds a little my Avisynth knowledge which is not much more than loading filters and setting parameters here and there. :o
We share the same boat, pal. :o
kedautinh12
16th May 2022, 17:34
I meet error: "there is no function named "ZoptiResize" when use with video
https://drive.google.com/file/d/1b0WGyIOisK6GgJNs-M_49n7MuG4XFism/view?usp=sharing
my scripts:
LoadPlugin("C:\Megui\MeGUI-2924-64\tools\lsmash\LSMASHSource.dll")
LWLibavVideoSource("C:\Users\ADMIN\Downloads\Yuuri - Betelgeuse [1440x1080i MPEG2 SSTV HD].ts")
AnimeIVTC(mode=1)
deep_resize(1920.0, 1080.0,edge="Zopti2",flat="SoftCubic100",show=false,th=0.6,elast=9)
Dogway
16th May 2022, 17:43
Yes sorry, Zopti2 has been deprecated, it's now called "Zopti" as original name, and old Zopti is now "ZoptiN" for Neutral.
LeXXuz
18th May 2022, 07:34
I've been playing around with different settings.
And I don't get it why this setup:
ConvertBits(16)
PRE=(sneo_dfttest(Y=3, U=3, V=3, tbsize=1, slocation="0.0:4 0.5:16 0.9:32 1.0:64", chrslocation="0.0:2 0.5:8 0.9:16 1.0:32"))
SMDegrain(tr=6, thSAD=600, contrasharp=50, limitS=true, LFR=150, DCTFlicker=true, refinemotion=true, truemotion=true, Str=5.0, pel=2, subpixel=3, prefilter=PRE, chroma=true, plane=4)
neo_f3kdb(range=15, Y=64, Cb=32, Cr=32, grainY=32, grainC=16, sample_mode=4)
Prefetch(16,16)
Return(Last
is much slower than this one:
ConvertBits(16)
PRE=(sneo_dfttest(Y=3, U=3, V=3, tbsize=1, slocation="0.0:4 0.5:16 0.9:32 1.0:64", chrslocation="0.0:2 0.5:8 0.9:16 1.0:32"))
PRE2=SMDegrain(tr=3, thSAD=600, blksize=32, contrasharp=false, limitS=true, LFR=150, DCTFlicker=true, refinemotion=true, truemotion=true, Str=5.0, pel=2, subpixel=3, prefilter=PRE, chroma=true, plane=4)
SMDegrain(tr=6, thSAD=300, blksize=32, contrasharp=50, limitS=true, LFR=false, DCTFlicker=false, refinemotion=true, truemotion=true, Str=5.0, pel=2, subpixel=3, prefilter=PRE2, chroma=true, plane=4)
neo_f3kdb(range=15, Y=64, Cb=32, Cr=32, grainY=32, grainC=16, sample_mode=4)
Prefetch(16,16)
Return(Last)
Or this one:
ConvertBits(16)
PRE=(sneo_dfttest(Y=3, U=3, V=3, tbsize=1, slocation="0.0:4 0.5:16 0.9:32 1.0:64", chrslocation="0.0:2 0.5:8 0.9:16 1.0:32"))
PRE2=(sneo_dfttest(Y=3, U=3, V=3, tbsize=1, slocation="0.0:2 0.5:8 0.9:16 1.0:32", chrslocation="0.0:1 0.5:4 0.9:8 1.0:16"))
SMDegrain(tr=6, thSAD=600, blksize=32, contrasharp=false, limitS=true, LFR=150, DCTFlicker=true, refinemotion=true, truemotion=true, Str=5.0, pel=2, subpixel=3, prefilter=PRE, chroma=true, plane=4)
SMDegrain(tr=3, thSAD=300, blksize=32, contrasharp=50, limitS=true, LFR=false, DCTFlicker=false, refinemotion=true, truemotion=true, Str=5.0, pel=2, subpixel=3, prefilter=PRE2, chroma=true, plane=4)
neo_f3kdb(range=15, Y=64, Cb=32, Cr=32, grainY=32, grainC=16, sample_mode=4)
Prefetch(16,16)
Return(Last)
Results:
https://abload.de/img/enc_times5mjl4.png (https://abload.de/image.php?img=enc_times5mjl4.png)
Filesizes don't differ that much so the encoder has about the same workload. What do I miss here? :eek:
Dogway
18th May 2022, 07:58
Sure, you are using blksize=32, so 4 times less blocks than say 16, but precision in MV is not going to very good so visually check everything is fine.
LeXXuz
18th May 2022, 08:58
Sure, you are using blksize=32, so 4 times less blocks than say 16, but precision in MV is not going to very good so visually check everything is fine.
Totally missed that. Thanks Dogway. :)
EDIT: So increase in blocksize decreases mv precision. 16 is default, right? Would it benefit to go down to 8 if speed is of less concern? Or is the possible visual gain negligible?
Mvtools default blocksize is 8. In some scripts I see recalculation down to 4 for best quality.
increase in blocksize decreases mv precision. '
Not only. It will either blur areas with small different moving objects with large enough thSAD or not degrain with low. Also will more distort edges of objects even with overlap enabled.
LeXXuz
18th May 2022, 16:22
That's interesting and could explain some effects I've seen during my tests.
I'll give it a try with 4 then if there is no other penalty than speed.
"give it a try with 4"
4 may be too low to search directly. It may be better to start search from 8x8 or bigger and recalculate (refine) down to 4x4.
MRecalculate: Refines and recalculates motion data of previously estimated (by MAnalyse) motion vectors with different super clip or new parameters set (e.g. lesser block size), after divide, etc. The two-stage method may be also useful for more stable (robust) motion estimation. The refining is at finest hierarchical level only. Interpolated vectors of old blocks are used as predictors for new vectors, with recalculation of SAD. Only bad quality new vectors with SAD above threshold thSAD will be re-estimated by search. thSAD value is scaled to 8x8 block size. Good vectors are not changed, but their SAD will be re-calculated and updated.
As I see at github the SMDegrain script can do 1 step half size refining with MRecalculate in refinemotion=true mode. So if you use initial blocksize 8 and set refinemotion=true it makes refining to 4x4.
More complex scripts can do >1 step refining so you can start from larger block size like 32x32 to decrease probability of gross search error and make 3 steps refining to 4x4 for best quality.
LeXXuz
18th May 2022, 17:14
So if you use initial blocksize 8 and set refinemotion=true it makes refining to 4x4.
Thanks DTL, I'll give that a try. :)
More complex scripts can do >1 step refining so you can start from larger block size like 32x32 to decrease probability of gross search error and make 3 steps refining to 4x4 for best quality.
Maybe Dogway will add that one day to SMDegrain. :rolleyes::D
"Maybe Dogway will add that one day to SMDegrain"
refinemotion may be changed from single true/false bool to 0 if no refine or number of refine steps. Typical everyday scripts may be designed to have acceptable speed/quality. Not best possible results with low speed.
Also for possibly a bit better quality you may check pel=4. It looks like typical precision of MPEG encoders search now. If found and applied correctly it should save from blurring a bit better. Though it is much slower and need about 4x more RAM in compare with pel=2. So with too much of threads and large frame size it is easy to run out of memory.
LeXXuz
18th May 2022, 19:32
Just running a test. Performance is lower but still okay with blksize=8, pel=4, subpel=3. Around 14FPS now which was ~19FPS before. Machine has 128GB. So memory should not become a bottleneck.
About 'blocksize' in processing: Smallest possible for refining with 'full-samples' size and 4:2:0 is 2x2 luma and 1 chroma samples pair. Though if going down to subsample processing it may be smaller. So it is in theory possible to make refining down to 'per-sample' processing - not per-block. It possibly may reduce some limitations of method based on very limited number of possible to process transforms in current MVtools.
Do not know why current limitation of SMDegrain is: SMDegrain: For RefineMotion you need a blksize of at least 8. If set 4x4 and refine to 2x2 it should be still supported by MVtools ? May be because overlap of 1 is not valid for 2x2 4:2:0 blocks ? So it is needed to convert to 4:4:4 to use refining to lower blocksizes.
Current limitation of min blocksize processing may be easily workarounded by upsizing clip before process and downsizing back after process. But it will be slower and require more RAM.
The script for test about:
N=2 (or 3,4,5...)
MyLovelyResize(width*N, height*N)
SMDegrain(...)
MyLovelyResize(width/N, height/N)
(may be a bit better to use Upsample/Desample functions pairs from jpsdr ResampleMT)
With N=2 and blocksize in degrain 8 and refinemotion=true it will be equal to processing blocksize 4x4 and refining to 2x2 (and doubling of pel precision). Unfortunately it may degrade quality with 'large starting blocksize' so it is better to add more refining steps in degrain script.
Also for better resistance to noise-errors with small blocksizes it may be better to use multi-stage processing starting from large blocksize and lower thSAD values to keep from error-blurring at stages with large blocksize. Also for processing with small blocksize to get less noise-based positions errors it may be good to test with new MVLPF processing versions.
Like
my_thSAD=...(typical thSAD/1.2)
next_step=1.2
SMDegrain(blocksize=16, thSAD=my_thSAD, refinemotion=true)
SMDegrain(blocksize=8, thSAD=my_thSAD*next_step, refinemotion=true)
LeXXuz
19th May 2022, 11:35
Like
my_thSAD=...(typical thSAD/1.2)
next_step=1.2
SMDegrain(blocksize=16, thSAD=my_thSAD, refinemotion=true)
SMDegrain(blocksize=8, thSAD=my_thSAD*next_step, refinemotion=true)
Thanks DTL. I'll give that a try, too. :)
The last time I actively used 2-stage denoising I wasn't really happy with the results. Because smearing and ghosting in fine textures was kinda awful. However, that was with a rather old version way before Dogway implemented all those updates and without modifying the blocksize because I simply didn't know better at that time. :o
LeXXuz
21st May 2022, 20:39
I have a DVD film here with some poor black levels and lots of noise in those black areas.
https://abload.de/thumb/darknoise38jys.png (https://abload.de/image.php?img=darknoise38jys.png)
I've used this so far:
ConvertBits(16)
PRE1=(sneo_dfttest(Y=3, U=3, V=3, tbsize=1, slocation="0.0:3 0.5:12 0.9:24 1.0:48", chrslocation="0.0:1.5 0.5:6 0.9:12 1.0:24"))
PRE2=(sneo_dfttest(Y=3, U=3, V=3, tbsize=1, slocation="0.0:2 0.5:8 0.9:16 1.0:32", chrslocation="0.0:1 0.5:4 0.9:8 1.0:16"))
SMDegrain(tr=6, thSAD=400, blksize=8, contrasharp=false, limitS=true, LFR=150, DCTFlicker=true, refinemotion=true, truemotion=true, Str=5.0, pel=4, subpixel=3, prefilter=PRE2, chroma=true, plane=4)
SMDegrain(tr=3, thSAD=600, blksize=8, contrasharp=50, limitS=true, LFR=false, DCTFlicker=false, refinemotion=true, truemotion=true, Str=5.0, pel=4, subpixel=3, prefilter=PRE1, chroma=true, plane=4)
neo_f3kdb(range=15, Y=64, Cb=32, Cr=32, grainY=32, grainC=16, sample_mode=4)
Prefetch(16,16)
Return(Last)
Daylight sceenes and even indoors look fine. But dark areas still have either noise or somethin that looks like a static noise curtain now.
Would appreciate any advice where/how to tweak.
It may be better to provide sample video for download.
LeXXuz
22nd May 2022, 15:21
It may be better to provide sample video for download.
You are probably right. Here is a sample file:
https://send.cm/d/BLrs
I check it. It looks the script somewhere create great 'shadow detail gain up' and it greatly increase residual dark noise.
I run simple mvtools-based script using my latest build from https://forum.doom9.org/showthread.php?p=1968988#post1968988
LoadPlugin("mvtools2.dll")
LoadPlugin("ffms2.dll")
FFMpegSource2("testsample-001.mkv")
tr = 12 # Temporal radius
super = MSuper (mt=false, chroma=true,pel=2, hpad=8, vpad=8, levels=0)
multi_vec = MAnalyse (super, multi=true, blksize=8, delta=tr, chroma=true, overlap=4, mt=false, optSearchOption=1, levels=0, scaleCSAD=0)
MDegrainN(super, multi_vec, tr, thSAD=300, thSAD2=290, mt=false, wpow=4, thSCD1=350, adjSADzeromv=0.5, adjSADcohmv=0.5, thCohMV=16, MVLPFGauss=0.9, thMVLPFCorr=50)
And it make much less noise at the dark areas of this frame - https://i1.imageban.ru/out/2022/05/26/00c0f8ed1ec8806b2abbe1d49b49deb3.png . I do not tweak parameters - it is some defaults from some testing of different versions with not very noisy content.
LeXXuz
27th May 2022, 09:03
I check it. It looks the script somewhere create great 'shadow detail gain up' and it greatly increase residual dark noise.
Dogway where are you? :D
And it make much less noise at the dark areas of this frame - https://i1.imageban.ru/out/2022/05/26/00c0f8ed1ec8806b2abbe1d49b49deb3.png . I do not tweak parameters - it is some defaults from some testing of different versions with not very noisy content.
Thank you DTL. :) That looks much better indeed. :eek:
I'll give that a try on the entire film and see how it plays out. :)
May be it is something about attempt to keep more details in shadows ? Also can it be levels 0<->16 different conversions to RGB ? I make preview of script in VirtualDub and framegrab via Ctrl+1 command.
May be you can start from disabling most of additional processing like neo_f3kdb(range=15, Y=64, Cb=32, Cr=32, grainY=32, grainC=16, sample_mode=4) to see what cause dark noise increasing.
LeXXuz
27th May 2022, 14:36
I have a DVD film here with some poor black levels and lots of noise in those black areas.
https://abload.de/thumb/darknoise38jys.png (https://abload.de/image.php?img=darknoise38jys.png)
Just to clarify: this is NOT the encoded output. It's a frame from the untouched source.
So you can show the processed source with a script of a dark scene to show the result.
LeXXuz
27th May 2022, 15:26
Sorry for any misunderstanding. I wanted to show the source pic to show you guys what I'm up against. And maybe to give some hints on how to tackle such noise the best way.
The output with SMdegrain() has much less noise but still visible in these scenes. Likewise I'm unsure about the black level as dark scenes clearly look too bright in the source. However, if I play around with PC/TV conversions the ouput got too dark. And it looks too bright when playing the DVD on my TV, too.
I'll show some comparisons with SMDegrain() when I'm back home later this weekend. :)
guest
28th May 2022, 07:56
Hi,
Can you please have a look at this...
https://forum.doom9.org/showthread.php?p=1969586#post1969586
DTL has been posting builds of Mvtools2, and I get an SMDegrain Line 645 error when checking with AVSMeter.
LeXXuz
30th May 2022, 11:36
So you can show the processed source with a script of a dark scene to show the result.
Okay I've encoded the film with the script provided by DTL and my script with SMDegrain. In addition I added sharpening by calling LSFPlus after denoising and finally debanding with f3kdb.
Scripts as follows:
tr = 12 # Temporal radius
super = MSuper (mt=false, chroma=true,pel=2, hpad=8, vpad=8, levels=0)
multi_vec = MAnalyse (super, multi=true, blksize=8, delta=tr, chroma=true, overlap=4, mt=false, optSearchOption=1, levels=0, scaleCSAD=0)
MDegrainN(super, multi_vec, tr, thSAD=300, thSAD2=290, mt=false, wpow=4, thSCD1=350, adjSADzeromv=0.5, adjSADcohmv=0.5, thCohMV=16, MVLPFGauss=0.9, thMVLPFCorr=50)
ConvertBits(16)
LSFPlus(preset="slow", strength=100)
neo_f3kdb(range=15, Y=64, Cb=32, Cr=32, grainY=32, grainC=16, sample_mode=4)
Prefetch(16,16)
Return(Last)
I could not run DTL's script with 16 bit. I always got an Access Violation error, so I had to convert to 16 bit afterwards.
This is the script I used with SMDegrain:
ConvertBits(16)
PRE=(sneo_dfttest(Y=3, U=3, V=3, tbsize=1, slocation="0.0:2 0.5:8 0.9:16 1.0:32", chrslocation="0.0:1 0.5:4 0.9:8 1.0:16"))
SMDegrain(tr=12, thSAD=400, blksize=8, contrasharp=false, refinemotion=true, truemotion=true, Str=5.0, pel=2, subpixel=2, prefilter=PRE, chroma=true, plane=4)
LSFPlus(preset="slow", strength=100)
neo_f3kdb(range=15, Y=64, Cb=32, Cr=32, grainY=32, grainC=16, sample_mode=4)
Prefetch(20,20)
Return(Last)
First of, DTL's script filters the content fairly stronger, resulting in an about 20% smaller output file.
(Also the encoding speed was twice as fast, 23FPS <> 11FPS. BUT that comparison is not fair, as it filters only in 8 bit and is leaving less noise in the output for x265 to handle. So I just put this as a side note in parentheses.)
However, both versions produce a blurring effect I really dislike and keeps me questioning if I should use noise reduction after all to convert my collection.
(I also did encodes without LSFPlus and f3kdb which hat little to no effect to the problem.)
To elaborate:
I've uploaded three files onto send.cm. Please download them to watch as that site doesn't support Matroska containers for direct playback.
File1 (https://send.cm/d/Bk1B)
File2 (https://send.cm/d/Bk1C)
File3 (https://send.cm/d/Bk1D)
File 1 is the original MPEG2 source. File 2 is a conversion with DTL's script to HEVC. File 3 the conversion with SMDegrain.
(Note: I slightly changed the black levels in the conversions, so pay no mind on that pls.)
If you compare both conversions with the original, take a very close look at the texture of John Nettles' (the actor on the left) suit. As he moves away the texture will be washed out making the suit look like an uni-coloured blanket. So to speak.
On a frame-by-frame close-up I saw that some frames are even washed out in the orginal frames, however overall the suit has much more detail in the original than in both conversions.
Right now I'm so focused on this effect that I may be exaggerating. So I'd like some honest opinions on this.:)
No matter what I tweaked, I could NOT get a solution that got rid of this blurring while still doing a decent denoising job overall. Maybe this is just wishful thinking anyway without scene based denoising?
Someone once told me: you can't denoise a video without sacrificing at least some detail. And as much as noise filters have improved, I'm still entitled to say he's probably right. :(
Dogway
30th May 2022, 13:14
The blurring, which I call smearing is a known side-effect, it smears low frequency details.
For that I made the LFR arg to recover some, it brings back some dirt blobs so it's better used with DCT=true (I might improve this area).
ConvertBits(16)
SMDegrain(tr=12, thSAD=400, blksize=8, contrasharp=100, refinemotion=true, LFR=150, DCTflicker=true, Str=3.0, pel=2, subpixel=2, prefilter=6, chroma=true, plane=4)
ConvertBits(8,dither=1)
This is low frequency detail that is recovered, low contrast high frequency detail is going to be lost since it will read as noise because getting that fine motion vectors is unpractical. For that reason I usually add grain afterwards for some "hallucination". But I think you are going for the high compressibility/clean look.
If you just want to denoise low luma areas pass the denoiser through a lumamask()
---------------------------
By the way, on another note. I'm making a BATCH file to process images in an easy way, so one can leverage the powerful AVS tools with cjxl, the state-of-the-art JPEG XL image compression encoder.
As I observed all the programs I found either don't support JXL or they support it but scarce on filtering options. As an example, ImageMagick doesn't support jxl --quality argument, besides its bicubic scaler coefficients don't match avisynth's (avisynth adds a preblurring of some sorts) so it's hard to relate.
Will upload soon with some TransformsPack updates.
"I could not run DTL's script with 16 bit. I always got an Access Violation error, so I had to convert to 16 bit afterwards."
It looks some bug with 16bit input to MAnalyse now. Current workaround is to feed MAnalyse with 8bit input:
ConvertBits(16)
tr = 12 # Temporal radius
super = MSuper (mt=false, chroma=true,pel=2)
super8 = ConvertBits(8).MSuper (mt=false, chroma=true,pel=2)
multi_vec = MAnalyse (super8, multi=true, blksize=8, delta=tr, chroma=true, overlap=4, mt=false, optSearchOption=1)
MDegrainN(super, multi_vec, tr, thSAD=300, thSAD2=290, mt=false, wpow=4, thSCD1=350, adjSADzeromv=0.5, adjSADcohmv=0.5, thCohMV=16, MVLPFGauss=0.9, thMVLPFCorr=50)
" take a very close look at the texture of John Nettles' (the actor on the left) suit. As he moves away the texture will be washed out making the suit look like an uni-coloured blanket. "
To possibly keep more low contrast details you can try more extreme settings like
tr = 15
super = MSuper (mt=false, chroma=true,pel=2)
super8 = ConvertBits(8).MSuper (mt=false, chroma=true,pel=2)
multi_vec = MAnalyse (super8, multi=true, blksize=8, delta=tr, search=3, searchparam=4, truemotion=true, chroma=true, overlap=4, mt=false, optSearchOption=1)
MDegrainN(super, multi_vec, tr, thSAD=100, thSAD2=100, mt=false, wpow=4, thSCD1=350, adjSADzeromv=0.3, adjSADcohmv=0.3, thCohMV=4, MVLPFGauss=0.9, thMVLPFCorr=20)
It will reduce global degrain level visibly. Though Dogway's script work also good. To keep more details - also try to use as low thSAD values as possible.
Blankmedia
31st May 2022, 00:39
I'm only here to talk about our lord and savior :
Flatmask
ex_retinex as no argument tv_in error on line 161.
Thanks again for your splendid work.
Dogway
31st May 2022, 01:27
I'm only here to talk about our lord and savior :
Flatmask
ex_retinex as no argument tv_in error on line 161.
Thanks again for your splendid work.
Did you update? tv_in was added in last commit (https://github.com/Dogway/Avisynth-Scripts/blob/2d509f9c8dacc332c090fd3560fc1b2e331296f1/SMDegrain%20v3.5.0d/SMDegrain%20v3.5.0d.avsi#L871).
Anyway just updated SMDegrain now with the most recent changes.
Blankmedia
31st May 2022, 03:40
Did you update? tv_in was added in last commit (https://github.com/Dogway/Avisynth-Scripts/blob/2d509f9c8dacc332c090fd3560fc1b2e331296f1/SMDegrain%20v3.5.0d/SMDegrain%20v3.5.0d.avsi#L871).
Anyway just updated SMDegrain now with the most recent changes.
-_-
Only thing I didn't update and I didn't check in what script ex_retinex was before posting.
thank you
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.