digitalFAQ.com Forum

digitalFAQ.com Forum (https://www.digitalfaq.com/forum/)
-   Restore, Filter, Improve Quality (https://www.digitalfaq.com/forum/video-restore/)
-   -   FixRips grain noise dropouts (tweaked version) script? (https://www.digitalfaq.com/forum/video-restore/12806-fixrips-grain-noise.html)

themaster1 06-03-2022 07:52 AM

FixRips grain noise dropouts (tweaked version) script?
 
6 Attachment(s)
I have spent some time tweaking the FixRipsP2 script (based on Didée's script initially ) and i believe i've nailed it. It now remove effectively grains/noise and keeps lots of details without weird artifacts (like warping).
I have tweaked: the motion vectors parameters to my liking (probably the hardest part), removed Tmedian2 (which cause warping) replaced with a tweaked version of Spotless.

This script is very useful for vhs with: grains, noise, dropouts

Feel free to try it with your video and report how good (or bad) it is for further tweaks.

Note: tested on Live footage from a VHS
Quote:

video_org=AVISource("MyVideo.avi")
# plugins directory
plugins_dir="C:\Program Files (x86)\AviSynth 2.6\plugins"
# FixRipsp2
Import(plugins_dir + "FixRipsP2_themaster1.avs")
### separate fields
video_org_sep=video_org.AssumeTFF().separateFields ()
### select even fields
video_org_sep_even=SelectEven(video_org_sep)
### select odd fields
video_org_sep_odd=SelectOdd(video_org_sep)
### repair
video_org_sep_even_rep=video_org_sep_even.FixRipsp 2()
video_org_sep_odd_rep=video_org_sep_odd.FixRipsp2( )
### interleave
video_interleaved=interleave(video_org_sep_even_re p,video_org_sep_odd_rep)
### weave
video_restored=video_interleaved.Weave()
last=video_restored
#return(video_restored)

lollo2 06-03-2022 08:17 AM

Thanks a lot themaster1!

Selur 06-11-2022 07:31 AM

@master1: Got a question you might be able to answer.
I wanted to combine your script with support for svp from https://forum.doom9.org/showthread.php?p=1574161
using:
Code:

#### TWEAKED VERSION OF FIXRIPSP2 , BY THEMASTER1, June 2022
# TO REMOVE GRAINS, DROPOUTS (Only light ones, not multi frames ones)
# http://www.digitalfaq.com/forum/video-restore/12806-fixrips-grainnoisedropouts-script.html
# The original script comes from Didée, see more here: http://forum.doom9.org/showpost.php?p=1483709&postcount=10
# + svp from https://forum.doom9.org/showthread.php?p=1574161, note that blocksize is only 8 not for as when using mvtools
#########
function FixRipsP2(clip a,  bool "svp")
{
    svp=default(svp,false)
    a
    clense(reduceflicker=false).merge(last,0.5).clense(reduceflicker=false)
    mot=removegrain(8,0).DepanEstimate(range=2)
    take2=a.depaninterleave(mot,prev=2,next=2,subpixel=2)
    clean1=take2.selectevery(5,2)
    clean1=clean1.mt_lutxy(clean1,"x 1 + y < x 2 + x 1 - y > x 2 - y ? ?",U=2,V=2)
   
    svp ? { # using svp
        sup1 = clean1 .SVSuper("pel:2, scale:{up:0}")
        search_params="block:{w:4,overlap:2}" # can't use blocksize 4, w:4 <> blocksize 8

        v21=sup1.SVAnalyse("{"+search_params+"}")
        v22=sup1.SVAnalyse("{"+search_params+",special:{delta:2}}")

        bv22=v22.SVConvert(isb=true)
        bv21=v21.SVConvert(isb=true)
        fv21=v21.SVConvert(isb=false)
        fv22=v22.SVConvert(isb=false)

        sup2 = a.msuper(pel=2,levels=1,sharp=2)
        interleave(a.mcompensate(sup2,fv22),a.mcompensate(sup2,fv21),a,a.mcompensate(sup2,bv21),a.mcompensate(sup2,bv22))

        selectevery(5,2)
        sup3 = last.msuper(pel=2,sharp=2,hpad=0,vpad=0)

        # SVAnalyse accepts MSuper with zero padding!
        v31=sup3.SVAnalyse("{"+search_params+"}")
        v32=sup3.SVAnalyse("{"+search_params+",special:{delta:2}}")
        v33=sup3.SVAnalyse("{"+search_params+",special:{delta:3}}")

        bv33=v33.SVConvert(isb=true)
        bv32=v32.SVConvert(isb=true)
        bv31=v31.SVConvert(isb=true)
        fv31=v31.SVConvert(isb=false)
        fv32=v32.SVConvert(isb=false)
        fv33=v33.SVConvert(isb=false)
    } : { # using mvtools
        sup1 = clean1.msuper(pel=2,sharp=0)
        sup2 = a.msuper(pel=2,levels=1,sharp=2)

        bv21=sup1.manalyse(isb=true, truemotion=true,global=true,delta=1,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        bv22=sup1.manalyse(isb=true, truemotion=true,global=true,delta=2,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        fv21=sup1.manalyse(isb=false,truemotion=true,global=true,delta=1,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        fv22=sup1.manalyse(isb=false,truemotion=true,global=true,delta=2,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        interleave(a.mcompensate(sup2,fv22),a.mcompensate(sup2,fv21),a,a.mcompensate(sup2,bv21),a.mcompensate(sup2,bv22))

        #SpotLess(RadT=5,ThSAD=1000000,ThSAD2=1000000,pel=2,chroma=false,BlkSz=8,Olap=4,tm=false,glob=false,bBlur=0.0).selectevery(5,2) # proposed by The Filter  Developper
        SpotLess(RadT=2,ThSAD=500000,ThSAD2=499000,pel=2,chroma=true,BlkSz=4,Olap=2,tm=false,glob=false,bBlur=0.0).selectevery(5,2) # to remove less  fine details BlkSz=4,Olap=2 et RADT=1 (If higher it creates artifacts)

        sup3 = last.msuper(pel=2,sharp=2)
        bv31=sup3.manalyse(isb=true, truemotion=true,global=true,delta=1,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        bv32=sup3.manalyse(isb=true, truemotion=true,global=true,delta=2,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        bv33=sup3.manalyse(isb=true, truemotion=true,global=true,delta=3,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        fv31=sup3.manalyse(isb=false,truemotion=true,global=true,delta=1,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        fv32=sup3.manalyse(isb=false,truemotion=true,global=true,delta=2,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
        fv33=sup3.manalyse(isb=false,truemotion=true,global=true,delta=3,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
    }
   
    #last.mdegrain1(sup3,bv31,fv31,bv32,fv32,bv33,fv33,thSAD=499)
    last.mdegrain1(sup3,bv31,fv31,thSAD=499)
    #last.mdegrain1(sup3,bv31,fv31,thSAD=499)

    interleave()
    return last
}
######################


################




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==0) ? mt_makediff(clp,clp.sbr(),U=uv2,V=uv2)
    \    : (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)
}

function SpotLess(clip c,int "RadT",int "ThSAD",int "ThSAD2",int "pel",bool "chroma", int "BlkSz",Int "Olap",bool "tm",Bool "glob",Float "bBlur") {
    RadT = Default(RadT,1) # Temporal radius. (MCompensate arg)
    ThSAD = Default(ThSAD,10000) # SAD threshold at radius 1 (Default Nearly OFF).
    ThSAD2 = Default(ThSAD2,ThSAD) # SAD threshold at radius RadT.
    Pel = Default(pel,2) # Default 2. 1, 2, or 4. Maybe set 1 for HD+. (1=precision to pixel, 2=precision to half pixel, 4=quarter pixel)
    Chroma = Default(chroma,True) # MAnalyse chroma arg. If set to true, use chroma in block matching.
    BlkSz = Default(BlkSz,8) # Default 8. MAnalyse BlkSize. Bigger blksz quicker and perhaps better, esp for HD clips. Maybe also better where BIG noise.
    OLap = Default(OLap, BlkSz/2) # Default half of BlkSz.
    Tm = Default(tm,True) # TrueMotion, Some folk swear MAnalyse(truemotion=false) is better.
    Glob = Default(glob,Tm) # Default Tm, Allow set MAnalyse(global) independently of TrueMotion.
    Bblur = Default(bblur,0.0) # Default OFF
    Assert(1 <= RadT,"SpotLess: 1 <= RadT")
    pad = max(BlkSz,8)
    sup = (bBlur<=0.0 ? c : c.blur(bblur)).MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2)
    sup_rend = (bBlur<=0.0) ? sup : c.MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2,levels=1) # Only 1 Level required where not MAnalyse-ing.
    MultiVec = sup.MAnalyse(multi=true, delta=RadT,blksize=BlkSz,overlap=OLap,search=4,chroma=Chroma,truemotion=Tm,global=Glob)
    c.MCompensate(sup_rend,MultiVec,tr=RadT,thSad=ThSAD,thSad2=ThSAD2)
    MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=RadT) # Temporal median blur only [not spatial]
    SelectEvery(RadT*2+1,RadT) # Return middle frame
}

Problem is the syntax of the ?-operator seems to be wrong.
I thought I correctly looked it up over at http://avisynth.nl/index.php/Block_statements, but that does not seem to be the case.
Do you see the what I did wrong?

Cu Selur

themaster1 06-11-2022 03:22 PM

Jeez.. i wish, I'm not a coder by any means, just a sub-par tweaker lol. I'm sure they'll help you out on doom9, brilliants minds over there. I support this SVP tweak though (MV's calculated by GPU) , anything to speed up the processing of this script is welcome.

Selur 06-12-2022 01:39 AM

okay, will probably figure it out later today. :)

Selur 06-12-2022 05:55 AM

What I don't understand in your script, you use:
  1. Code:

    last.mdegrain1(sup3,bv31,fv31,thSAD=499)
    and not
    Code:

    last.mdegrain3(sup3,bv31,fv31,bv32,fv32,bv33,fv33,thSAD=499)
  2. when you use mdegrain1, why are you still spending tons of time computing:
    Code:

    bv32=sup3.manalyse(isb=true, truemotion=true,global=true,delta=2,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
    bv33=sup3.manalyse(isb=true, truemotion=true,global=true,delta=3,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)

    and
    Code:

    fv32=sup3.manalyse(isb=false,truemotion=true,global=true,delta=2,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
    fv33=sup3.manalyse(isb=false,truemotion=true,global=true,delta=3,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)


without those your main function is just:
Code:

function FixRipsP2(clip a)
{
    a
    clense(reduceflicker=false).merge(last,0.5).clense(reduceflicker=false)
    mot=removegrain(8,0).DepanEstimate(range=2)
    take2=a.depaninterleave(mot,prev=2,next=2,subpixel=2)
    clean1=take2.selectevery(5,2)

    sup1 = clean1
    \          .mt_lutxy(clean1,"x 1 + y < x 2 + x 1 - y > x 2 - y ? ?",U=2,V=2)
    \          .msuper(pel=2,sharp=0)
    sup2 = a.msuper(pel=2,levels=1,sharp=2)

    bv21=sup1.manalyse(isb=true, truemotion=true,global=true,delta=1,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
    bv22=sup1.manalyse(isb=true, truemotion=true,global=true,delta=2,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
    fv21=sup1.manalyse(isb=false,truemotion=true,global=true,delta=1,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
    fv22=sup1.manalyse(isb=false,truemotion=true,global=true,delta=2,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)

    interleave(a.mcompensate(sup2,fv22),a.mcompensate(sup2,fv21),a,a.mcompensate(sup2,bv21),a.mcompensate(sup2,bv22))

    #SpotLess(RadT=5,ThSAD=1000000,ThSAD2=1000000,pel=2,chroma=false,BlkSz=8,Olap=4,tm=false,glob=false,bBlur=0.0).selectevery(5,2) # proposed by The Filter  Developper
    SpotLess(RadT=2,ThSAD=500000,ThSAD2=499000,pel=2,chroma=true,BlkSz=4,Olap=2,tm=false,glob=false,bBlur=0.0).selectevery(5,2) # to remove less  fine details BlkSz=4,Olap=2 et RADT=1 (If higher it creates artifacts)


    sup3 = last.msuper(pel=2,sharp=2)
    bv31=sup3.manalyse(isb=true, truemotion=true,global=true,delta=1,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)
    fv31=sup3.manalyse(isb=false,truemotion=true,global=true,delta=1,blksize=4,overlap=2,search=3,searchparam=5,DCT=2)

    last.mdegrain1(sup3,bv31,fv31,thSAD=499)

    interleave()
    return last
}

Cu Selur

Selur 06-12-2022 06:30 AM

Got another question, you wrote:
Code:

removed Tmedian2 (which cause warping) replaced with a tweaked version of Spotless.
What seems strange is that you only replaced TMeadian2 with Spotless in one occurance and simpls dropped the other.
You only use it for sup3, but Didée used it for all sups. This seems strange.

themaster1 06-12-2022 03:58 PM

One instance of spotless is enough to me (tested many times) and i prefer removegrain1 (some grain removed and details are well preserved)

You're right by the way, you could remove the bv32 bv33 / fv32 fv33 lines (mdegrain1 = 1 frame radius, mdegrain2 = 2 frames etc..)

Selur 06-15-2022 03:56 PM

Here's a port of your version using SVP in the FixRipsP2 part:
Code:

function FixRipsP2SVP(clip "a", bool "twofold")
{
    a
    Clense(reduceflicker=false).Merge(last,0.5).Clense(reduceflicker=false)
    mot=RemoveGrain(8,0).DepanEstimate(range=2)
    take2=a.DePanInterleave(mot,prev=2,next=2,subpixel=2)
    clean1=take2.SelectEvery(5,2)
    search_params="gpu: 1, block:{w:4,overlap: 2}" # can't use blocksize 4, w:4 <> blocksize 8

    sup1 = clean1.mt_lutxy(clean1,"x 1 + y < x 2 + x 1 - y > x 2 - y ? ?",U=2,V=2)
    sup1 = sup1.SVSuper("{ pel: 2, gpu: 1, scale: { up: 0 } }")
    v21=sup1.SVAnalyse("{"+search_params+"}")
    fv21=v21.SVConvert(isb=false)
    bv21=v21.SVConvert(isb=true)
    v22=sup1.SVAnalyse("{"+search_params+", special: { delta: 2 } }")
    bv22=v22.SVConvert(isb=true)
    fv22=v22.SVConvert(isb=false)


    sup2 = a.MSuper(pel=2,levels=1,sharp=2)
    src = interleave(a.MCompensate(sup2,fv22),a.MCompensate(sup2,fv21),a,a.MCompensate(sup2,bv21),a.MCompensate(sup2,bv22))
    src = src.SpotLess(RadT=2,ThSAD=500000,ThSAD2=499000,pel=2,chroma=true,BlkSz=4,Olap=2,tm=false,glob=false,bBlur=0.0) # to remove less  fine details BlkSz=4,Olap=2 et RADT=1 (If higher it creates artifacts)
    src = src.SelectEvery(5,2)
   
    sup3 = src.SVSuper("{ pel: 2, gpu: 1, scale: { up: 0 } }")
    search_params="gpu: 1, block:{w:4,overlap:2}}" # can't use blocksize 4, w:4 <> blocksize 8
    v31=sup3.SVAnalyse("{"+search_params+"}")
    bv31=v31.SVConvert(isb=true)
    fv31=v31.SVConvert(isb=false)
 
    sup3 = src.MSuper(pel=2,sharp=2)
    last.MDegrain1(sup3,bv31,fv31,thSAD=499)

    return interleave()
}


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==0) ? mt_makediff(clp,clp.sbr(),U=uv2,V=uv2)
    \    : (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)
}

Function SpotLess(clip c,int "RadT",int "ThSAD",int "ThSAD2",int "pel",bool "chroma", int "BlkSz",Int "Olap",bool "tm",Bool "glob",Float "bBlur") {
    RadT = Default(RadT,1) # Temporal radius. (MCompensate arg)
    ThSAD = Default(ThSAD,10000) # SAD threshold at radius 1 (Default Nearly OFF).
    ThSAD2 = Default(ThSAD2,ThSAD) # SAD threshold at radius RadT.
    Pel = Default(pel,2) # Default 2. 1, 2, or 4. Maybe set 1 for HD+. (1=precision to pixel, 2=precision to half pixel, 4=quarter pixel)
    Chroma = Default(chroma,True) # MAnalyse chroma arg. If set to true, use chroma in block matching.
    BlkSz = Default(BlkSz,8) # Default 8. MAnalyse BlkSize. Bigger blksz quicker and perhaps better, esp for HD clips. Maybe also better where BIG noise.
    OLap = Default(OLap, BlkSz/2) # Default half of BlkSz.
    Tm = Default(tm,True) # TrueMotion, Some folk swear MAnalyse(truemotion=false) is better.
    Glob = Default(glob,Tm) # Default Tm, Allow set MAnalyse(global) independently of TrueMotion.
    Bblur = Default(bblur,0.0) # Default OFF
    Assert(1 <= RadT,"SpotLess: 1 <= RadT")
    pad = max(BlkSz,8)
    sup = (bBlur<=0.0 ? c : c.blur(bblur)).MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2)
    sup_rend = (bBlur<=0.0) ? sup : c.MSuper(hpad=pad,vpad=pad,pel=pel,sharp=2,levels=1) # Only 1 Level required where not MAnalyse-ing.
    MultiVec = sup.MAnalyse(multi=true, delta=RadT,blksize=BlkSz,overlap=OLap,search=4,chroma=Chroma,truemotion=Tm,global=Glob)
    c.MCompensate(sup_rend,MultiVec,tr=RadT,thSad=ThSAD,thSad2=ThSAD2)
    MedianBlurTemporal(radiusY=0,radiusU=0,radiusV=0,temporalradius=RadT) # Temporal median blur only [not spatial]
    SelectEvery(RadT*2+1,RadT) # Return middle frame
}

should be faster but might blur more since it one can use blocksize 8 not 4.

Cu Selur

themaster1 06-16-2022 01:04 AM

2 Attachment(s)
Hey well done, could be useful for animes perhaps (not my area).
Though, Svp is not exactly "motion safe" i've noticed it before when messing with motion interpolation

In any case i couldn't have done it better :congrats:

Selur 06-16-2022 01:29 AM

Happy if someone has any usage for it. I'm usually not really using AviSynth so I won't use it. :)
I gues the motion problem is related to the bloack size ony be 8.

Cu Selur


All times are GMT -5. The time now is 04:28 AM

Site design, images and content © 2002-2026 The Digital FAQ, www.digitalFAQ.com
Forum Software by vBulletin · Copyright © 2026 Jelsoft Enterprises Ltd.