View Full Version : Need Suggestions for VERY GRAINY source
Adub
15th February 2008, 22:27
Cool, will do.
Edit: Done.
Sagekilla
15th February 2008, 22:50
Also, I just got my hands on a new Blu-Ray drive so I can finally rip and play with 300 in HD! I'll see if I can do a before and after using 1080p frames to show how well it works, and help me do testing to improve it. If I have enough time, I might even encode it twice to show the bitrate reduction possible.
Edit: How odd, I tried changing the idx on the NR2 MVDegrain from idx=2 to idx=3 and wanna know what my results were? idx=2 (same idx as the last MVdegrain) was more detailed and looked better. It was only MARGINALLY better though. You have to look VERY closely to see if there was any change.
Results from no TD (first one) vs with TD
G:\Movies\300_HD>x264_aq --crf 18 --ref 5 --mixed-refs --no-fast-pskip --bframes
16 --bime --weightb --b-pyramid --b-rdo --8x8dct --subme 7 --me umh --trellis 1
--aq-strength 0.3 --threads auto --progress "source.avs" --output "Grainy.264"
--pass 1 --stats "Grainy.log"
avis [info]: 1920x800 @ 23.98 fps (360 frames)
x264 [info]: using cpu capabilities: MMX MMXEXT SSE SSE2 SSE3 3DNow!
x264 [info]: slice I:2 Avg QP:15.80 size:402956 PSNR Mean Y:47.30 U:51.04
V:51.57 Avg:48.26 Global:48.26
x264 [info]: slice P:181 Avg QP:18.05 size:224610 PSNR Mean Y:44.65 U:49.72
V:50.04 Avg:45.80 Global:45.78
x264 [info]: slice B:177 Avg QP:20.15 size:152771 PSNR Mean Y:42.90 U:49.27
V:49.64 Avg:44.20 Global:44.18
x264 [info]: mb I I16..4: 29.0% 45.7% 25.3%
x264 [info]: mb P I16..4: 29.5% 16.7% 12.0% P16..4: 18.4% 17.3% 5.1% 0.0% 0
.0% skip: 0.9%
x264 [info]: mb B I16..4: 13.4% 7.8% 7.2% B16..8: 38.1% 6.1% 6.6% direct:
14.4% skip: 6.4%
x264 [info]: 8x8 transform intra:28.5% inter:17.4%
x264 [info]: ref P 75.9% 12.5% 6.4% 3.2% 2.1%
x264 [info]: ref B 74.2% 19.5% 4.4% 2.0%
x264 [info]: SSIM Mean Y:0.9813726
x264 [info]: PSNR Mean Y:43.801 U:49.506 V:49.853 Avg:45.025 Global:44.928 kb/s:
36497.25
encoded 360 frames, 0.68 fps, 36497.60 kb/s
G:\Movies\300_HD>pause
Press any key to continue . . .
G:\Movies\300_HD>pause
Press any key to continue . . .
G:\Movies\300_HD>x264_aq --crf 18 --ref 5 --mixed-refs --no-fast-pskip --bframes
16 --bime --weightb --b-pyramid --b-rdo --8x8dct --subme 7 --me umh --trellis 1
--aq-strength 0.3 --threads auto --progress "source.avs" --output "NotGrainy.26
4" --pass 1 --stats "NotGrainy.log"
avis [info]: 1920x800 @ 23.98 fps (360 frames)
x264 [info]: using cpu capabilities: MMX MMXEXT SSE SSE2 SSE3 3DNow!
x264 [info]: slice I:2 Avg QP:15.45 size:278436 PSNR Mean Y:47.03 U:51.37
V:51.57 Avg:48.07 Global:48.07
x264 [info]: slice P:136 Avg QP:17.75 size:108867 PSNR Mean Y:44.63 U:50.04
V:50.26 Avg:45.81 Global:45.79
x264 [info]: slice B:222 Avg QP:19.84 size: 32984 PSNR Mean Y:43.42 U:50.00
V:50.23 Avg:44.73 Global:44.71
x264 [info]: mb I I16..4: 21.3% 54.7% 24.0%
x264 [info]: mb P I16..4: 6.4% 12.5% 3.1% P16..4: 34.6% 30.1% 11.2% 0.0% 0
.0% skip: 2.1%
x264 [info]: mb B I16..4: 0.3% 0.7% 0.2% B16..8: 38.1% 3.7% 8.2% direct:
6.2% skip:42.6%
x264 [info]: 8x8 transform intra:57.0% inter:46.0%
x264 [info]: ref P 70.6% 21.3% 3.3% 2.4% 2.3%
x264 [info]: ref B 85.3% 13.8% 0.6% 0.3%
x264 [info]: SSIM Mean Y:0.9810072
x264 [info]: PSNR Mean Y:43.895 U:50.026 V:50.245 Avg:45.159 Global:45.100 kb/s:
12086.75
encoded 360 frames, 0.26 fps, 12087.09 kb/s
G:\Movies\300_HD>pause
Press any key to continue . . .
Sagekilla
17th February 2008, 00:02
Sasovics, did my updated script or the uploaded version work for you at all or do you still have problems?
Sasovics
17th February 2008, 02:06
Post moved to separate topic here (http://forum.doom9.org/showthread.php?t=134917)
Sagekilla
17th February 2008, 02:55
Please don't use my FastDegrain -- It's currently b0rked. Also, Sasovics please don't cross post.
Nikos
17th February 2008, 03:48
Edit: How odd, I tried changing the idx on the NR2 MVDegrain from idx=2 to idx=3 and wanna know what my results were? idx=2 (same idx as the last MVdegrain) was more detailed and looked better. It was only MARGINALLY better though. You have to look VERY closely to see if there was any change.
According to Didée from post 125 for using 2 mvdegrain (mvdegrain2+mvdegrain1):
Without corrected weightings, it will denoise less, not more. (Unless you split the idx'es, then it will denoise more indeed.)
With the word split he mean different idx in each degrainX?
We need a little more teaching from Didée about idx :)
Terranigma
17th February 2008, 04:30
I think the guy "Bobby" who encoded the movie, had to use some kind of combination of avs filters as I am using the very same x264 encoder settings and of course the very same source, US retail HDDVD.
I have tried various avs filters, including Sagekilla's TemporalDegrain, FastDegrain, Dark Shikari's GrainOptimizer,
as well the LimitedSharpenFaster alone and many more.
None of them helped to get to the quality of iLL release :(
Because iLL's like the greatest (real-life source) encoder there is?
They don't use any of these premade scripts, I can tell you that for sure. :)
Sasovics
17th February 2008, 04:33
Because iLL's like the greatest (real-life source) encoder there is?
They don't use any of these premade scripts, I can tell you that for sure. :)
Don't understand what you mean with that "real-life source"
.. if they don't use these scripts, what are they using ? How can you tell ?
Terranigma
17th February 2008, 04:42
Don't understand what you mean with that "real-life source"
Real Life source, as in, non-toon sources (like this movie 300 for instance).
.. if they don't use these scripts, what are they using ? How can you tell ?
I can tell because they've been encoding way before temporaldegrain, mc_spuds, or this thread started, so that shouldn't be so hard to figure out.:cool:
(btw, lets leave out encoders or groups for that matter, as it's against the rules per se.)
Lets just say that what they use is actually simpler than you think; btw, it's not so hard to write scripts, just look over the syntax document in avisynth's directory, or take examples from scripts like mc_spuds or temporaldegrain for that matter.
Sagekilla
17th February 2008, 05:14
Real Life source, as in, non-toon sources (like this movie 300 for instance).
I can tell because they've been encoding way before temporaldegrain, mc_spuds, or this thread started, so that shouldn't be so hard to figure out.:cool:
(btw, lets leave out encoders or groups for that matter, as it's against the rules per se.)
Lets just say that what they use is actually simpler than you think; btw, it's not so hard to write scripts, just look over the syntax document in avisynth's directory, or take examples from scripts like mc_spuds or temporaldegrain for that matter.
Indeed, TD is fairly simple as far as filter chains go. It doesn't use a lot of complex concepts compared to others imo.
Didée
17th February 2008, 19:03
ATM I've not the energy (a really bad flu', can't concentrate) to cut through all the stuff posted on the last few pages.
Not sure if it's to rate as "tragedy" or "comedy" ... In any case, lots of nonsense has been posted.
There've been really screwed-up findings & correlations about blocksizes, bogus inventions like "detection thresholds", funny alternate filters (dfttest with default tbsize=1 versus fft3dfilter with bt=5 ... hell, you cannot compare that!), instances of non-functional functions, even posted to the wiki (Sagekilla, do you actually try your own stuff? MVAnalyse has no argument "ov", only "overlap", and why is "ov" responsible for "blocksize"), backwards-evolutions of proven concepts (in the longer-ago past, the biggest complain about MVDenoise was blockyness due to not-yet implemented block-overlap modes ... nowadays block overlapping is hardcoded'ly taken away because of performance...welcome in stoneage), and what not else.
Back to sick bed, crying in silence.
Terranigma
17th February 2008, 19:42
Welcome back Didée. Hope you get well soon, and then you can explain to us about some of the nonsense that was posted (I know that i'm responsible for most of it. :D). Honestly though, Fizick would have to update his document if blocksize 4 is weaker than blocksize 8 for denoising. I was thinking that they also functioned like the blockx, blocky arguments in tfm. Again, from comparisons i've done, blocksize 4 seemed to be stronger than 8 and 16 just like how Fizick has it documented, but whatever: you're the expert around these parts. :)
jeffy
17th February 2008, 20:54
Didée,
please get well soon and forget all the nonsense for a while!
:thanks: for everything.
Back to sick bed, crying in silence.
foxyshadis
17th February 2008, 22:22
It's not so much that blocksize 4 is stronger, it's that it has a higher chance of making bad correlations and subsequently denoising places that shouldn't by rights have been affected. Meaning smudgier details and edges in random places. blocksize 8 or 16 with a soft threshold, as Didée's been asking for forever, would be a better improvement.
Zanejin
17th February 2008, 23:32
It's not so much that blocksize 4 is stronger, it's that it has a higher chance of making bad correlations and subsequently denoising places that shouldn't by rights have been affected. Meaning smudgier details and edges in random places. blocksize 8 or 16 with a soft threshold, as Didée's been asking for forever, would be a better improvement.
So for MVAnalyse, based purely on results for MVDegrain, the blksize value that gives the greatest speed also happens to give the strongest and most accurate filtering?
Nikos
18th February 2008, 03:45
Welcome back Didée.
Please explain to me the differents if any between 1 and 2:
1.
source=last
b1_vec = source.MVAnalyse(isb = true, delta = 1, blksize = 8, overlap =4, pel = 2, sharp= 2, idx=1)
f1_vec = source.MVAnalyse(isb = false, delta = 1, blksize = 8, overlap =4, pel = 2, sharp= 2, idx=1)
NR1=source.MVDegrain1(b1_vec, f1_vec, thSAD = 400, idx = 1)
NRa=NR1.MVDegrain1(b1_vec, f1_vec, thSAD = 400, idx = 1)
2.
source=last
b1_vec = source.MVAnalyse(isb = true, delta = 1, blksize =8, overlap = 4, pel = 2, sharp = 2, idx = 1)
f1_vec = source.MVAnalyse(isb = false, delta = 1, blksize =8, overlap = 4, pel = 2, sharp = 2, idx = 1)
NR1=source.MVDegrain1(b1_vec, f1_vec, thSAD = 400, idx = 1)
NRb=NR1.MVDegrain1(b1_vec, f1_vec, thSAD= 400, idx = 2)
And the correlation, if any between the two above with this:
3.
source=last
b2_vec = source.MVAnalyse(isb = true, delta = 2, blksize = 8, overlap = 4, pel = 2, sharp = 2, idx = 1)
b1_vec = source.MVAnalyse(isb = true, delta = 1, blksize = 8, overlap = 4, pel = 2, sharp = 2, idx = 1)
f1_vec = source.MVAnalyse(isb = false, delta = 1, blksize = 8, overlap = 4, pel = 2, sharp = 2, idx = 1)
f2_vec = source.MVAnalyse(isb = false, delta = 2, blksize = 8, overlap = 4, pel = 2, sharp = 2, idx = 1)
NRc=source.MVDegrain2(b1_vec, f1_vec, b2_vec, f2_vec, thSAD = 400, idx = 1)
I know that here (3) we have more frames.
Thank you.
foxyshadis
18th February 2008, 03:58
Strongest and fastest, but least accurate. On the other hand, it can be more accurate on some edges. Using large blocksizes in most areas and progressively smaller ones in occulded areas is the best way, as x264 does, but what can you do at the moment, y'know? This was discussed in the mvtools thread a while back.
Nikos
18th February 2008, 15:17
Thank you foxyshadis for the reply. Yoy mean that 1 and 2 are strongest and fastest but least accurate than 3 in my understanding.
What's the differents between 1 and 2?
Both of them are correct or only one?
foxyshadis
18th February 2008, 19:34
Sorry, that was a reply to Zanejin.
You always have to use a new idx when you use a new source (unless you use pel=1, then idx doesn't offer a speedup). So you have one idx for MV with source, and another idx for MV on NR1.
Nikos
18th February 2008, 20:25
Thank you foxyshadis for the explain.
With simple words the right script is the 2 with idx=2.
2.
source=last
b1_vec = source.MVAnalyse(isb = true, delta = 1, blksize =8, overlap = 4, pel = 2, sharp = 2, idx = 1)
f1_vec = source.MVAnalyse(isb = false, delta = 1, blksize =8, overlap = 4, pel = 2, sharp = 2, idx = 1)
NR1=source.MVDegrain1(b1_vec, f1_vec, thSAD = 400, idx = 1)
NRb=NR1.MVDegrain1(b1_vec, f1_vec, thSAD= 400, idx = 2)
thetoof
19th February 2008, 07:37
@ Didée
From what you said... I guess/hope you'll rewrite the script to correct everything and I was wondering if you could add (or simply explain how to do it) a function to use dfttest and fft3dfilter at the same time. Maybe it's just a bad idea to use 2 denoisers... but the source I have requires additional chroma denoise with specific s2/3/4 values with fft3d to be clean.
I tweaked the parameters of dfttest in the TemporalDegrain.avsi and I got pretty good results, but couldn't find a way to add fft3d... hope you'll be willing to help me.
archaeo
25th February 2008, 00:16
Just tried sagekilla's TemporalDegrain() on a very grainy old film transfer: "I am a Fugitive from a Chain Gang" (1932), and I am very impressed with the results (See attachments). The grain on the original transfer was extremely heavy, and other degrain combinations never got close to the results I got with TD... Slow...YES, (even with an E6700, I only got about 2 fps) but well worth the wait.
I have also tried this on a couple of other older films, with similar results - grain virtually gone, but excellent detail retention. Very nice script!
I only wish there was a way to speed it up a bit with MT :(
Original clip: http://www.mediafire.com/?mi11znznz3r
TD clip: http://www.mediafire.com/?its3m3z9yud
stills:
8141
8142
Nikos
28th February 2008, 02:01
I read an old Didee's post in another forum and i replace the prefilter with this:
soft = hqdn3d(source).bicubicresize(source.width/4/4*4,source.height/4/4*4).bicubicresize(source.width,source.height,1,0)
filter=mt_lutxy( source, soft, "x y = x x x y - abs 1 + 1 2 / ^ x y - x y - abs / * - ?", U=2, V=2 )
The different in rendering speed was respectable, +40% with overlap=4, and +70% with overlap=2.
I use MVDegrain2 and MT(2,2).
The quality in my eyes was the same, but i want an opinion from experienced user.
Any idea for another correct "spat" filter?
Didee help us :)
Didée
28th February 2008, 08:42
Several issues.
1) The string in lutxy is wrong. That syntax was for YV12lutxy() of old MaskTools v1.
For mt_Lutxy of MaskTools v2, the string has to be "x y == ..." (TWO equal signs. Try to retun "filter" with your current syntax, you'll immediately see that something's wrong.)
2) With that order of filters, you're actually nullifying the effect of HQDN3D. In this case, the more reasonable ordering is
soft = source.bicubicresize(source.width/4/4*4,source.height/4/4*4).bicubicresize(source.width,source.height,1,0)
filter=mt_lutxy( source, soft, "x y == x x x y - abs 1 + 1 2 / ^ x y - x y - abs / * - ?", U=2, V=2 ).hqdn3d()
3) Whether pre-denoising is needed at all depends on the stronginess of grain. I see slight danger that this sort of processing now gets thrown at all kind of sources, even those that don't need such a processing method.
4) That combo is a very speedy trick-filter. It might work out for the most part, but there'll be cases where it bites you back. Dumb filters can destroy the motion of rather smooth regions (e.g. close-up of smooth faces + head-movement) strong enough so that MVTools won't reckognize motion anymore.
BTW, HQDN3D is generally not fully safe in this respect.
4) We have about one thousand different denoising filters or -scripts. If source has strong grain, the pre-filtering should be barely strong enough to make static areas calm.
Which filter that is or could be, depends on the source. If you're going to ask about all thousand possibilities, this thread will become long. ;)
Nikos
28th February 2008, 14:52
Thanks Didée for the correction. That syntax was for YV12lutxy(). The reverse polish notation is a little difficult. What's the different beetween the "==" and "="? These days i read your old post to find out solutions for my problems :)
If you want translate in simple maths the function.
I need a speedy prefilter whith acceptable (not high) quality with for High Definition sources with moderate or low noise. The prefilter must be spatial, temporal, or spatiotemporal; I must put the spatial first or the temporal;
The FFT3DGPU is suitable for prefilter?
It's a good idea to write a "magic" script for prefilter in MVDegrain with options for heavy, medium or light denoise :)
Any help.....
Didée
28th February 2008, 16:35
"=" is an assignment, whereas "==" means "is equal to" in logical expressions.
a = 3 # assign the value "3" to the variable "a"
a == 4 # this is "TRUE" if "a" has the value "4", and is "FALSE" if "a" has ar value other than "4".
The syntax used by MaskTools v1 ever was wrong in that respect. MaskTools v2 now has it correct.
The reverse polish notation is a little difficult. No, not really. It's just a matter of practice.
"x y == x x x y - abs 1 + 1 2 / ^ x y - x y - abs / * - ?"
reads in english
IF (x is equal to y)
THEN (use x)
ELSE (apply the square root of (difference between x and y, plus 1) to x)
I need a speedy prefilter whith acceptable (not high) quality with for High Definition sources with moderate or low noise.
For low noise you need exactly no prefiltering at all. Use MVDegrainX directly as stated in MVTools' documentation.
The FFT3DGPU is suitable for prefilter?
When asking questions where the only objective answer is "there is no objective answer", it won't get better if you guys keep asking over and over again.
Nikos
28th February 2008, 17:09
Now with your help i begin to understand the mask tool and the Reverse Polish notation.
Now i am going for practice. I will be back soon with more serious questions :)
Thanks for your time to answer my questions.
jeffy
28th February 2008, 19:23
"x y == x x x y - abs 1 + 1 2 / ^ x y - x y - abs / * - ?"
reads in english
IF (x is equal to y)
THEN (use x)
ELSE (apply the square root of (difference between x and y, plus 1) to x)
Didée, could you please rewrite the lime part in a normal (infix) notation? Thank you.
Didée
28th February 2008, 21:01
In infix notation it is
(x == y) ? x : x - ( sqrt( abs( x - y ) + 1 ) * ( x - y ) / abs( x - y ) )
That's very basic math. Everyone once has used something like
clip1 = last
clip2 = clip1.blur(1)
result = clip1 .merge( clip2, 0.4 )
What is this? It is: apply a filter to your source (here: blur filter), but use only 40% of the result. (Or the resulting effekt). That's trivial, isn't it?
From a slightly different angle, it is this: calculate something, but instead of just using the resulting difference, multiply the difference by 0.4 before using it. That's a linear function: F(diff) = diff * p
Now, what the initial code does is just this: instead of using a linear function to reduce the effect, it uses a square root function: F(diff) = sqrt(diff)
That's all, and hardly worth all the babbling. :)
Lorax2161
28th February 2008, 22:48
Actually, thank you for "babbling." Not everyone is at the same level, and I learned some things from it. A good explanation goes a long way to helping people open doors they thought were locked.
BTW, to further on what archaeo said, I ran TemporalDegrain() on a somewhat noisy cable tv capture and the results were stunning. (I didn't know how noisy it was until after it was cleaned.) I only get 1.8fps on my dual core machine, but I haven't seen anything at any speed that comes close to that quality, especially true if I follow it with LSF. So to you and sagekilla I say thanks.
Nikos
28th February 2008, 22:48
To help a little.
( x - y ) / abs( x - y ) = sign(x-y)
In masktools Round(1.5)=? and Round(-1.5)=?
I suppose 2 and -1, but i am not sure.
Terranigma
28th February 2008, 23:22
I think you guys may want to split this thread into a new one, because it's now getting way offtopic :)
NathanX
3rd March 2008, 10:22
Please don't use my FastDegrain -- It's currently b0rked. Also, Sasovics please don't cross post.
Your FastDegrain scripts sounds interesting to me, is it still in development?
Thank you!
ChrisW77
3rd March 2008, 15:55
Sagekilla, Thats one amazing script that works extremely well on SD material, and heck, even on old VHS it does wonders.
So thanks to both you and Didee :)
I'm currently using Temporal Degrain V1.18 (Feb 14, 2008), but cannot seem to get any joy from MT, CPU doesn't go above 60% usage, no matter where I put SetMTmode(2) in a simple script.
For instance
SetMemoryMax(512)
LoadPlugin("C:\Program Files\AviSynth\plugins\DGDecode.dll")
LoadPlugin("C:\Program Files\AviSynth\plugins\mpasource.dll")
Import("C:\Program Files\AviSynth\plugins\TemporalDegrain2.avs")
SetMTmode(2)
video = mpeg2source("D:\DVB-T\test1.d2v", cpu=4, iPP=true, idct=3)
audio = MPASource("D:\DVB-T\test1 T01 DELAY 0ms.mpa", normalize = false)
AudioDub(video, audio)
ConvertToYV12(interlaced=true)
AssumeTFF()
SeparateFields()
TemporalDegrain()
Weave()
Crop(8,8,-8,-8,align=true).Addborders(8,8,8,8)
This is just a simple DVB-T capture test, keeping interlaced full frame, and on my Core2duo E6300 I get around 3 fps with or without SetMTmode(2).
One thing I have tried, as I have a powerful GPU (8800GT), that gained me 13fps from 3fps to 16fps with out any perceived loss in quality, is to modify your function as follows
Change all FFT3D entries to FFT3dGPU, changing BT=5 to BT=4, as the GPU version doesn't support 5, and blksize from 8 to 16. Huge speedup, and I couldn't see any difference in quality.
Many thanks for this function, it's amazing. :D
archaeo
3rd March 2008, 19:09
I'm currently using Temporal Degrain V1.18 (Feb 14, 2008), but cannot seem to get any joy from MT, CPU doesn't go above 60% usage, no matter where I put SetMTmode(2) in a simple script.
Try MT("TemporalDegrain()").
It worked well for me - I am seeing 90% plus usage on my Core2
Boulder
3rd March 2008, 19:20
I wonder if MVAnalyse/MVDegrain plays nice with MT..nobody ever tested it IIRC.
ChrisW77
3rd March 2008, 20:17
Try MT("TemporalDegrain()").
It worked well for me - I am seeing 90% plus usage on my Core2
Thanks, I'll give that a try.
Terranigma
3rd March 2008, 20:21
I wonder if MVAnalyse/MVDegrain plays nice with MT..nobody ever tested it IIRC.
I don't know what this (http://forum.doom9.org/showthread.php?p=1056510#post1056510) is exactly, but I stumbled across it in the MT thread. :P
maxisvk
3rd March 2008, 20:44
Thanks, I'll give that a try.
This is my test on Core 2 Duo with TemporalDegrain()
SetMTMode(2,0) , 50% Cpu
SetMTMode(2,3) , 65% Cpu
SetMTMode(2,4) , 90/100% Cpu
on Q6600 is the same, only if i use SetMTMode(2,8) it work at 100%
ChrisW77
3rd March 2008, 21:01
SetMTMode(2,4) , 90/100% Cpu
Yes, yes, now that worked well, getting 95% continuous. Cheers :) Never thought of using 4 threads.
A strange thing I found with MVTools was this
SetMemoryMax(512)
LoadPlugin("C:\Program Files\AviSynth\plugins\RemoveGrainSSE2.dll")
LoadPlugin("C:\Program Files\AviSynth\plugins\MVTools.dll")
LoadPlugin("C:\Program Files\AviSynth\plugins\DeGrainMedian.dll")
LoadPlugin("C:\Program Files\AviSynth\plugins\DGDecode.dll")
LoadPlugin("C:\Program Files\AviSynth\plugins\mpasource.dll")
SetMTmode(2)
video = mpeg2source("D:\VHS\90sadverts.d2v", cpu=6, iPP=true, idct=3)
audio = MPASource("D:\VHS\90sadverts T01 DELAY 0ms.mpa.d2a", normalize = false)
AudioDub(video, audio)
source=ConvertToYV12(interlaced=true).Crop(10,4,-10,-10,align=true).Addborders(10,7,10,7)
fields=source.AssumeTFF().SeparateFields().DeGrainMedian(mode=0,interlaced=false).RemoveGrain(mode=2)
lbda=512
blk=16
ol=8
sch=2
pel=1
backward_vec2 = fields.MVAnalyse(isb=true, search=sch, truemotion=true, lambda=lbda, delta=2, pel=pel, blksize=blk, overlap=ol, sharp=1, idx=1)
backward_vec1 = fields.MVAnalyse(isb=true, search=sch, truemotion=true, lambda=lbda, delta=1, pel=pel, blksize=blk, overlap=ol, sharp=1, idx=1)
forward_vec1 = fields.MVAnalyse(isb=false, search=sch, truemotion=true, lambda=lbda, delta=1, pel=pel, blksize=blk, overlap=ol, sharp=1, idx=1)
forward_vec2 = fields.MVAnalyse(isb=false, search=sch, truemotion=true, lambda=lbda, delta=2, pel=pel, blksize=blk, overlap=ol, sharp=1, idx=1)
fields.MVDegrain2(backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=800,idx=1).MVDenoise(backward_vec2,backward_vec1,forward_vec1,forward_vec2,tht=10,thSAD=800)
Weave()
That script ran well and fast, constantly at 100%, until it finished. Yet, add anything after weave, such as LimitedSharpenFaster, or even Tweak, and it kind of broke MT, and you were left with a script running 55%.
Cheers to maxisvk, that worked well.
Next, to look at a cheap quad core upgrade :D
Didée
3rd March 2008, 21:13
That script ran well and fast, constantly at 100%, ...
... and the result was 100% garbage.
source=ConvertToYV12(interlaced=true).Crop(...).Addborders(10,7,10,7)
Progressive YV12 shouldn't be cropped or add-border'ed by odd numbers vertically .
For interlaced YV12, that is MUST NOT. Never, never, never ever. If you do, you're changing chroma phase, i.e. luma and chroma are no more temporally aligned.
ChrisW77
3rd March 2008, 21:41
... and the result was 100% garbage.
Looked good enough to MY eyes ;)
Progressive YV12 shouldn't be cropped or add-border'ed by odd numbers vertically .
For interlaced YV12, that is MUST NOT. Never, never, never ever. If you do, you're changing chroma phase, i.e. luma and chroma are no more temporally aligned.
Then suggest something then, rather than just spouting off one.
How would one, by Didee's standards, crop off the shite on a Interlaced VHS cap.
I'm listening, o Great one :D
thetoof
4th March 2008, 08:10
Basic rule of MT : Look at the time it takes, not the CPU usage!
Also, I think setmtmode(2) for MVtools would be better since:
1- In the guide, there is this info: # Note: SetMTMode(2) mode of multithreaded AviSynth is also supported since MVTools v.1.8.4.1 (beta testing)
2-MT("filter()") splits the frames in multiple parts (depending on the # of threads)... and unless you use a HUGE overlap, the motion vectors won't be as accurate as if you had used the complete frame (which is done by setmtmode(2))
If you didn't know, setmtmode(2) separates the frames temporally (so it's always the complete frame that is processed), while MT() separates them spatially.
maxisvk
4th March 2008, 13:43
Basic rule of MT : Look at the time it takes, not the CPU usage!
ok, obviously, but in my test:
SetMTMode(2,0) , 50% Cpu
-> encoded 120 frames, 1.61 fps, 855.64 kb/s
SetMTMode(2,3) , 65% Cpu
-> encoded 120 frames, 1.64 fps, 855.64 kb/s
SetMTMode(2,4) , 90/100% Cpu
-> encoded 120 frames, 2.15 fps, 855.64 kb/s
i also noticed that using only Mvdegrain and not TemporalDegrain best result are stuck with SetMTMode(2,3), Why?..., I really did not know!
thetoof
4th March 2008, 22:35
Because Temporaldegrain uses a predenoised reference clip for motion vector search... so it takes more computer ressources and it's very possible your hard drive disk can't handle the high number of reads and writes. That's why there's a peak with speed. You can "solve" that by doing the reference clip yourself with FFT3Dfilter.
If you only want to denoise, use this:
1 - Create a simple script to create your reference clip, it doesn't really matter if you lose some details and it looks a tad overdenoise since it's only a clip used for motion vector search:
whateversource("yoursource")
FFT3DFilter(your favorite parameters... check the documentation for more info)
2 - Process through Direct Stream Copy in virtualdubmod. If you have another HDD, save it on this one. The file'll be HUGE.
3 - create another script with temporaldegrain using the source clip that is on the other HDD
source = whateversource("youroriginalclip")
denoised = avisource("thereferenceclip")
temporaldegrain(source, denoised)
About your speedtest... it's OBVIOUS that using more threads will increase the speed. SetMTmode(2) is always the best choice since it'll set the number of threads to the # of available processors.
When I say to look at speed instead of CPU usage, it's with the same # of CPUs. The thing is, when you have a more complex script, MT may not help (I have a script that runs @ 1fpm with 750MB of RAM and 25% CPU usage (100% of 1 processor on my Quad-core) and it's a LOT slower with MT and uses 3GB of RAM).
foxyshadis
5th March 2008, 07:32
Eh, no matter how slow a script is, writing part of it to disk and reading it back will always be slower. Whether you're going to make another lossless encode from the final output, or use it in a one-pass encoding, by the time you're done you'll have put much more effort into it and it will have taken longer overall. Memory overflow and disk swapping is about the only way that partial scripting can be faster. TemporalDegrain can't even remotely cause a hard drive bottleneck anyway, even with uncompressed sources it takes about a hundred times as long to filter as read.
On the other hand, if you have a second computer handy, running fft3dfilter on that and using TCPSource can really speed things up, as long as the second computer's fast enough to keep up.
I'd also say that your conclusion that SetMTmode(2) is best is mistaken; after all, you just said more threads was faster, and speed is all that matters, as long as the final encoder's thread is included rather than just the avisynth script measured. In some scripts 4 threads will be faster, others 1, though I suppose yours might be swapping like crazy once it gets there. Always measure though, never take a forum poster's word. :p
thetoof
5th March 2008, 08:39
Oh well, seems like I was lucky on my first try using the method I described before... I ran some other tests to show how effective it was, but everything I got looked like crap.
Dunno why it worked once (and there were actually great speed improvement by outputting the reference clip on another HDD and then call it in the script using temporalgrain as "denoise", from 53 mins total (complete script) to 13 mins total (split script) for the same amount of frames) and I'm sorry for posting it before running more tests... but heh, I'm learning!
Also, about my statement regarding setmtmode(2), I had in mind that it was regarding MVtools usage (and from what I understood from its documentation, it's the most appropriate mode). My bad for not being clear.
Eh, no matter how slow a script is, writing part of it to disk and reading it back will always be slower. Whether you're going to make another lossless encode from the final output, or use it in a one-pass encoding, by the time you're done you'll have put much more effort into it and it will have taken longer overall. Memory overflow and disk swapping is about the only way that partial scripting can be faster. TemporalDegrain can't even remotely cause a hard drive bottleneck anyway, even with uncompressed sources it takes about a hundred times as long to filter as read.
yup 1 pass encodes it would not help but 2 pass encoding is much faster when I do twriteavi() on the first pass of slow encode due to scripts like the stuff in this thread.
If you are only getting 2 FPS like me you for sure want to save out a lossless during the first pass else you are stuck doing it all again on the second pass. resize, decimation, MVtools, fft3dfilter, etc... I go from 2 FPS on the first pass to 14 FPS on the second pass and this is now with the real encoding being done also. (it would be only about .75 FPS on pass 2 if I didn't do this) huge time savings on 2 pass encodes.
no I would not do it like thetoof did it since you want the lossless (I use VBLE cause it is fast and thus little CPU overhead) made the same time as first pass stats are being made :)
g-force
7th March 2008, 07:49
TemporalDegrain looks really nice, but my PC is way to slow to run this thing practically. So I used Didee's limiting approach and wrote something that required less MV operations with very good results IMHO. Let me know what you think!
# GTemporalDegrainFaster ver.1.00 6MAR08
# Function by G-force,"Limited" Concept by Didee
# Requires FFT3DFilter.dll, mt_masktools, MVtools.dll, RemoveGrain.dll
function GTemporalDegrainFaster (clip input,int "threads",int "sigma")
{
source = input
ncpu = default(threads,1) #max number of CPU threads to use in FFT calculation (int>0, default=1)
sigma = default(sigma, 16) #turn down for more limited denoising
s2 = floor (sigma * 0.625)
s3 = floor (sigma * 0.375)
s4 = floor (sigma * 0.250)
filter = source.fft3dfilter(ncpu=ncpu,sigma=sigma,sigma2=s2,sigma3=s3,sigma4=s4,bt=5,bw=16,bh=16,ow=8,oh=8)
filterD = mt_makediff(source,filter)
backward_vec1= filter.MVAnalyse(isb=true, delta=1,pel=2,overlap=4,sharp=1,idx=1)
forward_vec1 = filter.MVAnalyse(isb=false,delta=1,pel=2,overlap=4,sharp=1,idx=1)
bw1 = source.MVCompensate(backward_vec1,idx = 2) #idx = 2 since working on a different clip than MVAnalyse
fw1 = source.MVCompensate(forward_vec1, idx = 2)
#nice thing about this approach is that it doesn't necessarily use any pixels from current frame
#this gets rid of a lot more dirt, scratches etc. (things that last only one frame)
nr = Interleave(bw1,source,fw1).Clense().SelectEvery(3,1)
# Limit "nr" to not do more than what "filter" would do. -Didee
nrD = mt_makediff(source,nr)
DD = mt_lutxy(filterD,nrD,"x 128 - abs y 128 - abs < x y ?")
source.mt_makediff(DD,U=2,V=2)
output = last
return(output)
}
-G
Didée
8th March 2008, 20:43
... and the result was 100% garbage.
Looked good enough to MY eyes ;)
I don't know your eyes, so I can't tell what seems good enough to them and what not.
With your sequence of crop+addborders, this is what happens to an interlaced YV12 source:
http://img401.imageshack.us/img401/5262/yv12iwrongua9.th.png (http://img401.imageshack.us/my.php?image=yv12iwrongua9.png)
In contrast, with correct treatment you get:
http://img401.imageshack.us/img401/967/yv12icorrectkt7.th.png (http://img401.imageshack.us/my.php?image=yv12icorrectkt7.png)
Then suggest something then, rather than just spouting off one.
How would one, by Didee's standards, crop off the shite on a Interlaced VHS cap.
I'm listening, o Great one :D
It's a basic technical requirement that the top border of interlaced YV12i may only be altered in mod4 steps.
This has nothing-at-all to do with "my standards".
-----
Generating script: (yeah, it's not elegant):p
base = blankclip(width=704,height=576,pixel_type="YV12",fps=50.000,color=$408080)
base = base.subtitle("This is some scrolling text ...",size=40,x=128,y=480)
interleave( base, base.crop(0,16*1,-0,-0).addborders(0,0,0,16*1,color=$408080),
\ base.crop(0,16*2,-0,-0).addborders(0,0,0,16*2,color=$408080),
\ base.crop(0,16*3,-0,-0).addborders(0,0,0,16*3,color=$408080),
\ base.crop(0,16*4,-0,-0).addborders(0,0,0,16*4,color=$408080),
\ base.crop(0,16*5,-0,-0).addborders(0,0,0,16*5,color=$408080),
\ base.crop(0,16*6,-0,-0).addborders(0,0,0,16*6,color=$408080),
\ base.crop(0,16*7,-0,-0).addborders(0,0,0,16*7,color=$408080),
\ base.crop(0,16*8,-0,-0).addborders(0,0,0,16*8,color=$408080),
\ base.crop(0,16*9,-0,-0).addborders(0,0,0,16*9,color=$408080),
\ base.crop(0,16*10,-0,-0).addborders(0,0,0,16*10,color=$408080),
\ base.crop(0,16*11,-0,-0).addborders(0,0,0,16*11,color=$408080),
\ base.crop(0,16*12,-0,-0).addborders(0,0,0,16*12,color=$408080),
\ base.crop(0,16*13,-0,-0).addborders(0,0,0,16*13,color=$408080),
\ base.crop(0,16*14,-0,-0).addborders(0,0,0,16*14,color=$408080),
\ base.crop(0,16*15,-0,-0).addborders(0,0,0,16*15,color=$408080) )
vid_50p = last
vid_50i = assumeTFF().SeparateFields().SelectEvery(4,0,3).Weave()
# the wrong way:
#---------------
vid_50i
crop(0,4,-0,-10)
addborders(0,7,0,7)
wrong = last
# the better way:
#---------------
vid_50i
crop(0,4,-0,-12)
addborders(0,8,0,8)
better = last
result_wrong = stackhorizontal( wrong.subtitle("interlaced after non-MOD4 cropping or addborders",y=20),
\ stackvertical( wrong.SeparateFields().selecteven().subtitle("--> top field",y=20),
\ wrong.SeparateFields().SelectOdd().Subtitle("--> bottom field",y=20) ) )
result_better = stackhorizontal( better.subtitle("interlaced after correct (MOD4) cropping or addborders",y=20),
\ stackvertical(better.SeparateFields().selecteven().subtitle("--> top field",y=20),
\ better.SeparateFields().SelectOdd().Subtitle("--> bottom field",y=20) ) )
result_wrong
#result_better
return( last )
ChrisW77
8th March 2008, 23:10
Didée, Thankyou. Great explanation. :)
You see, I'm always still learning, and I get frustrated when I can't see a solution that you see straight away. All I need is a brief explanation, and a possible script demo, and I learn from that.
Once again, thankyou.
Lorax2161
9th March 2008, 20:27
TemporalDegrain looks really nice, but my PC is way to slow to run this thing practically. So I used Didee's limiting approach and wrote something that required less MV operations with very good results IMHO. Let me know what you think!
-G
What speed improvements did you find with your version, and what processor type are you using?
TemporalDegrain is awesome, but I have to check the TV guide before I invoke it to see if there is anything else I wanted to capture in the next day or so before I begin encoding. :)
g-force
10th March 2008, 17:51
What speed improvements did you find with your version, and what processor type are you using?
I'm not sure right off hand all of the specs on the processor. It's an AMD from a few years ago. I'll take a look when I get home from work.
What I do know is that when I would call TemporalDegrain, it would take about 30sec to generate a frame, whereas mine took maybe a few seconds. In retrospect, I've found it to blur fast motion stuff a bit too much for what I intended to use it for, but I'm still trying to run with the idea of using the median aspects of Clense with mo-comp'd frames.
-G
Nikos
22nd April 2008, 00:55
I think that there is a mistake in Didée's post #33.
o = last
f = o.MinBlur(1,2).MinBlur(2,2).RemoveGrain(11,-1)
f.FluxSmoothT(7).mt_AddDiff(mt_MakeDiff(o,f,U=1,V=1),U=4,V=4)
# eventually, limit the maximum pixel change to +/- 2 :
mt_LutXY(last,o,"x 2 + y < x 2 + x 2 - y > x 2 - x ? ?",U=2,V=2)
For example, if pixel value o = 100 and pixel value last = 93 then the output pixel value = 95.
That is pixel change = 5
In my opinion the right syntax is:
o = last
f = o.MinBlur(1,2).MinBlur(2,2).RemoveGrain(11,-1)
f.FluxSmoothT(7).mt_AddDiff(mt_MakeDiff(o,f,U=1,V=1),U=4,V=4)
# eventually, limit the maximum pixel change to +/- 2 :
mt_LutXY(o,last,"x 2 + y < x 2 + x 2 - y > x 2 - y ? ?",U=2,V=2)
But, may be i am wrong :)
Didée
22nd April 2008, 13:06
@Nikos: Exactly like you said, that LUT expression was wrong. Well spotted, thanks for noting!
Also, there's something strange with
>> mt_AddDiff(mt_MakeDiff(o,f,U=1,V=1),U=4,V=4)
UV=4 means copy chroma from 2nd clip argument. The 2nd clip argument is mt_MakeDiff(o,f,U=1,V=1), which has chroma in an undefined state.
Funny that this seems to output correct chroma nonetheless ...
LUT and chroma issues are in the script of post#33 are fixed now.
Nikos
22nd April 2008, 15:13
Thanks Didée for the correction and for all your work.
From my tests on a very problematic HD movie the results from the script was great. The dirty dancing effect reduced with almost no smoothing.
I had tried many other filters without success.
Now the usual questions :)
1. In masktools Round(1.5)=2 or 1.
2. Why in mt_makediff with identical clips, the difference is 128 and not 0 like maths. In general i don't understand well the meaning of 128 :)
3. It's a good idea to use the motion compensate ML3DexGPU for prefiltering in my MC-denoise scripts?
I tried your script with the ML3DexGPU and the result happens to be sufficient and pleasant. This prefilter combo is able to cut down the dirty dancing noise almost completely with minimal blurriness.
Thanks again!!!
Didée
23rd April 2008, 13:14
1. It should follow the usual convention for rounding, .5 is rounded upwards. (It appears to be so ... but don't nail me on that it does so in each possible case. I'm not the coder of MaskTools.)
2. A pixel can't have a negative value, only 0-255. In order to handle "negative" differences, the range -127..0..127 is offsetted to 0..128..255.
3. You tell, I don't know. The exact operation of ML3Dex isn't fully clear to me (have been a bit lazy when looking through that pdf) ... however in practice, it doesn't impress me too much. The temporal artefacts in motion areas (resp. areas with erroneous motion compensation) are pretty much the same as those of plain temporal median, so there's no benefit in that respect. In areas without motion (resp. in areas with correct motion compensation), it does remove a bit more signal spikes, no matter whether it's noise or detail.
Thus, for me ML3Dex isn't a interesting option. And ML3DexGPU isn't because I don't have GPU acceleration.
If it works sufficient for you, then you answered your own question. :)
Nikos
23rd April 2008, 16:09
2. A pixel can't have a negative value, only 0-255. In order to handle "negative" differences, the range -127..0..127 is offsetted to 0..128..255
If pixels differences are above +/- 127 (very rare case), then what's happen?
I suppose that clip them to +/- 127.
Thanks again!!!
yup
30th April 2008, 08:21
Hi folks!
Simple idea. I very frequently use MVDegrain3 for denoising VHS cassette capture. I use big thSAD 800 for luma and 1200 for chroma for many parts video this work very good, but for frame with big scan I see ghosting, may be will be useful use mask with motion estimation (vector length). Separate all frame to three types slow motion, medium motion and fast motion (depending from value motion vector) and use three MVDegrain3 and after use mask.
yup.
Snake91
11th October 2009, 08:46
Hi to all, I'm encoding Matrix Revolutions from my HDDVD and i wanted to clean the flickering on the background (minimizing detail loss) that's sometimes there fro compressibility purpose. I've checked the first pages of the thread and tried this (http://forum.doom9.org/showthread.php?p=1073349#post1073349) script from Didée. The script doesn't give me any error nor when I load it nor when I'm encoding but the results are very strange with some frames getting more accelerated than the others.
Samples
http://www.megaupload.com/?d=J6ISVCM3 - Encoded
http://www.megaupload.com/?d=VAOBD7FL - Source
Watch the logo, this effect is repeated across all the movie making it unwatchable. If I use only dss and crop the video is perfect, how can I solve???
Didée
11th October 2009, 16:00
If I use only dss and crop the video is perfect, how can I solve???
(Frankly, I did not look at your files.)
Do not use DSS.
DSS is not frame accurate on seeking. With a script that's so ressource hungry as the one you're referring to, it is very likely that frames will be requested out-of-(linear)-order, and that's where DSS may and will cause problems.
Also, I don't know the HD version of that movie, only the SD one ... and that one is not extraordinarily noisy. I'd suspect that you don't need such a complex denoising strategy for this movie, and that a simple MDegrain2|3 should be sufficient.
(In particular, it's the act of MDegraining an already-MDegrain'ed clip that is eating ressources for breakfast. Such should not be done when poking in the blue, but only on well-aimed intention.)
Snake91
11th October 2009, 20:30
Do not use DSS.
DSS is not frame accurate on seeking. With a script that's so ressource hungry as the one you're referring to, it is very likely that frames will be requested out-of-(linear)-order, and that's where DSS may and will cause problems.
I've tried DSS2 (which has frame-accuracy) and it worked:eek:
Thanks a lot!!!
Also, I don't know the HD version of that movie, only the SD one ... and that one is not extraordinarily noisy. I'd suspect that you don't need such a complex denoising strategy for this movie, and that a simple MDegrain2|3 should be sufficient.
(In particular, it's the act of MDegraining an already-MDegrain'ed clip that is eating ressources for breakfast. Such should not be done when poking in the blue, but only on well-aimed intention.)Thanks for the suggestion, I will compare both and pick the best
tormento
26th June 2010, 18:45
Something to try: the following script will remove the low-frequency flicker, leaving the high-frequencies intact.
Would you accept the trial to write something that is available in avisynth x64 domain? :devil:
Didée
26th June 2010, 21:38
That script is based on FluxSmooth and MedianBlur. Unfortunately, neither of them has been ported to x64 yet.
It would be possible to construct something similar. MedianBlur can be done via mt_luts(). FluxSmooth could be approximated with a combination of Clense and TemporalSoften. But no, seems that Clense is not included in the current compilation of RemoveGrain_x64. (Not Joshy's compilation. And kassandro's 64bit compilation is said to not work at all)(?) - So it would need to be built by a 3-fold mt_logic() combination.
Workarounds for workarounds for workarounds. The result would probably run 5 to 10 times slower than the 32bit script. That's not really worth the effort.
Much better choice:
- Instead of challenging me to script that, challenge the plugin guys to port FluxSmooth and MedianBlur to 64bit. Possibly also Clense.
- For bonus points, someone write a plain Temporal-Median Filter that is actually usable. (MedianBlurT is not, if radius>2.)
tormento
26th June 2010, 23:22
Didée you are right and I apologise for threatening your patience ;) My disappoint comes from the impossibility to run MCTD in x64. After some frames in MT it just plain crashes.
I have some very difficulties to encode BD (Save private Ryan to tell one) and using higher CRF to fit a DVD9 is not an option as quality would suffer too much.
I am currently trying TemporalDegrain or MC Degrain3, however believe me or not the result are always over 10 GB. MCTD_x64 could be a solution. It's a pity it does not exist =)
SilaSurfer
13th January 2011, 15:56
Didée thank you for the script.
Really calms down that "naasty dance effect of grain". I was wondering could that script be modified to have stronger effect? In some of my Dvd sources it doesn't calm down grain fully, and Mdegrain after isn't really effective and produces smearing in those areas where that dancing effect is stronger mostly in the CGI elements of some movies that I tried on. Thanks
Didée
13th January 2011, 16:36
This thread has 16 pages, 300+ posts, and quite a few scrpts have been posted. Which script exactly are you speaking of?
If it's the initial denoising script I had posted - meanwhile converted to "TemporalDegrain" by Sagekilla - that one is basically performing source.MDegrain3().MDegrain3() ...
... so yes, you are right: using MDegrain after that isn't really effective. Why should it, after all. :D
But maybe we're talking past each other. Please specify.
tormento
14th January 2011, 08:13
This thread has 16 pages, 300+ posts, and quite a few scrpts have been posted. Which script exactly are you speaking of?
The one you will write for us using the *very fast* NLMeansCL filter ;)
SilaSurfer
14th January 2011, 13:30
This thread has 16 pages, 300+ posts, and quite a few scrpts have been posted.
Yes I know, took me some time to read it and a lot of coffee.:p
If it's the initial denoising script I had posted - meanwhile converted to "TemporalDegrain" by Sagekilla
Thats one of the best scripts in my opinion using Mdegrain denoising with a prefilter analysis clip. Used copy/paste on it straight to my hard drive so I can modify it for my own usage. :p But nope not this one.
... so yes, you are right: using MDegrain after that isn't really effective. Why should it, after all. :D
Why would I do that?:D Using Mdegrain1/2/3 on top already two instances of Mdegrain3. I was referring to how LF errors aka dancing effect can disturb ME engine using Mdegrain if it is not removed before so not only that efficiency od denoising is reduced but also smearing becomes present in those areas where that effect is present.
Which script exactly are you speaking of?
This one
o = last
f = o.MinBlur(1,2).MinBlur(2,2).RemoveGrain(11,-1)
f.FluxSmoothT(7).mt_AddDiff(mt_MakeDiff(o,f,U=2,V=2),U=4,V=4)
# eventually, limit the maximum pixel change to +/- 2 :
# mt_LutXY(o,last,"x 2 + y < x 2 + x 2 - y > x 2 - y ? ?",U=2,V=2)
# to compare:
stackvertical(o,last)
#interleave(o,last)
return(last)
To modify it to have more stronger effect or am I mixing apples with oranges? :p
Thank you
Didée
14th January 2011, 14:08
The Question is - what are the apples, and what are the oranges? :)
In which way should it be stronger? Is it that FluxSmooth isn't strong enough (is there still residual flicker of low spatial frequencies)? Or is it that too much grain is in the output? If it's the latter - the whole purpose of this script is to not touch grain at all, and to calm down only the low spatial frequencies.
SilaSurfer
16th January 2011, 16:48
The Question is - what are the apples, and what are the oranges? :)
It's a form of expression. :p
In which way should it be stronger? Is it that FluxSmooth isn't strong enough (is there still residual flicker of low spatial frequencies)? Or is it that too much grain is in the output? If it's the latter - the whole purpose of this script is to not touch grain at all, and to calm down only the low spatial frequencies.
I'm fully aware this script is meant for removing LF flicker effect and not grain. ;) So Fluxsmooth should be tweaked to get stronger effect if so are those sideaffects of shading going to be more amplified if I do so? Thank you for your patience. :)
Didée
16th January 2011, 17:28
So Fluxsmooth should be tweaked to get stronger effect
Maybe yes, maybe no. Read on.
if so are those sideaffects of shading going to be more amplified if I do so?
Definetly yes. If FluxSmooth is set up more aggressively (i.e. bigger threshold), then it'll do more good where Flux is doing right, and will do more bad where Flux is doing wrong.
Remember FluxSmooth is a simple temporal smoother with median-like decision where to filter and where not.
Examples:
a) a pixel sequence: ... 80 81 85 79 80 ...
Flux will filter the "85" and the "79", because these two pixels are overshooting both of their neighbors.
b) pixel sequence: ... 80 81 85 85 81 80
Flux will filter *nothing*, because no pixel satisfies the "overshooting both neighbors" criteria.
For case b), this means:
- IF those two "85" are due to motion, then Flux has done correct.
- But IF those two "85" in fact are related to "flicker" in a "flat" a/o "static" area, then Flux has not filtered something that you would like to have filtered.
Truth is, this kind of "flickering of low spatial frequencies" is one of the ultimate foes, because right here it is where the nebula-of-uncertainty becomes thick:
a) without mocomp, you can't know if it's flicker or motion
b) with mocomp, you can't know if the mocomp has been misleaded by the flicker
c) With prefiltering before mosearch, you can't know if the prefilter has mangled moving areas (because of a)) and conseqquentially has misleaded the mosearch
Chicken-and-egg problem, without any definite solution.
SilaSurfer
16th January 2011, 17:45
Flickering. :devil: Thank you Didée for your explenation. I'm goint to go in a way of using your original script which was used with Zep's source by modifying it for my needs. Testing, testing and more testing.:p
Didée
16th January 2011, 18:25
Related - I've though several times if and how the "FluxSmooth principle" could be extended from the current 3-frame temporal window to a 5-frame temporal window.
A reasonable approach would be this:
- calculate temporal median with radius=2
- calculate temporal soften with radius=2
- for each pixel, use that result that caused the smaller difference
Radius=2 temporal median can be done via MedianBlurT, but this implementation is tooooo slow.
Instead, get the nice median2 script by g-force (http://forum.doom9.org/showthread.php?p=1169990#post1169990)!
For convenience and simple usage, create a "TMedian2" wrapper function:
function TMedian2(clip c) {
Median2( c.selectevery(1,-2), c.selectevery(1,-1), c, c.selectevery(1,1), c.selectevery(1,2) ) }
Armed with these helpers, a 5-frame-variant of FluxSmoothT could look like this:
function Flux5framesT(clip c, int "th", int "thC") {
th = default(th,7)
thC = default(thC,th)
med = c.TMedian2()
avg = c.temporalsoften(2,th,thC,24,2)
medD = mt_makediff(c,med,U=3,V=3)
avgD = mt_makediff(c,avg,U=3,V=3)
DD = mt_lutxy(medD,avgD,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=3,V=3)
c.mt_makediff(DD,U=3,V=3)
}
tormento
17th January 2011, 19:24
Please port that AVS to x64 aware version ;)
Didée
17th January 2011, 19:47
No, I'm bored of it. Wait for the x256-version of Avisynth 7.0.
SilaSurfer
19th January 2011, 13:20
Armed with these helpers, a 5-frame-variant of FluxSmoothT could look like this:
function Flux5framesT(clip c, int "th", int "thC") {
th = default(th,7)
thC = default(thC,th)
med = c.TMedian2()
avg = c.temporalsoften(2,th,thC,24,2)
medD = mt_makediff(c,med,U=3,V=3)
avgD = mt_makedif(c,avg,U=3,V=3)
DD = mt_lutxy(medD,avgD,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=3,V=3)
c.mt_makediff(DD,U=3,V=3)
}
Didée I now you get this a lot but you are a genius.:eek:;) Tried the script on the same source and the result is fantastic. Really calms down grain when LF flicker is removed. Now I can use this filtering on a clip for ME analysis. I only have to tweak th setting, right? Thanks again.
Didée
19th January 2011, 14:01
For this one, 'th' and 'thC' are the only knobs to tweak, yes.
Somewhere earlier in this thread I had posted a pre-calm script (with MinBlur() and FluxSmooth) - in essence the same as I suggested at the end of this post (http://forum.doom9.org/showthread.php?p=1471926#post1471926) to TheProfileth.
Depending on the source characteristics, using Flux5 instead of simple Flux within such a pre-calmer can make sense.
SilaSurfer
19th January 2011, 14:17
Another one for the recipe book. Those sideaffect of shading do not happen with Flux5fremesT script? Thanks Didée.
BTW There is a typo in your Flux5framesT script
avgD = mt_makedif(c,avg,U=3,V=3) --> avgD = mt_makediff(c,avg,U=3,V=3);)
Didée
19th January 2011, 14:46
Yeah, a few minutes ago I discovered that typo, too.
Of course, Flux5 is *not* safe in regards to weak shadings in moving areas. Vanilla Flux is not safe, and Flux5 is even less. Well, you can't expect anything else from a simple, thresholded temporal smoother. It's a compromise the user needs to balance out.
SilaSurfer
19th January 2011, 15:03
Thanks again Didée for your patience and interest for helping out.
SilaSurfer
23rd January 2011, 17:37
Didée from your post #70
The biggest difference to Zep's denoising is - most probably, since we didn't see his script up to now - the usage of fft3dfilter. It seems that he used to much of it, or at to strong settings. All the ringing and texture echoing is a typical side-effect fft3dfilter, when not used with enough caution. Judging from the overall look, I'd guess that Zep first did an initial filtering with fft3dfilter, and then continued to further process the result with MV-denoising. (Some places look like fft3d-banding that has been temporally averaged, but it's hard to judge after x264-compression.)
In comparison, my script never applies fft3dfilter in the chain that produces the output clip. Instead, it is only used as a "brake" to keep the 1st temporal filter within reasonable bounds. (Which is essential in the bigger scripts where the 1st stage is done with median filtering.)
Does this mean that whatever is used in prefiltering step in this case Fft3dfilter, is like you never used it, but still got results from it? If so for example I could apply two stages of Flux5FramesT for prefiltering to MDegrain2?
Flux5FramesT().Flux5FramesT() to really make the clip calm.
SilaSurfer
24th January 2011, 21:42
Didée nevermind my previous post. I wanted to ask you what do you think about this. Would need some suggestions if you have any.;):D
SetMTMode(5,2)
SetMemoryMax(1000)
MPEG2Source("C:\System\fotr1.d2v", info=3)
Colormatrix(hints=true)
crop(8,78,704,420)
source=last
a=source.Fft3dgpu(sigma=16, sigma2=10, Sigma3=6, sigma4=8, bt=4) # Deblocking and some sigma4 help to Flux5framesT() which comes next
b = a.RemoveGrain(11)
f = b.Flux5FramesT().merge(b,0.49)
Nr1=a.mt_makediff(mt_makediff(b,f,U=3,V=3),U=3,V=3) # Prefiltering clip for MAnalyze
SetMTMode(2)
NR1_super=NR1.Msuper(pel=2, sharp=2)
source_super = source.MSuper(pel=2,sharp=2, levels=1)
bv2=MAnalyse(NR1_super,isb=true, delta=2, overlap=4, truemotion=false)
bv1=MAnalyse(NR1_super,isb=true, delta=1, overlap=4, truemotion=false)
fv1=MAnalyse(NR1_super,isb=false,delta=1, overlap=4, truemotion=false)
fv2=MAnalyse(NR1_super,isb=false,delta=2, overlap=4, truemotion=false)
NR2=source.MDegrain2(source_super, bv1,fv1,bv2,fv2, thsad=300, thscd1=300, thscd2=90).contra(source) # Denoising and Your Contrasharpening. Function (see below)
SetMTmode(5)
sharp0 = NR2.Seesaw(nrlimit=0, nrlimit2=99, bias=49, sstr=1.24, Spower=3, Szp=12, Sdamplo=4, SdampHi=19, Slimit=99, sootheT=0, sootheS=0)
SetMTMode(2)
sharpD = mt_makediff(NR2,sharp0)
zeroD = sharpD.mt_lut("x",Y=-128)
sup1 = NR2.MSuper(pel=2,sharp=2)
sup2 = sharpD.MSuper(pel=2,sharp=2,levels=1)
zeroD.MDegrain2(sup2,bv1,fv1,bv2,fv2) # Motion Compensated Sharpening. Your 2a variant which doesn't denoise. I split the denoising and sharpening to avoid artefacts.
NR2.mt_makediff(last,U=2,V=2)
GradFun2DBmod(thr=1.4, str=1.2, mode=2,adapt=64, temp=50) #Some dihtering and adding grain to prevent blocking and banding
SetMTMode(5)
Spline64resize(704,288)
function contra (clip denoised, clip original)
{
s = denoised.minblur(1,1) # Damp down remaining spots of the denoised clip.
allD = mt_makediff(original,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 )
}
This was tested on not so good Dvd source. It contains a lot of dark areas where blocking is present. Areas with grain inherit those nice charming LF errors aka Flicker. So what do you think of my first "cough" advanced script? (Also having a flu overhere):p
Didée
24th January 2011, 22:09
Well, what to say. Technically, the flow of processing is all valid. On some sources this will look great, on some sources it will look desastrous. :)
Seeing the source is LOTR, I'd say the prefiltering is MUCH too strong. LOTR is rather clean with only little noise, no need to break a fly on a wheel. The current prefiltering will nuke-out enough content to make the motionsearch worse than it could be. Sometimes less is simply more.
Also, you're producing a little stamp of 704x288. So much filtering for only so few pixels in the result? :D
SilaSurfer
24th January 2011, 22:17
True. Lord of the Rings: Fellowship of the ring SEE first part. Yeah Fft3dgpu is really on steroids. Will try it with lowered settings. Thanks
SilaSurfer
25th January 2011, 14:55
Yeah that is too much filtering. I lowered Fft3dgpu to sigma=2, bt=1, used Mdegrain1 instead of Mdegrain2, and for sharpening with SeeSaw I used SootheS=25. What is the max value for FluxsmoothT(Temporal)?
Didée
25th January 2011, 15:49
Maximum is 255. Perhaps more, but in 8-bit-sources pixel differences can not be larger than 255, anyway.
Of course, with such big threshold there will appear motion artifacts.
Out of the sleeve,
MinBlur(1)
FluxSmoothT().merge(last,0.251)
sbr()
should be a "simple" but effective searchclip-pre-processing for such rather clean sources.
If you don't have them in the toolbox - - -
# Highpass of spatial r=1 Gaussian
function sbr(clip c)
{
rg11=c.removegrain(11,-1)
rg11D=mt_makediff(c,rg11)
rg11DD=mt_makediff(rg11D,rg11D.removegrain(11,-1)).mt_lutxy(rg11D,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?")
c.mt_makediff(rg11DD,U=2,V=2)
}
# Nifty Gauss/Median combination
function MinBlur(clip clp, int r, int "uv")
{
uv = default(uv,3)
uv2 = (uv==2) ? 1 : uv
rg4 = (uv==3) ? 4 : -1
rg11 = (uv==3) ? 11 : -1
rg20 = (uv==3) ? 20 : -1
medf = (uv==3) ? 1 : -333
RG11D = (r==1) ? mt_makediff(clp,clp.removegrain(11,rg11),U=uv2,V=uv2)
\ : (r==2) ? mt_makediff(clp,clp.removegrain(11,rg11).removegrain(20,rg20),U=uv2,V=uv2)
\ : mt_makediff(clp,clp.removegrain(11,rg11).removegrain(20,rg20).removegrain(20,rg20),U=uv2,V=uv2)
RG4D = (r==1) ? mt_makediff(clp,clp.removegrain(4,rg4),U=uv2,V=uv2)
\ : (r==2) ? mt_makediff(clp,clp.medianblur(2,2*medf,2*medf),U=uv2,V=uv2)
\ : mt_makediff(clp,clp.medianblur(3,3*medf,3*medf),U=uv2,V=uv2)
DD = mt_lutxy(RG11D,RG4D,"x 128 - y 128 - * 0 < 128 x 128 - abs y 128 - abs < x y ? ?",U=uv2,V=uv2)
clp.mt_makediff(DD,U=uv,V=uv)
return(last)
}
SilaSurfer
25th January 2011, 20:15
I meant SootheS=75. How come every time I ask you something you hit me with another function?:D;) Thanks Didée I like it a lot!
BTW this doesn't really belong in this thread but since it is connected to my script: MY script crawls on my system even with SetMTMode it doesn't get any faster and I was meaning to ask you what do you think about MVToolsMulti version which has multithreading built in. I know it is somewhat unstable but I could gain a couple fps?
Boulder
26th January 2011, 19:56
Maximum is 255. Perhaps more, but in 8-bit-sources pixel differences can not be larger than 255, anyway.
Of course, with such big threshold there will appear motion artifacts.
Out of the sleeve,
MinBlur(1)
FluxSmoothT().merge(last,0.251)
sbr()
should be a "simple" but effective searchclip-pre-processing for such rather clean sources.It seems to blur the image quite a bit even with clean sources. Is that intentional?
Didée
26th January 2011, 20:25
Yes, sure, that's intentional. Preprocessing for the searchclip. Did you see that? ;)
If you have a nicely sharp & high-contrast clip, with "default operation as per documentation" you'll end up with pretty big SADs wherever there's an edge. Means, little to nothing will happen on edges. Which is quite counterproductive when the goal is to calm (the effect of) a sharpener.
Boulder
26th January 2011, 20:42
Yes, sure, that's intentional. Preprocessing for the searchclip. Did you see that? ;)Of course :) I was just wondering that it was meant for clean sources but your further explanation makes the idea clearer. Probably the function would work just nicely on lower quality sources as well as it at least kills the excess noise and blocks.
SilaSurfer
26th January 2011, 21:19
Yeah it's great for ME, just tried it. Works better then Fft3dgpu at least for me. :)
cobo
26th January 2011, 23:12
MinBlur(1)
FluxSmoothT().merge(last,0.251)
sbr()
Last is meant to be merged with itself here, or am I misunderstanding?
Didée
26th January 2011, 23:19
MinBlur(1)
FluxSmoothT().merge(last,0.251)
sbr()
or, of you prefer, the same with explicit naming:
spatial = MinBlur(1)
temporal = spatial.FluxsmoothT()
mixed = temporal.merge(spatial,0.251)
mixed.sbr()
davsim
6th April 2011, 18:09
Thanks to Didée and Sagekilla for all your efforts.
I've just been reading through old threads to catch up on degraining/denoising. I came across the old sample clip Babylon5_snip.m2v and tried quite a few different scripts, until getting this very nice result with Temporal Degrain:
source:
http://i.imgur.com/Vq8r9s.png (http://i.imgur.com/Vq8r9.png)
TemporalDegrain(degrain=2, SAD1=300, SAD2=200, ov=4, blksize=8) :
(also re-encoded as x264)
http://i.imgur.com/YRxZSs.jpg (http://i.imgur.com/YRxZS.png)
vBulletin® v3.8.5, Copyright ©2000-2012, Jelsoft Enterprises Ltd.