Selur's Little Message Board

Full Version: DeepEnhancer
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6
I attached the full porting to VapourSynth of FRED film restore

I included the call to DepanEstimate and DepanStabilise

I added also the script for the function UnsharpMask (unsharpmask.py) -> It is safe to add it in Hybrid

This script should be copied in ".\Hybrid\64bit\vsscripts"

It is quite annoying the fact that Vapoursynth display the message:

Code:
Avisynth Compat: requested frame ... not prefetched, using slow method

I think that the addins ColorYUV2.dll and AutoLevels_x64.dll could be added to the whitelist in avisynth_compat.cpp 


Dan

@Selur: I think that script FRED_Restoring_Blending_Cleaning.vpy with the necessary changes to include only the FRED restoring part could be added in  ".\Hybrid\64bit\vsscripts"
Quote:@Selur: I think that script FRED_Restoring_Blending_Cleaning.vpy with the necessary changes to include only the FRED restoring part could be added in ".\Hybrid\64bit\vsscripts"
The whole FRED part should be put in a function, with proper parameters and documentation.
Also, not adding a script that requires Avisynths dlls (here: ColorYUV2 and AutoLevels) Hybrids Vapoursynth scripts.

Cu Selur
Hi Dan,

I’ve just completed a new test today, trying to faithfully reproduce Fred’s 2017 script — the one he described in detail on Doom9 but never published fully.

I used the same filter chain as he mentioned:

RemoveDirtSMC()

GamMac()

DePanStabilize()

Several passes of Tweak() (with starthue and endhue) to isolate specific color bands


McDegrainSharp()

And his sharpening technique: UnsharpMask, blur, UnsharpMask again, then Sharpen()

The goal was to stay as close as possible to Fred's 2017 workflow.
Let me know what you think of the results — I’ll be happy to refine it further based on your suggestions.

Best regards,
Nass



Code:
FFVideoSource("test.mp4").converttoYV12()
Spline64ResizeMT(960, 720)
RemoveDirtSMC()
ConvertToRGB24
GamMac(LockChan=1, Verbosity=1, Scale=2, x=20, y=20, w=-20, h=-20, LoTh=0.04, HiTh=0.04, RedMul=1.00, GrnMul=1.00, BluMul=1.00, Show=false)
ConvertToYV12()  
#Stabilization
mdata=DePanEstimate(last)
DePanStabilize(last, data=mdata)
Crop(20, 20, -20, -20)
# Ajustement des couleurs
Tweak(sat=1.2, bright=5, cont=1.1)
Tweak(hue=10, startHue=0, endHue=30)
Tweak(hue=-10, startHue=30, endHue=60)
Tweak(hue=5, startHue=60, endHue=120)
Tweak(hue=-5, startHue=120, endHue=180)
Tweak(hue=8, startHue=180, endHue=240)
Tweak(hue=-8, startHue=240, endHue=300)
# Denoising et sharpness
RemoveDirtSMC()
McDegrainSharp()
UnsharpMask(radius=3, strength=150)
Blur(0.5)
UnsharpMask(radius=2, strength=100)
Blur(0.3)
Sharpen(0.5)
return last
@djilayeden: you should add 'code'-tags around your script.
Code:
# FUNCTION RemoveDirtSMC
#============================================================================================================================================.

function RemoveTempGrain(clip clp, int "_mode")
{
  _mode = Default(_mode, 17)

  rg    = RemoveGrain(clp, mode=_mode)

  return TemporalRepair(rg, clp)
}





function RemoveDirtS(clip clp, int "limit", bool "_grey")
{
  _grey   = Default(_grey, false)
  limit   = Default(limit, 6)

  clensed = clp.Clense(grey=_grey, cache=4)
  alt     = clp.RemoveGrain(10)

  return (RestoreMotionBlocks(clensed, clp, alternative=alt, pthreshold=4, cthreshold=6, gmthreshold=40, \
                              dist=1, dmode=2, debug=false, noise=limit, noisy=16, grey=_grey))
}





function RemoveDirtSMC(clip clp, int "limit", bool "_grey")
{
  _grey  = Default(_grey, false)
  limit  = Default(limit, 6)

  super1  = MSuper(clp, pel=2, sharp=2)
  bvec1  = MAnalyse(super1, isb=true,  blksize=16, delta=1, truemotion=true)
  fvec1  = MAnalyse(super1, isb=false, blksize=16, delta=1, truemotion=true)
  backw1 = MFlow(clp, super1, bvec1)
  forw1  = MFlow(clp, super1, fvec1)

  clp    = Interleave(backw1, clp, forw1)
  clp    = clp.RemoveDirtS(limit, _grey).removetempgrain(10)
  clp    = clp.SelectEvery(3, 1)


  return clp
}
RemoveDirtSMC()

Code:
function McDegrainSharp(clip c, int "frames", int"strenght",float "bblur", float "csharp", bool "bsrch")
{ # Based on MCDegrain By Didee, http://forum.doom9.org/showthread.php?t=161594
  # Also based on DiDee observations in this thread: http://forum.doom9.org/showthread.php?t=161580
  # "Denoise with MDegrainX, do slight sharpening where motionmatch is good, do slight blurring where motionmatch is bad"
  # In areas where MAnalyse cannot find good matches, the blur() will be dominant.
  # In areas where good matches are found, the sharpen()'ed pixels will overweight the blur()'ed pixels
  # when the pixel averaging is performed.
    frames = default(frames, 2)
    strenght = default(strenght,400)
    bblur  = default(bblur, 1.0)
    csharp = default(csharp, 1.0)
    bsrch  = default(bsrch, true)
    
          blocks = 16
          overl = 8
    
    c2 = c.blur(bblur)
    super = bsrch ? c2.MSuper(pel=2, sharp=1) : c.MSuper(pel=2, sharp=1)
    super_rend     = c.sharpen(csharp).MSuper(pel=2, sharp=1,levels=1)
    backward_vec3 = MAnalyse(super, isb = true, delta = 3, blksize=blocks, overlap=overl)
    backward_vec2 = MAnalyse(super, isb = true, delta = 2, blksize=blocks, overlap=overl)
    backward_vec1 = MAnalyse(super, isb = true, delta = 1, blksize=blocks, overlap=overl)
    forward_vec1 = MAnalyse(super, isb = false, delta = 1, blksize=blocks, overlap=overl)
    forward_vec2 = MAnalyse(super, isb = false, delta = 2, blksize=blocks, overlap=overl)
    forward_vec3 = MAnalyse(super, isb = false, delta = 3, blksize=blocks, overlap=overl)    
    (frames<=0) ? c :\
    (frames==1) ? c2.MDegrain1(super_rend, backward_vec1,forward_vec1,thSAD=strenght) :\
    (frames==2) ? c2.MDegrain2(super_rend, backward_vec1,forward_vec1,backward_vec2,forward_vec2,thSAD=strenght) :\
              c2.MDegrain3(super_rend, backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,thSAD=strenght)
    return(last)
}

McDegrainSharp()
Here's a Vapoursynth port or RemoveDirtSMC, but normal RemoveDirtMC seems superior.
The S seems to stand for 'simple'.
Code:
def RemoveTempGrain(clip: vs.VideoNode, mode: int=17) -> vs.VideoNode:
  if hasattr(core, 'zsmooth'):
    rg = core.zsmooth.RemoveGrain(clip, mode=mode)
  else:
    rg = core.rgvs.RemoveGrain(clip, mode=mode)
  return TemporalRepair(rg, clip)

def RemoveDirtS(clip: vs.VideoNode, limit: int= 6, grey: bool=False) -> vs.VideoNode:
  clensed = core.rgvs.Clense(clip)
  if hasattr(core, 'zsmooth'):
    alt = core.zsmooth.RemoveGrain(clip, mode=10)
  else:
    alt = core.rgvs.RemoveGrain(clip, mode=10)
  return core.removedirt.RestoreMotionBlocks(clensed, clip, alternative=alt, pthreshold=4, cthreshold=6, gmthreshold=40, dist=1, dmode=2, debug=False, noise=limit, noisy=16, grey=False)

def RemoveDirtSMC(clip: vs.VideoNode, limit: int=6, repmode: int=16, remgrainmode: int=17, block_size: int=8, block_over: int=4, gpu: bool=False) -> vs.VideoNode:
  
  if gpu:
    import ChangeFPS
    block_over = 0 if block_over == 0 else 1 if block_over == 2 else 2 if block_over == 4 else 3
    Super = core.svp1.Super(clip, "{gpu:1,pel:4}")
    bvec = core.svp1.Analyse(Super['clip'], Super['data'], clip, "{ gpu:1, block:{w:"+str(block_size)+", h:"+str(block_size)+",overlap:"+str(block_over)+"} }")
    fvec = core.svp1.Analyse(Super['clip'], Super['data'], clip, "{ gpu:1, block:{w:"+str(block_size)+", h:"+str(block_size)+",overlap:"+str(block_over)+",special:{delta: 1}} }")
    backw = core.svp2.SmoothFps(clip,Super['clip'], Super['data'],bvec['clip'],bvec['data'],"{}") # here the frame rate is doubled
    forw = core.svp2.SmoothFps(clip,Super['clip'], Super['data'],fvec['clip'],fvec['data'],"{}")  # here the frame rate is doubled
    # since backw and forw now have twice the frame count I drop half the frames
    backw = ChangeFPS.ChangeFPS(backw,clip.fps_num,clip.fps_den)
    forw = ChangeFPS.ChangeFPS(forw,clip.fps_num,clip.fps_den)
  else:
    #block size of MAnalyze, blksize 8 is much better for 720x576 noisy source than blksize=16
    #block overlapping of MAnalyze 0! 2 or 4 is not good for my noisy b&w 8mm film source
    i = core.mv.Super(clip, pel=2, sharp=2)    #  avs: i=MSuper(clip,pel=2, isse=false)
    bvec = core.mv.Analyse(super=i,isb=True, blksize=block_size,overlap=block_over, delta=1, truemotion=True, chroma=True)  
    fvec = core.mv.Analyse(super=i,isb=False, blksize=block_size,overlap=block_over, delta=1, truemotion=True, chroma=True)
    backw = core.mv.Flow(clip=clip,super=i,vectors=[bvec])
    forw  = core.mv.Flow(clip=clip,super=i,vectors=[fvec])

  clip    = core.std.Interleave([backw, clip, forw])
  clip    = RemoveDirtS(clip, limit)
  if hasattr(core, 'zsmooth'):
    clip = core.zsmooth.RemoveGrain(clip, mode=10)
  else:
    clip = core.rgvs.RemoveGrain(clip, mode=10)
    
  clip = core.std.SelectEvery(clip, 3, 1)

  return clip
(12.04.2025, 15:47)Selur Wrote: [ -> ]
Quote:@Selur: I think that script FRED_Restoring_Blending_Cleaning.vpy with the necessary changes to include only the FRED restoring part could be added in  ".\Hybrid\64bit\vsscripts"
The whole FRED part should be put in a function, with proper parameters and documentation.
Also, not adding a script that requires Avisynths dlls (here: ColorYUV2 and AutoLevels) Hybrids Vapoursynth scripts.

Cu Selur

Unfortunately I was unable to find any Vapoursynth substitute for ColorYUV  and AutoLevels  do you have any idea if they are available ?

Dan
Afaik. they do not exist.
They are listed them in my 'Things missing in Vapoursynth'-thread over in Doom9s forum.
Since these are missing for years, my hope to get a proper port for these is slim.
For ColorYUV, the old Vapoursynth doc stated that one should 'Do the adjustment yourself' with 'std.Lut/std.Expr'. Rolleyes

Cu Selur
I implemented a version of FRED which is using only Vapoursynth functions.

I attached a test sample. In the archive there are the following files:
  • FRED_Restoring_Blending_Cleaning_AVS.vpy : script using Avisynth dlls (similar to the one already provided, with only the FRED code)
  • FRED_Restoring_Blending_Cleaning_VS.vpy : script using only Vapousynth functions
  • sample_full.mp4 : sample clip

To use the Vapoursynth version is necessary to install the new filter included in this post: New AutoColor adjustment filter

Dan
Pages: 1 2 3 4 5 6