Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
|
|
Thread Tools | Search this Thread | Display Modes |
|
22nd March 2008, 21:09 | #1 | Link |
Huh?
Join Date: Sep 2003
Location: Uruguay
Posts: 3,103
|
Alternatives to FFT3DFilter for luma denoising on pictures?
As amazing as FFT3DFilter is for chroma denoising on pictures, I find the luma denoising to be lacking as it seems to cause artifacting. Can you recommend me something that works as nicely on luma only?
__________________
Read Decomb's readmes and tutorials, the IVTC tutorial and the capture guide in order to learn about combing and how to deal with it. |
22nd March 2008, 21:40 | #2 | Link |
Registered User
Join Date: Jul 2005
Posts: 438
|
I don't know, if this denoises only luma, but I have made very good experience with "Temporal Degrain" (http://avisynth.org/mediawiki/Temporal_Degrain). It gave me very pleasing results on semi-noisy sources. So give it a try, if you like.
|
23rd March 2008, 17:33 | #5 | Link |
Huh?
Join Date: Sep 2003
Location: Uruguay
Posts: 3,103
|
It works better than FFT3DFilter, but not by that much. Noise Ninja still does better in that regard.
__________________
Read Decomb's readmes and tutorials, the IVTC tutorial and the capture guide in order to learn about combing and how to deal with it. |
3rd April 2008, 21:39 | #8 | Link |
Sleepy overworked fellow
Join Date: Feb 2008
Location: Maple syrup's homeland
Posts: 933
|
1 - Open several Virtualdubmod windows (I use about 10)
2 - Load your video with Code:
FFT3DFilter(sigma=40, plane=3, bw=32, bh=32, bt=5, ow=16, oh=16) FFT3DFilter(sigma2=0, sigma3=50, sigma4=50, plane=0, bw=32, bh=32, bt=5, ow=16, oh=16) 3 - Create multiple scripts with different values of sigma2 (1,2,3,4,5,etc.) 4 - Choose 3 frames to ensure that the settings you use are good for all your video: Very high (and I mean VERY HIGH) motion/a lot of small detail/still with nice gradients 5 - Compare and choose the one that has absolutely no noise. 6 - Repeat for sigma3 and 4, in that order. When you check for sigma3, use the sigma2 value you found earlier and when you check sigma4, use the values of sigma2/3 you found earlier. Be careful about: - Overdenoising sigma3/4... it'll completely screw up your gradients and you'll have ugly stripes of color instead. Values too high by 2-4 for sigma2 are no big deal (it's better if you can find the most appropriate, but it won't be as bad as too high 3/4) - Using some values you're not sure about (you may need a bit of practice in order to see what the best value for your source is, so if it's too hard with FFT3D alone, use the same method but with TemporalDegrain (that way you'll see the final effect of your denoising) If it's still to hard to find the good values, you can add a very strong sharpener right after denoising, so if you left some noise, it'll be enhanced and you'll know that you still have to tweak your filters... but that's a "last resort" option imo. As a reference, my reference clip for the source I posted looks like this. For the gradients, this is the frame I chose for my source. (light brown to dark brown on the wall) Original/Denoised |
5th April 2008, 20:33 | #12 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,391
|
Is your mod based on the Temporaldegrain script that's linked in the Avisynth Wiki? I just noted that that script is broken ... not that it caused artifacts, but it gives only ~50% denoising efficiency, since the 2nd MVDegrain uses wrong idx. That's not what I showed in the original script ...
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) |
5th April 2008, 20:57 | #13 | Link |
Sleepy overworked fellow
Join Date: Feb 2008
Location: Maple syrup's homeland
Posts: 933
|
This is my mod... the idx changes at every step, so I guess it's the good version.
Code:
############################################################################# # Temporal Degrain V1.18b (April 5th, 2008) # # Function by Sagekilla, original script created by Didée, mod by thetoof # # # # Works as a simple temporal degraining function that'll remove MOST grain # # from video sources, including dancing grain, like the grain found on 300. # # Is currently capable of utilizing MVDegrain 1, 2, or 3 for degraining # # Also note, the parameters don't need to be tweaked much. # # # # Required plugins: FFT3DFilter.dll / mt_masktools / MVtools.dll # # HQdn3D.dll / RemoveGrain.dll / Repair.dll # # # # FFT3DFilter: http://bag.hotmail.ru/fft3dfilter/fft3dfilter.dhtml # # mt_masktools: http://manao4.free.fr/mt_masktools.html # # MVtools: http://avisynth.org.ru/mvtools/mvtools.html # # RemoveGrain: http://www.removegrain.de.tf/ # # Repair: See above # # HQdn3D: http://akuvian.org/src/avisynth/hqdn3d/ # ############################################################################# ######################################################## # Description of functions # # denoise = Denoised clip for detecting motion vectors # # pel = MVAnalyse Subpixel accuracy # # blksize = MVAnalyse block size # # ov = MVAnalyse block overlap # # search = MVAnalyse search effort # # dct = use of DCT for motion vector calculation # # SAD1 = MVDegrain thSAD # # SAD2 = MVDegrain thSAD # # degrain = MVDegrain with 1, 2, or 3 vectors # # HQ = Additional filtering after MVDegrain # ######################################################## function TemporalDegrain ( clip input, clip "denoise", int "pel", int "blksize", int "ov", int "degrain", int "limit", int "SAD1", int "SAD2", int "HQ", int "search", int "dct" ) { o = input pel = default( pel, 2 ) # Higher values increase motion vector quality at the cost of speed blksize = default( blksize, 8 ) # Higher values are faster, less accurate, and degrain less ov = default( ov, 4 ) # Increase for better motion vectors but slower speed degrain = default( degrain, 3 ) # MVDegrain 1, 2 or 3 limit = default( limit, 255 ) # Limits maximum change of a pixel. Default means no limit SAD1 = default( SAD1, 400 ) # Threshold for degraining. Decrease if you suffer from ghosting SAD2 = default( SAD2, 300 ) # See above HQ = default( HQ, 0 ) # Additional filtering after MVDegrain search = default( search, 2 ) # MVAnalyse search effort dct = default( dct, 0 ) # Use of DCT for motion vector calculation # "srch" is a prefiltered clip on which the motion search is done. srch = denoise # "spat" is a prefiltered clip which is used to limit the effect of the 1st MV-denoise stage. spat = denoise spatD = mt_makediff(o,spat) # Motion vector search (With very basic parameters. Add your own parameters as needed.) b3vec = (degrain==3) ? \ srch.MVAnalyse(isb=true, delta=3, pel=pel, overlap=ov, idx=1, blksize=blksize, dct=dct, search=search) : BlankClip b2vec = (degrain>=2) ? \ srch.MVAnalyse(isb=true, delta=2, pel=pel, overlap=ov, idx=1, blksize=blksize, dct=dct, search=search) : BlankClip b1vec = srch.MVAnalyse(isb=true, delta=1, pel=pel, overlap=ov, idx=1, blksize=blksize, dct=dct, search=search) f1vec = srch.MVAnalyse(isb=false, delta=1, pel=pel, overlap=ov, idx=1, blksize=blksize, dct=dct, search=search) f2vec = (degrain>=2) ? \ srch.MVAnalyse(isb=false, delta=2, pel=pel, overlap=ov, idx=1, blksize=blksize, dct=dct, search=search) : BlankClip f3vec = (degrain==3) ? \ srch.MVAnalyse(isb=false, delta=3, pel=pel, overlap=ov, idx=1, blksize=blksize, dct=dct, search=search) : BlankClip # First MV-denoising stage. Usually here's some temporal-medianfiltering going on. # For simplicity, we just use MVDegrain. NR1 = (degrain==3) ? o.MVDegrain3(b1vec,f1vec,b2vec,f2vec,b3vec,f3vec,thSAD=SAD1,idx=2,limit=limit) : \ (degrain==2) ? o.MVDegrain2(b1vec,f1vec,b2vec,f2vec,thSAD=SAD1,idx=2,limit=limit) : \ o.MVDegrain1(b1vec,f1vec,thSAD=SAD1,idx=2,limit=limit) NR1D = mt_makediff(o,NR1) # Limit NR1 to not do more than what "spat" would do. DD = mt_lutxy(spatD,NR1D,"x 128 - abs y 128 - abs < x y ?") NR1x = o.mt_makediff(DD,U=2,V=2) # Second MV-denoising stage. We use MVDegrain2. NR2 = (degrain==3) ? NR1x.MVDegrain3(b1vec,f1vec,b2vec,f2vec,b3vec,f3vec,thSAD=SAD2,idx=3,limit=limit) : \ (degrain==2) ? NR1x.MVDegrain2(b1vec,f1vec,b2vec,f2vec,thSAD=SAD1,idx=3,limit=limit) : \ NR1x.MVDegrain1(b1vec,f1vec,thSAD=SAD1,idx=3,limit=limit) NR2 = (HQ==1) ? NR2.HQDn3D(1,1,4,1) : NR2 # Temporal filter to remove last bits of dancing pixels NR2 = (HQ>=1) ? NR2.HQDn3D(2,1,6,1) : NR2 # A stronger version if the default isn't strong enough. # Contra-sharpening: sharpen the denoised clip, but don't add more than what was removed previously. # Here: A simple area-based version with relaxed restriction. The full version is more complicated. s = NR2.minblur(1,1) # Damp down remaining spots of the denoised clip. allD = mt_makediff(o,NR2) # 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. NR2.mt_adddiff(ssDD,U=2,V=2) # Apply the limited difference. (Sharpening is just inverse blurring.) output = last return(output) } # From Didee's MCBob script 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 : -200 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) } Last edited by thetoof; 5th April 2008 at 21:13. |
5th April 2008, 21:28 | #14 | Link |
Registered User
Join Date: Apr 2002
Location: Germany
Posts: 5,391
|
Yes, that one seems okay.
My concern is just that by now, there are malformed versions out there in the wild, and who knows since how long back ... without a central home for such scripts, that's a problem. Edit: uploaded fixed versions of TemporalDegrain and TemporalDegrain_beta to the Wiki.
__________________
- We´re at the beginning of the end of mankind´s childhood - My little flickr gallery. (Yes indeed, I do have hobbies other than digital video!) Last edited by Didée; 5th April 2008 at 22:37. |
5th April 2008, 21:57 | #15 | Link |
Sleepy overworked fellow
Join Date: Feb 2008
Location: Maple syrup's homeland
Posts: 933
|
Yeah, it'd be nice to have such a place, but I think the wiki does the job... my only question is how the hell did that bad version got there??
Maybe the problem lies in how the scripts are chosen when it's time to put them in the wiki (dunno... there could be some "original author approval" or something like that), but heh, getting off topic. |
7th April 2008, 09:53 | #16 | Link |
Registered User
Join Date: Apr 2005
Posts: 213
|
Let’s do some examples. Here are my attempts with FFT3DFilter, TNLMeans and dfttest.
Original >> FFT3DFilter >> Code:
# FFT3DFilter sigma_y = 8.0 sigma_uv = 14.0 bw = 16 bh = 16 Code:
# TNLMeans (luma denoising) Ax = 8 Ay = 8 Sx = 16 Sy = 16 Bx = 1 By = 1 a = 1.0 h = 8 sse = true # FFT3DFilter (chroma denoising) sigma_uv = 14.0 bw = 16 bh = 16 Code:
# dfttest sigma_y = 3.9 sigma_uv = 3.9 sbsize = 12 smode = 1 sosize = 9 swin = 0 sbeta = 2.5 Last edited by Archimedes; 11th April 2008 at 10:34. |
|
|