I want to degrain/denoise a 1080p anime ripped straight from the Blu-ray. I'm not too skilled with scripting, so I use Handbrake or Hybrid. I can kind of use scripts in ffmpeg and VirtualDub.
My issue is that most methods I try end up leaving grain in the first few frames when scenes change, so there's a distracting flicker of grain. I'd like to get rid of as much grain as possible while still maintaining some sharpness and fine lines to keep the file sizes reasonable.
So far, Handbrake's NLMeans Medium with Animation preset seems to give the best results, but it's way too slow. All of Avisynth/Vapoursynth filters I try seem to leave the grain after a scene change almost untouched. It looks like the grain is frozen for a few frames. Maybe that makes it harder to detect and degrain?
I haven't been able to duplicate NLMeans results in other degrainers, but I don't understand most of the settings. I wanted to try using equivalent settings for something like KNLMeansCL.
I've attached a few seconds of scenes where it's noticeable.
+ Reply to Thread
Results 1 to 24 of 24
-
-
Temporal noise filters require the grain to be different in successive frames. They see something that's the same across frames as detail that's supposed to be retained. What you could do is remove the duplicates, denoise, then replace the missing duplicates with copies of the first non-duplicate frame. As a proof of concept:
Code:LWLibavVideoSource("sample1.mkv", cache=false, prefer_hw=2) Crop(240,0,-240,-0) ShowFrameNumber(x=20, y=20) Trim(0,36)+Trim(39,0) #Remove frames 37 an 38 SMDegrain(tr=2, thSAD=1000, refinemotion=false, contrasharp=false, PreFilter=0, mode=0, truemotion=false, plane=4, chroma=true) Trim(0,36)+Trim(37,37)+Trim(37,37)+Trim(37,0) # restore frames 37 and 38 with copies of frame 39
-
Quick and dirty solution is to use strong spatial NR, like this combo:
Code:Removegrain(2) FFT3Dfilter (bt=1, sigma=2, sigma2=2, sigma3=10.0, sigma4=10.0, beta=2, plane=4, ncpu=2) KNLMeansCL(d=0, a=3, h=5)
Code:LSMASHVideosource ("G:\Temp\sample12 [nvenc].mp4") RemoveGrain(2) neo_vd (threshold=15, method=1, nsteps=5, y=2,u=3,v=3, percent=80) #FFT3DGPU (bt=1, sigma=2, sigma2=2, sigma3=10.0, sigma4=10.0, beta=2, plane=0) FFT3Dfilter (bt=1, sigma=2, sigma2=2, sigma3=10.0, sigma4=10.0, beta=2, plane=0, ncpu=2) prefetch(4,4) KNLMeansCL(d=0, a=3, h=5) tr=2 bs=16 thSAD=350 thSAD2=250 limit=5 mt=false AddBorders(8,8,16,8) sc_full = MSuper(hpad=0,vpad=0) pre_ds = BicubicResize (width/2,height/2,b=0,c=0.5) sc_ds = pre_ds.MSuper (hpad=0,vpad=0) mv_ds = sc_ds.MAnalyse (multi=true, delta=tr, blksize=bs, mt=mt) mv_dsr = sc_ds.MRecalculate (mv_ds, tr=tr, blksize=bs/2, overlap=2, thSAD=100, mt=mt) mv = mv_dsr.MScaleVect(2) MDegrainN (sc_full, mv, tr, thSAD=thSAD, thSAD2=thSAD2, limit=limit, mt=mt) Crop(8,8,-16,-8) prefetch(4)
Last edited by buzz1891; 16th Jan 2022 at 08:08.
-
Here's a pair of scripts for variable frame rate encoding with DeDup:
pass 1:
Code:v1 = LWLibavVideoSource("sample1.mkv", cache=false, prefer_hw=2) v2 = LWLibavVideoSource("sample2.mkv", cache=false, prefer_hw=2) v1+v2 Crop(240,0,-240,-0) Stab(dxmax=8, dymax=8, range=8, mirror=15) BilinearResize(width/4, height/4) DupMC(log="blah.dup.txt")
Code:v1 = LWLibavVideoSource("sample1.mkv", cache=false, prefer_hw=2) v2 = LWLibavVideoSource("sample2.mkv", cache=false, prefer_hw=2) v1+v2 Crop(240,0,-240,-0) Stab(dxmax=8, dymax=8, range=8, mirror=15) ShowFrameNumber(x=20, y=20) # so we can see exactly which frames were chosen DeDup(threshold=1.0, trigger2=22, maxcopies=3, maxdrops=3, show=false, log="blah.dup.txt", times="blah.times.txt", decwhich=2) SMDegrain(tr=3, thSAD=1000, refinemotion=false, contrasharp=false, PreFilter=0, mode=0, truemotion=false, plane=4, chroma=true) KNLMeansCL(d=0, a=3, h=3)
You can use more or less noise reduction if you want. You can also change the DeDup threshold to get more or fewer dups removed. -
I think I like the results of DeDup since it looks sharper while still removing a lot of grain. I'll try to experiment with the spatial NR method too. Not sure when I'll get time to really dive into it.
Some questions:
Will removing frames and changing to VFR create stutter?
Do two passes mean I run two different scripts?
Is stab required to help remove duplicate frames?
Is it something that can be batch processed?
Is there an easier way to run scripts these days instead of manually creating .avs files and loading all of the plugins and dependencies? I'm looking at StaxRip now, since I'm hoping a GUI will make it easier.
What's the difference between DeDup and ExactDeDup, which is what I see in StaxRip? -
I managed to get DeDup working with VirtualDub2. I'm trying to get it to work in ffmpeg now, but it just creates an empty blah.dup.txt file but no video.
DeDupPass1.avs:
Code:LoadPlugin("C:\Program Files (x86)\AviSynth+\plugins64\DeDup.dll") LWLibavVideoSource("sample2.mkv", cache=false, prefer_hw=2) Crop(240,0,-240,-0) BilinearResize(width/4, height/4) DupMC(log="blah.dup.txt")
Code:ffmpeg -i "DeDupPass1.avs" -c:v libx264 -crf 20 "video.mkv" pause
-
I have the same problem with ffmpeg. I often use:
Code:ffmpeg -benchmark -i %1 -c copy -f null -
Using x264 CLI with -preset ultrafast works fine for the first pass. As does VirtualDub. -
My ultimate goal is to batch run the script so I can process multiple videos while I sleep. I'm having trouble figuring out how to get the script to source multiple videos in a folder instead of linking to the exact video name, and having the txt filenames automatically match the names of the videos. Is there some syntax to do that or do I need to make multiple avs files linking to each video?
-
You can build the AVS scripts within the batch file that steps through file names. Or you can rename each file as it's being processed so it matches the name in the AVS scripts. Then rename it and the output file when the processing is done. I'll post an example later.
-
Here's a post with a batch file that creates an AviSynth script for each video then calls ffmpeg to encode:
https://forum.videohelp.com/threads/396064-DePALifying-TV-Episodes#post2574487
Yes, you can delete the video created during the first pass. Only the stats file is needed for the second pass. -
I'm still having trouble with some scene changes looking grainy. I tried raising the threshold, but I don't know what a safe value is.
threshold=1.6 seems to help with the grain on the scene of the switch.
threshold=2.5 gets rid of the grain in an earlier scene change, but there's noticeable skipping. -
Sample3.mkv has as many as 4 frames in a row with static grain. Change maxdrops and maxdups to 4. Threshold can remain at 1.0.
-
It was looking good until I noticed some fades are no longer smooth when increasing maxcopies and maxdrops, like in this sample video. So far I've only noticed it at the beginning and end of the episode, and every episode will begin and end the same way.
-
The grain fades away along with the rest of the picture. So when the grain falls below the DeDup threshold the frames are tossed out, even though the picture is changing. One possible way to address this is to add grain to the small video that's given to DupMC whenever the overall average luma falls below some threshold value. After a few calculations and little experimentation... Add:
Code:ConditionalFilter(last, last.AddGrain(5.0), last, "AverageLuma()", "lessthan", "24")
During the second pass (even though you're no longer adding grain to the dark frames) DeDup will see the dark frames as non-identical. -
That seems to have fixed it. I appreciate the help.
I noticed what's hopefully the last issue. Is there a way to retain small details like in the sample video of small specks of debris trailing from the spaceship? Lowering SMDegrain thSAD seemed to help, but I'm wondering if there are better options. -
It's tough. With a background moving differently than the spots a temporal filter will have problems. It it locks onto the scrolling background the spots will be blurred away. If it locks onto the spots the scrolling background will be blurred. Increasing the temporal radius (tr=5) and decreasing the thSAD to 300 keeps a bit more of the spots and still provides a lot of the noise reduction.
-
-
You can see more noise around the edges of the space ship, in the nook and crannies.
Sorry, I started with a cut/pasted from another script (which dealt with heavy noise but little motion) and forgot to check that variable. Setting it to true does help with this video. Changing the prefilter option may help too. Try values between 0 and 4 (different noise reduction algorithms are used to clean a copy of the video that's used for motion analysis). That should give you better motion vectors for the main noise reduction.
Processing is slower. But since it helps a lot it should be worth it. Same for the prefilter variable. -
Yes, refinemotion=true seemed to be twice as slow.
I noticed a weird freezing frame issues with refinemotion=true at the end of the explosion in this sample. -
The freezing problem seems to have went away over the course of tweaking the SMDegrain settings.
Another issue I noticed is that I see flickering splotches of smeared grain in some parts of the background. -
Yes, I'm still working on this. I think I have everything looking acceptable now.
I have a few questions I want to understand.
In the DeDup log file, I see numbers in parentheses. What do those mean?
Code:frm 0: diff from frm 1 = 0.5913% at (640,224) frm 1: diff from frm 2 = 0.5955% at (1344,768) frm 2: diff from frm 3 = 0.6005% at (608,672) frm 3: diff from frm 4 = 0.5992% at (960,640) frm 4: diff from frm 5 = 0.6005% at (1152,192) frm 5: diff from frm 6 = 0.6009% at (992,192) frm 6: diff from frm 7 = 0.5997% at (736,288) frm 7: diff from frm 8 = 0.5947% at (1120,512) frm 8: diff from frm 9 = 0.5934% at (1248,512) frm 9: diff from frm 10 = 0.6055% at (672,864) frm 10: diff from frm 11 = 0.6080% at (480,480) frm 11: diff from frm 12 = 0.5926% at (1408,0) frm 12: diff from frm 13 = 0.5972% at (864,160) frm 13: diff from frm 14 = 0.5959% at (1376,864) frm 14: diff from frm 15 = 0.5959% at (64,832) frm 15: diff from frm 16 = 0.5922% at (608,0) frm 16: diff from frm 17 = 0.5959% at (64,576) frm 17: diff from frm 18 = 0.6026% at (32,832) frm 18: diff from frm 19 = 0.6105% at (544,992) frm 19: diff from frm 20 = 0.5959% at (512,896) frm 20: diff from frm 21 = 0.5959% at (576,448) frm 21: diff from frm 22 = 0.5930% at (160,608) frm 22: diff from frm 23 = 0.6092% at (768,864) frm 23: diff from frm 24 = 6.9099% at (1312,1024) frm 24: diff from frm 25 = 1.2155% at (416,96)
My last question is I'm confused about how Trim works.
I used this code to trim frame 17087 and then added a copy of frame 17086, but I had to use +Trim(17086,17086)+Trim(17086,17086) to make the frame count match the original video, even though I only removed one frame. Why didn't using just +Trim(17086,17086) work?
Code:Trim(0,17086)+Trim(17088,0) Trim(0,17086)+Trim(17086,17086)+Trim(17086,17086)+Trim(17088,0)
-
The filter doesn't compare the images as whole, it compares 32x32 pixel blocks. The numbers in parenthesis are the X and Y coordinates of the 32x32 block with the maximum difference. It's basically just informative -- in case you want to look at the frames and see the difference yourself.
I never tried it but is seems like you should be able to change the diff values in the log file to stop the second pass from deleting particular frames, or force it to delete others.
Similar Threads
-
Scene change
By coolgit in forum RestorationReplies: 6Last Post: 9th Oct 2021, 12:22 -
Smoothing of dark scene with fading
By VHS_Hunter in forum RestorationReplies: 1Last Post: 3rd May 2020, 04:15 -
Scene Play DIFFERENT from Project Preview!...
By Mike Ono in forum Newbie / General discussionsReplies: 2Last Post: 29th Nov 2019, 14:24 -
Ripping only a scene
By Faustus in forum DVD RippingReplies: 4Last Post: 18th Apr 2018, 19:10 -
Lines on scene changes - NTSC LD upscaling
By adhouse13972 in forum RestorationReplies: 17Last Post: 30th Oct 2017, 15:26