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.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 6th August 2018, 22:24   #21  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Also, in looking at all the metrics, the four main "ratio" metrics, which appear to be the heart of the detection logic, don't seem to change all that much for the frames containing lots of noise.
Yes well, as I recall you did your inital script to detect Flash Frames, aint no flashes here, just crap.
PRatio and NRatio in you image were though still over BadThresh of 1.3 (actually about 1.57),
and the MC ratios need both be lo-ish.
EDIT: If you set GoodThreshold very high, then will sort of behave pretty much as your detector would (assuming same Badthresh).
The purpose of GoodThreshold is to limit replacement where would be clearly detrimental.

The shown MC frame is synthesized from those either side of the (upper) source frame, ie src(n-1 and n+1).
The MC frame aligning with src(n-1) was synthesized from source frames src(n-2 and n) and as src(n) is the current crap
frame, so it is bad [which actually means it is less likely to be chosen to replace src(n-1), if good GoodThreshold can be found].
Exact same thing for MC frame aligning with src+1.

Anyways, make ShowSubs=False, and leave ShowDot and STACK at true, and play, you should see the clip being fixed
(source will move to bottom and fixed without subs to top, but showing the DOT on fixed frames).
Not perfect I know, but is better, I was kinda hoping that you might improve whilst I was off doing stuff.
Well I shall try maybe recreate src(n) by (as well as using n-1 and n+1 as MC interp sources) using n-2 and n+1, and another from n-1 and n+2,
and try chose least worst of the bunch.
I'm probably off doing stuff again for a lil bit but should get back within the hour probably (and then try do it).


Where there was two consecutive crud frames in source, both result MC frames will likely look bad
(probably not as bad as original, unless 3 or 4 consecutive crap frames, where would probably look worse
especially where crap coincides) .

EDIT: OK, I see what you misunderstood, the MC clip is a test comparison clip, it is not the fixed clip, where
numbers are good, the current MC frame will be chosen to replace the crud source frame. (MC is created at top
of script and it dont change). It is both part of the detection whatsit, and where appropriate the source of individual
frames used in fixing crud, but only for fixing single bad frames.
Every frame in the MC clip is the result of interpolating the two frames either side of it in the source clip.
In your script, ReplaceBadFramesI just blindly replaces bad frames when bad
source is detected, here we use the MC clip (the source of frames that will repair crud frames) within the detector,
to see if replacment frames are likely better than the crud they are to fix, that is what GoodThreshold thing is about.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 6th August 2018 at 23:36.
StainlessS is offline   Reply With Quote
Old 7th August 2018, 01:45   #22  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,695
StainlessS,

Thanks for the lengthy explanation. It answers all my questions and gives me enough information that I should be able to play around and, who knows, I might actually do something useful.

I'll be able to get to this tomorrow. I have a vested interest in this, beyond just helping the OP, because the problem of fixing individual bad frames happens ALL the time, in countless different ways. Having a better script would be welcome.
johnmeyer is offline   Reply With Quote
Old 7th August 2018, 21:41   #23  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,695
Played around with ShowSubs=False, as you suggested and except for the two-frame corruption at frames 166 & 167, the script works flawlessly.

I'm still trying to fully understand the way you've done comparisons using n-2, n-1, n+1, n+2, but if I ask questions about that, we'll go down the same long rat hole (see this) about how motion estimation deltas work, etc. No need to re-hash that now.

So, with this test clip, the script seems to work almost flawlessly for single corrupt frames, and your logic does a better job detecting them than did my simple, single YDifference ratios. Your attempt to make it also work when there are two flawed frames in a row doesn't appear to work on that one pair I mentioned above.

I'll keep looking at this, as time permits.

[edit] The script does replace about 2x the number of frames that it needs to (i.e., it is replacing quite a few good frames). My script did that as well.

In looking some more at 166 & 167, your script does detect and then replace them both, but since the only motion compensation clip you create is "MC", that doesn't give good results when an adjacent frame is also corrupt.

Last edited by johnmeyer; 8th August 2018 at 00:08. Reason: clarity; later, removed sentence fragment at end
johnmeyer is offline   Reply With Quote
Old 7th August 2018, 22:57   #24  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
EDIT:
Quote:
Originally Posted by johnmeyer View Post
and your logic does a better job detecting them than did my simple, single YDifference ratios. Your attempt to make it also work when there are two flawed frames in a row doesn't appear to work
Not my logic John, thats your logic, messed about a bit but doing same thing.

Have not implemented 2 crud frame stuff yet, that is what I am currently struggling with, only improvement over yours really is in the Goodthresh thing.
End_EDIT:


I have not as yet been able to figure out a way of using the additional MC fix clips (n-2,n+1, etc) and weighting so as to be able to compare with each other,
but have not as yet given up.

As for GoodThreshold, I think that a fixed thresh is not the best thing here.
Reason,
1st of all, to detect bad, instead of using PRatio and NRatio, we could simplify to just 1 ratio ie Ratio = Max(PRatio,NRatio).
In detector, if EITHER P or N ratio is greater or equal to BadThreshold, then is bad, so decision is really governed by the greater of the two.
Similarly, to detect if MC candidate fix frame is good, BOTH MC_P AND MC_N ratios should be less than GoodThreshold, so decision is really again
governed by the greater of the two MC ratio's, so MC_Ratio = Max(MC_PRatio,MC_NRatio).
So now I can just use terms Ratio and MC_Ratio.

The bad Ratio could be significantly greater than BadThreshold, and so by using GoodThreshold = Badthreshold as default, might be expecting too great an improvment
via the candidate MC fix frame, perhaps we need self calibrating GoodThreshold.
My first idea was to remove GoodThreshold from user setting and inside script for each frame make it, GoodThreshold=(Ratio-1)/2.0 + 1.0, so
it would be set half way between 1.0 and detected numbers for the crud frame. this seems quite reasonable, but it could be that anything
below Ratio would (by the numbers) be an improvment, where could be set as GoodThreshold=Ratio.
So next (and current best) idea, is allow user set option of Goodthreshold, and depending upon user setting, either use fixed GoodThreshold, or
self calibrating.
If user sets GoodThreshold > 1.0, then is non self calibrating fixed threshold.
If 0.0 < GoodThreshold <= 1.0, then self calibrating, where for each frame Goodthr = (Ratio - 1.0) * GoodThreshold + 1.0,
so a GoodThreshold of eg 0.5, would set GoodThr for each frame to half way between 1.0 and Ratio, 0.666 to 2/3 of the way, 1.0 to Ratio.
[EDIT: GoodThreshold <= 0.0 error]
Anyways, if doubts then shout up.
EDIT: Above in Red Perhaps Wrong, see next post.

Here shifted clips.
[Actually using RT_Stats RT_LumaDifference(clip1,clip2, n=i n2=j) (or delta=k, delta2=l) could avoid all of the shifting stuff (but implementing as raw avs script).]
Code:
############ Shifted Source Clips #######

P2C       = ORG.selectevery(1, -2)                                             # src n-2 Frame shifted to frame n
P1C       = ORG.selectevery(1, -1)                                             # src n-1 Frame shifted to frame n
N1C       = ORG.selectevery(1, +1)                                             # src n+1 Frame shifted to frame n
N2C       = ORG.selectevery(1, +2)                                             # src n+2 Frame shifted to frame n

############   Shifted MC Clips   #######

Prefilt   = ORG.RemoveGrain(22)
Super     = ORG.MSuper(hpad=16,vpad=16,levels=1,sharp=1,rfilter=4)             # One level is enough for MRecalculate
Superfilt = Prefilt.MSuper(hpad=16,vpad=16,sharp=1,rfilter=4)                  # All levels for MAnalyse
bv        = Superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=2)# DELTA 2, (distance between interpolate source frames)
fv        = Superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=2)
bv        = Super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
fv        = Super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
MC11      = ORG.MFlowInter(Super,bv,fv,time=50.0,ml=200).SelectEvery(1,-1)     # n interplated from src n-1 & n+1 @ 50.0% (n-1 shifted to n)
#
bv        = Superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=3)# DELTA 3
fv        = Superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=3)
bv        = Super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
fv        = Super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
MC21      = ORG.MFlowInter(Super,bv,fv,time=200.0/3,ml=200).SelectEvery(1,-2)    # n interplated from src n-2 & n+1 @ 66.67% (n-2 shifted to n)
MC12      = ORG.MFlowInter(Super,bv,fv,time=100.0/3,ml=200).SelectEvery(1,-1)    # n interplated from src n-1 & n+2 @ 33.33% (n-1 shifted to n)
#
bv        = Superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=4)# DELTA 4
fv        = Superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=4)
bv        = Super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
fv        = Super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
MC22      = ORG.MFlowInter(Super,bv,fv,time=50.0,ml=200).SelectEvery(1,-2)     # n interplated from src n-2 & n+2 @ 50.0% (n-2 shifted to n)
#####################################
EDIT: the (n-1 shifted to n) in blue above aligns the interpolated MC frame to align with the src frame that is intended to fix.
EDIT: MC interpolated frames are not created at the same frame number as the frame they are intended to fix, they are created at the same frame number of the lower of the two source frame numbers used as interpolate source frames, and so need to be shifted to align with fix target frame in source clip.
EDIT: eg YDifferencetoNext can be used to get dif between a clip frame current_frame and same clip current_frame+1, but if current and n+2, then must use
something else. LumaDifference allows for two clips (which could be same clip), but both frames compared are at current frame, this is the reason for clip alignment (also same type thing used to compare n+1, n+2, shifted clip can still use YDifferencetoNext with shifted clip).
LumaDifference allows eg clip1, n+x to clip2 n+y, but both clips need be aligned by -x and -y. (avs 2.60 allows for offset arg which can avoid some shifting if both x and y are same).
EDIT: Talking B*ll*cks above, AverageLuma et al have offset arg, YDifferenceToNext and LumaDifference do NOT have Offset args in v2.60.
RT_Stats funcs for same stuff can use current_frame (by default) or 'n=x' for frame x or delta=y (default 0, offset from current_frame or specified frame number) and where two clips (eg RT_LumaDifference) can specify all (or default) for each clip.


EDIT: Thanx John, revisited your link in prev post and found a broken PostImage link, now fixed.
EDIT: MC21 and MC12 MFlowInter times fixed (was eg 1.0/3 instead of 100.0/3)
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 12th August 2018 at 18:05.
StainlessS is offline   Reply With Quote
Old 8th August 2018, 02:50   #25  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Prev posted self calibrating GoodThreshold is perhaps wrong, was Goodthr = (Ratio - 1.0) * GoodThreshold + 1.0, but should maybe be as below.

Below correction.
If user sets GoodThreshold > 1.0, then is non self calibrating fixed threshold.
If 0.0 <= GoodThreshold <= 1.0, then self calibrating, where for each frame Goodthr = (Ratio - BadThreshold) * GoodThreshold + BadThreshold,
so a GoodThreshold of eg 0.5, would set GoodThr for each frame to half way between BadThreshold and Ratio, 0.666 to 2/3 of the way, 1.0 to Ratio.
GoodThreshold < 0.0 error. [EDIT: was GoodThreshold <= 0.0 error. if 0.0 then GoodTh set to BadThreshold]

Seem more sensible ? (or not, I aint sure)

Here, prev posted script modded as per prev post corrected GoodThreshold stuff.

Code:
AVISource("D:\GreyMouse_Rollaine_Noise_Sample_Pass1_huffy.avi").ConvertToYV12
ORG=Last

SelectEvery(1,-1) # Shift Forward 1
super=MSuper()
prefilt    = RemoveGrain(22)
super      = MSuper(hpad=16,vpad=16,levels=1,sharp=1,rfilter=4)   # One level is enough for MRecalculate
superfilt  = prefilt.MSuper(hpad=16,vpad=16,sharp=1,rfilter=4)      # All levels for MAnalyse
bv        = superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=2)
fv        = superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=2)
bv        = super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
fv        = super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
MFlowInter(super,bv,fv,time=50,ml=200)
MC=Last
ORG

BadThreshold  = 1.3

GoodThreshold = 1.0/3       # 0.333, self calibrating threshold. [EDIT: Was 0.666]

SHOWSUBS=True
ShowDot=true
STACK=true

Met_Script = """                                                               # Where n = current_frame
        ###################
        P1C       = selectevery(1, -1)                                         # Clip where n-1 Frame shifted to frame n
        N1C       = selectevery(1, +1)                                         # Clip where n+1 Frame shifted to frame n
        P2C       = selectevery(1, -2)                                         # Clip where n-2 Frame shifted to frame n
        N2C       = selectevery(1, +2)                                         # Clip where n+2 Frame shifted to frame n
        P2P1Dif   = YDifferenceFromPrevious(P1C)                               # Dif(n-2, n-1)
        N1N2Dif   = YDifferenceToNext(N1C)                                     # Dif(n+1, n+2)
        P1Dif     = YDifferenceFromPrevious                                    # Dif(n-1, n+0)
        N1Dif     = YDifferenceToNext                                          # Dif(n+0, n+1)
        PRatio    = P1Dif / Max(P2P1Dif,0.00001)                               # Dif(n-1, n+0) / Max(Dif(n-2,n-1),0.00001)
        NRatio    = N1Dif / Max(N1N2Dif,0.00001)                               # Dif(n+0, n+1) / Max(Dif(n+1,n+2),0.00001)
        ###
        MC_P1Dif    = Lumadifference(P1C,MC)                                   # Dif(n-1,    MC(n+0))
        MC_N1Dif    = Lumadifference(MC,N1C)                                   # Dif(MC(n+0),n+1)
        MC_PRatio   = MC_P1Dif / Max(P2P1Dif,0.00001)                          # Dif(n-1, MC(n+0)) / Max(Dif(n-2,n-1),0.00001)
        MC_NRatio   = MC_N1Dif / Max(N1N2Dif,0.00001)                          # Dif(MC(n+0), n+1) / Max(Dif(n+1,n+2),0.00001)
        Ratio       = Max(PRatio,NRatio)
        MC_Ratio    = Max(MC_PRatio,MC_NRatio)
        SrcIsBad    = (Ratio >= badthreshold)                                  # True if Source frame bad (bad if either is bad)
        GoodTh      = GoodThreshold > 1.0
                      \ ? GoodThreshold
                      \ : (Ratio - BadThreshold) * GoodThreshold + BadThreshold
        MCIsGood    = (MC_Ratio < GoodTh)                                      # True if MC frame Good (good only if both good)
        UseMC       = SrcIsBad && MCIsGood
        ###
        ScriptDot = "Bad="+String(SrcIsBad) + " GoodFix=" + String(MCIsGood) + " " + (UseMC ? "***" : "")
        Met_Script_S  =
            \ ScriptDot                             +
            \ String(P2P1Dif,   "\nP2P1Dif   = %f") +
            \ String(N1N2Dif,   "\nN1N2Dif   = %f") +
            \ String(P1Dif,     "\nP1Dif     = %f") +
            \ String(N1Dif,     "\nN1Dif     = %f") +
            \ String(MC_P1Dif,  "\nMC_P1Dif  = %f") +
            \ String(MC_N1Dif,  "\nMC_N1Dif  = %f") +
            \ String(Ratio,     "\nRatio     = %f") +
            \ String(MC_Ratio,  "\nMC_Ratio  = %f")
        SHOWSUBS ? Subtitle(Met_Script_S, lsp=0,Font="Courier New",Size=28) : NOP
        SHOWSUBS ? Subtitle(String(GoodTh,    "GoodTh    = %f"),Font="Courier New",Size=28,Align=1)            : NOP

        Return SHOWSUBS ? Last : !UseMC ? Last : ShowDot ? MC.Subtitle("***") : MC
"""

Scriptclip(Met_Script)
return STACK ? StackVertical(Last,(SHOWDOT&&!SHOWSUBS)?ORG.Subtitle("Source"):MC.Subtitle("MC")) : Last
Still no attempt to find best thresholds for this specific clip.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 8th August 2018 at 10:25.
StainlessS is offline   Reply With Quote
Old 14th August 2018, 11:27   #26  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by StainlessS View Post
GreyMouse,
I thought 118 MB for an 8 seconds clip of 720x576@25 was a bit high, seems is HuffYUV RGB.

Assuming source was YUV then suggest next time in VDub2,
Video/Fast Recompress/
Video/Compression/HuffYUV/Configure/RGB Compression Method/ = Convert To YUY2
Video/Compression/HuffYUV/Configure/YUY2 Compression Method/ = Predict Median(Best)

Should be somewhat smaller and without YUV to RGB conversion.
Greymouse, can you post a bigger sample than originally supplied, more than 8 seconds and as per above, but preferably as YV12
and encoded with UT_Video ("ULY0") and minus the audio, can re-encode via AVS and VDub2, as in quote but using UT_Video.

Are all of your sources non interlaced ?

Code:
Avisource("...")
ConvertToYV12(Interlaced=False)
Killaudio
Return Last
Feed into VD2, and UT_Video ULY0, Fast Recompress.

EDIT: Max about 1GB.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 14th August 2018 at 11:31.
StainlessS is offline   Reply With Quote
Old 1st September 2018, 21:21   #27  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
GreyMouse (not online since Aug 4th), here fixer-upper, fixes all seriously bad frames in your source.

Part #1 of 3

DirtBox_MI.Avs
Code:
Function DirtBox_MI(clip c,clip "dc",Float "Th",Float "ThMin",Int "MinLen",Int "MaxLen",Bool "ProcSingles",
        \ bool "Show",Int "Chop",String "SurgeonFile") {
/*
    DirtBox_MI().   [ Take your time saying the name out aloud when in public place ].
        Req:- GScript OR Avs+, Grunt, MvTools2, Masktools2, RemoveGrain, CallCmd, RT_Stats v1.43.
              CallCmd() optional, will auto delete DBase on clip closure if present.
        YUV Only (well whatever MvTools2 supports).

    Args:-
        c,           Source clip.
        dc,          Detection Clip, Default c. Must have same number of frames as Src c, no other requirement.
                     Intent to use eg Zebra Bands to better tune for detection, Used only for primary detect of
                     leftmost and rightmost frames where damage occurs.
        Th,          Bad Ratio Threshold, default 1.3. If eg Cur->Nxt / Max(Prv->Cur,0.001) > Th then Nxt
                     frame is possble 1st of damaged frames (but Cur->Nxt must also be >= ThMin as described below).
        ThMin,       Difference of current frame to next must be at least this to detect Left 'breakup'. default 0.5.
                     (Avoid detection where prev frame is a duplicate and Cur->Nxt diff is very small.)
        MinLen,      Minimum length of damaged sequence to fix, default 1.
        MaxLen,      Maximum length of damaged sequence to fix, default 2 (1 <= MinLen <= MaxLen <= 5).
        ProcSingles, Default True, Process single frame scene as noise. (where detected as both EOS and SOS).
        Show,        Show Metrics, default True.
        Chop,        Show Mode if Show=True,
                       0 Normal
                       1 Left half of frame is fixed, Right original.
                       2 Top half of frame is fixed, Bottom original.
        SurgeonFile, Default "FrameSurgeonCmd.txt". If Non "", then writes a FrameSurgeon() command file to
                     recreate result, so can manually edit the result file and re-render in FrameSurgeon.
                     [part of the Sawbones/FrameSurgeon combo which also requires ClipClop()].
                     If using Multi-instances, each instance should have its own SurgeonFile file.

        Dc clip implemented to assist in detection, where can use eg Zebra() to create a 'tuned to error' diagnostic clip.
        Most damage will likely occur horizontally (in eg VHS tracking gunk), and so we might use Zebra Default Row=true
        to create a vertical set of Zebra bars (same height as clip c), and can use the Zebra args, Threshold, Lo and Hi,
        to tune some of the bars to better reveal where errors occur. If any of the bars seem of no use, then best
        get rid of those bars so as not to 'water down' the detection metrics.
        May be able to detect several kinds of frame corruption, including flash frames, up to five frames catered for.
        Dc clip probably not needed for flash photography flashes.
        To deal with Interlaced clip, can eg SeparateFields  / SelectEven/Odd and handle each separately, then weave them
        back together again afterwards. Is multi-instance capable and so (despite use of global vars) will work just fine.
        Probably better to only seek forwards, as jumping into middle of bad sequence will start detect from jump point.

        Shows Flags where hi-lited,
            E=End Of Scene, S=Start Of Scene, L=Left Intep Src frame, R=Right Interpolate Src frame, *=Interpolated frame.

*/
    c    myName="DirtBox_MI: " # v0.0
    IsAvsPlus=(FindStr(UCase(versionString),"AVISYNTH+")!=0) HasGScript=RT_FunctionExist("GScript")
    HasGRunt =RT_FunctionExist("GScriptClip")                HasMvTools=RT_FunctionExist("MSuper")
    HasMaskTools=RT_FunctionExist("MT_Lutxy")
    HasRemoveGrain=RT_FunctionExist("RemoveGrain")           HasCallCmd = RT_FunctionExist("CallCmd")
    IsAvs26=(VersionNumber>=2.6)
    Assert(IsAvsPlus || HasGScript,RT_String("%sNeed either GScript or AVS+",myName))
    Assert(HasGRunt,RT_String("%sNeed GRunt:-https://forum.doom9.org/showthread.php?t=139337 ",myName))
    Assert(HasMVTools,RT_String("%sNeed MvTools2:-http://forum.doom9.org/showthread.php?t=131033",myName))
    Assert(HasMaskTools,RT_String("%sNeed MaskTools",myName))
    Assert(HasRemoveGrain,RT_String("%sNeed RemoveGrain",myName))
    dc          = Default(dc,c)
    Th          = Default(Th,1.3)
    ThMin       = Default(ThMin,0.5)
    MinLen      = Default(MinLen,1)
    MaxLen      = Default(MaxLen,2)
    ProcSingles = Default(ProcSingles,True)
    Show        = Default(Show, True)
    Chop        = Default(Chop, 0)
    SurgeonFile = Default(SurgeonFile, "FrameSurgeonCmd.txt")
    Assert(dc.Framecount==c.FrameCount,RT_String("%sdc.FrameCount does not match",myName))
    Assert(1 <= MinLen <= MaxLen <= 5,RT_String("%s1 <= MinLen(%d) <= MaxLen(%d) <= 5",myName,MinLen,MaxLen))
    Chop = Show ? Min(Max(Chop,0),2) : 0
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 1st September 2018 at 21:45.
StainlessS is offline   Reply With Quote
Old 1st September 2018, 21:22   #28  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Part #2 of 3 [append to part #1]

Code:
    Func_S="""
        Function Fn@@@(clip c,clip dc,String DB,Float Th,Float ThMin,Int MinLen,Int MaxLen,Bool ProcSingles,
                \ Bool Show,Int Chop,String SurgeonFile) {
            c   i=current_frame                                              # Using i, (avoid confusion with n of Next)
            Status=RT_DBaseGetField(DB,i,0)
            if(Show || Status == 0) {                                        # In here if Show or unvisited
                iPrv = RT_LumaDifference(dc,dc,delta=-1,delta2=0)            # dc(i-1), dc(i)
                iNxt = RT_LumaDifference(dc,dc,delta= 0,delta2=1)            # dc(i),   dc(i+1)
                LftRat = iNxt / Max(iPrv,0.001)
                if(Status==0) {
                    Status=1 IpLen=0 IpIx=0                                  # Default to Src
                    EOSOS = Int(EOSOS@@@.RT_AverageLuma(n=i,w=1,h=1))        # 0=Norm, 1=EOS, 2=SOS, 3=EOS & SOS
                    Proc = EOSOS!=1||(ProcSingles&&Int(EOSOS@@@.RT_AverageLuma(n=i+1,w=1,h=1))==3)?1:0
                    if (Proc==1 && iNxt >= ThMin && LftRat >= Th) { # Got Left suspect breakup
                        TstLen=0
                        ETerm=Min(i+MaxLen,FrameCount-3)                     # Last possible INTERPOLATED frame
                        for(j=i+1,ETerm) {                                   # Determine unknown length (checking for EOS)
                            if(RT_DBaseGetField(DB,j,0)<=1) {                # Unknown or Src
                                ES=Int(EOSOS@@@.RT_AverageLuma(n=j,w=1,h=1))==1 # Is EOS ?
                                if(ES) {                                     # EOS
                                    j = Eterm                                # Break
                                } Else {
                                    TstLen=TstLen+1
                                }
                            } Else { j = Eterm }                             # Break
                        }
                        if(TstLen>=MinLen) {
                            CL_d = 0 # Init to Int, ie not yet tested
                            ETerm = i + TstLen
                            IpLen=0 BestMax=256.0
                            for(j=i+MinLen,ETerm) {
                                dcP_d = RT_LumaDifference(dc,dc,n=j,n2=j,delta=0,delta2=1) # dc(j  ),dc(j+1)
                                dcN_d = RT_LumaDifference(dc,dc,n=j,n2=j,delta=1,delta2=2) # dc(j+1),dc(j+2)
                                RgtRat = dcP_d / Max(dcN_d,0.001)
                                if(dcP_d >= ThMin && RgtRat >= Th) {
                                    # We have possible bad frames as tested via DC detection clip (at least MinLen).
                                    # i = Left Interp Src frame. j = possible Right Interp Src frame - 1.
                                    BadLen = j - i  # Suspect badlen
                                    ML_c = BadLen==1?M1@@@:BadLen==2?M21@@@:BadLen==3?M31@@@:BadLen==4?M41@@@:M51@@@
                                    # Now test whether 1st Interp better matches 1st InterpSrc (NOT using dc clip)
                                    CL_d=CL_d.IsInt ? RT_LumaDifference(c,c,n=i,n2=i,delta=0,delta2=1): CL_d    # c(i),c(i+1)
                                    ML_d=RT_Lumadifference(c,ML_c,n=i,n2=i,delta=0,delta2=1) # c(i),ML_c(i+1)
                                    if(ML_d < CL_d && ML_d < BestMax) {
                                        MR_c = BadLen==1?M1@@@:BadLen==2?M22@@@:BadLen==3?M33@@@:BadLen==4?M44@@@:M55@@@
                                        # Now test whether last Interp better matches Last InterpSrc (NOT using dc clip)
                                        CR_d = RT_LumaDifference(c,c,   n=j,n2=j,delta=0,delta2=1) # c(j),   c(j+1)
                                        MR_d = RT_Lumadifference(MR_c,c,n=j,n2=j,delta=0,delta2=1) # MR_c(j),c(j+1)
                                        if(MR_d < CR_d && MR_d < BesTMax)  {
                                            BestMax=Max(ML_d,MR_d) IpLen=BadLen
                                        }
                                    }
                                }
                            } # End, for j
                            if(IpLen>0) {
                                Status=2                                 # Left Interp Src
                                RT_DBaseSet(DB,i,Status,EOSOS,IpLen,0)
                                BadStart=IpLen==1?4:IpLen==2?5:IpLen==3?7:IpLen==4?10:14
                                for(k=0,IpLen-1) {
                                    EOSOS = Int(EOSOS@@@.RT_AverageLuma(n=i+1+k,w=1,h=1))   # 0=Norm, 1=EOS, 2=SOS, 3=EOS & SOS
                                    RT_DBaseSet(DB,i+1+k,BadStart+k,EOSOS,IpLen,k+1)
                                }
                                EOSOS = Int(EOSOS@@@.RT_AverageLuma(n=i+1+k,w=1,h=1))   # 0=Norm, 1=EOS, 2=SOS, 3=EOS & SOS
                                RT_DBaseSet(DB,i+1+IpLen,3,EOSOS,IpLen,0)     # Right Interp Src
                                if(SurgeonFile!="") { RT_WriteFile(SurgeonFile,"I%d %d",IpLen,i+1,Append=True) }
                            }
                        } # End if TstLen >= MinLen
                    }
                    (Status == 1) ? RT_DBaseSet(DB,i,Status,EOSOS,IpLen,IpIx) : NOP   # Defaulted Src
                } # End if Status == 0
            } # End, if(Show || Status == 0)
            Assert(1 <= Status <= 18,RT_String("Error bad Status=%d",Status))
            Status<=3?Last
                \ : Status <= 9 ? (Status==4?M1@@@:Status==5?M21@@@:Status==6?M22@@@:Status==7?M31@@@:Status==8?M32@@@:M33@@@)
                \ : Status <= 13 ? (Status==10?M41@@@:Status==11?M42@@@:Status==12?M43@@@:M44@@@)
                \ : Status == 14 ? M51@@@ : Status==15 ? M52@@@ : Status==16 ? M53@@@ : Status==17 ? M54@@@ : M55@@@
            if(Show) {
                if(Chop==1)       { W=Last.Width/8*4  StackHorizontal(Last.Crop(0,0,W,0),c.Crop(Last.Width-W,0,0,0)) }
                Else if (Chop==2) { H=Last.Height/8*4 StackVertical(Last.Crop(0,0,0,H),c.Crop(0,Last.Height-H,0,0)) }
                HiLite=45 LoLite=76
                EOSOS = RT_DBaseGetField(DB,i,1)
                EOS_C = RT_BitTST(EOSOS,0) ? Hilite : LoLite
                SOS_C = RT_BitTST(EOSOS,1) ? Hilite : LoLite
                if(Status == 1) {
                    RT_Subtitle("%d] \a%cE\a%cS\aLLR*\a- D(n-1)=%.3f : D(n+1)=%.3f\nLftRat=%.3f",i,EOS_C,SOS_C,iPrv,iNxt,LftRat)
                } Else {
                    IpLen = RT_DBaseGetField(DB,i,2)
                    IpIx  = RT_DBaseGetField(DB,i,3)
                    if(Status==2) { # Left InterpSrc
                        Pdf = RT_LumaDifference(dc,dc,n=i+IpLen+1,n2=i+IpLen+1,delta=-1,delta2=0)
                        Ndf = RT_LumaDifference(dc,dc,n=i+IpLen+1,n2=i+IpLen+1,delta=0,delta2=1)
                        RgtRat=Pdf/Max(Ndf,0.001)
                        RT_Subtitle("%d] \a%cE\a%cS\a-L\aLR*\a- D(n-1)=%.3f : D(n+1)=%.3f\nLftRat=%.3f (RgtRat=%.3f)",
                            \ i,EOS_C,SOS_C,iPrv,iNxt,LftRat,RgtRat)
                    } Else if(Status==3) { # Right InterpSrc
                        RgtRat = iPrv / Max(iNxt,0.001)
                        Pdf = RT_LumaDifference(dc,dc,n=i-IpLen-1,n2=i-IpLen-1,delta=0,delta2=-1)
                        Ndf = RT_LumaDifference(dc,dc,n=i-IpLen-1,n2=i-IpLen-1,delta=0,delta2=1)
                        LftRat=Ndf/Max(Pdf,0.001)
                        RT_Subtitle("%d] \a%cE\a%cS\aL\a-R\aL*\a- D(n-1)=%.3f : D(n+1)=%.3f\nRgtRat=%.3f (LftRat=%.3f)",
                            \ i,EOS_C,SOS_C,iPrv,iNxt,RgtRat,LftRat)
                    } Else {
                        RT_Subtitle("%d] \a%cE\a%cS\aLLR\a-*\a*\a- [%d/%d] D(n-1)=%.3f : D(n+1)=%.3f",
                            \ i,EOS_C,SOS_C,IpIx,IpLen,iPrv,iNxt)
                    }
                }
            }
            Return Last
        }
        if(SurgeonFile!="") {
            SurgeonFile=RT_GetFullPathName(SurgeonFile)
            RT_FileDelete(SurgeonFile)
            RT_WriteFile(SurgeonFile,"###\n# FrameSurgeon() Command file [ Generated by DirtBox() ]\n###\n\n")
        }
        DB=RT_GetFullPathName("~@@@_"+RT_LocalTimeString+".DB")    RT_DBaseAlloc(DB,FrameCount,"iiii")
        /*  DBase Fields:-
            0) Status,
                0 = UnKnown
                1 = Src
                2 = Left Interp Src
                3 = Right Interp Src
                4 = Interp[1/1]
                5 = Interp[1/2]  :  6 = Interp[2/2]
                7 = Interp[1/3]  : 8 = Interp[2/3] : 9 = Interp[3/3]
                10 = Inter[(1/4) : 11 = Inter[(2/4) : 12 = Inter[(3/4) : 13 = Inter[(4/4)
                14 = Inter[(1/5) : 15 = Inter[(2/5) : 16 = Inter[(3/5) : 17 = Inter[(4/5) : 18 = Inter[(5/5)
            1)  EOS/SOS
                0 Normal Source
                1 EOS (End Of Scene)
                2 SOS
                3 SOS and EOS (ie single frame scene)
            2)  InperpLen 0 Src, or 1 to 5
            3)  InterpIx, 1 to InterpLen if if Not Src.
        */
        RT_DBaseSet(DB,0,            1,2,0,0)   # Set SOS for 1st frame
        RT_DBaseSet(DB,FrameCount-1, 1,1,0,0)   # Set EOS for last frame
        Prefilt   = c.RemoveGrain(22)
        Super     = c.MSuper(hpad=16,vpad=16,levels=1,sharp=1,rfilter=4)               # One level is enough for MRecalculate
        Superfilt = Prefilt.MSuper(hpad=16,vpad=16,sharp=1,rfilter=4)                  # All levels for MAnalyse
        bv        = Superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=2)# DELTA 2, (distance between interpolate source frames)
        fv        = Superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=2)
        bv        = Super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
        fv        = Super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
        Global M1@@@=c.MFlowInter(Super,bv,fv,time=50.0,ml=200).SelectEvery(1,-1)     # n interp from src n-1 & n+1 @ 50.0% (n-1 shifted to n)
        #
        bv        = Superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=3)# DELTA 3
        fv        = Superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=3)
        bv        = Super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
        fv        = Super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
        Global M21@@@=c.MFlowInter(Super,bv,fv,time=100.0/3,ml=200).SelectEvery(1,-1)  # n interp from src n-1 & n+2 @ 33.33% (n-1 shifted to n)
        Global M22@@@=c.MFlowInter(Super,bv,fv,time=200.0/3,ml=200).SelectEvery(1,-2)  # n interp from src n-2 & n+1 @ 66.67% (n-2 shifted to n)
        #
        bv        = Superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=4)# DELTA 4
        fv        = Superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=4)
        bv        = Super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
        fv        = Super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
        Global M31@@@=c.MFlowInter(Super,bv,fv,time=25.0,ml=200).SelectEvery(1,-1)    # n interp from src n-1 & n+3 @ 25.0% (n-1 shifted to n)
        Global M32@@@=c.MFlowInter(Super,bv,fv,time=50.0,ml=200).SelectEvery(1,-2)    # n interp from src n-2 & n+2 @ 50.0% (n-2 shifted to n)
        Global M33@@@=c.MFlowInter(Super,bv,fv,time=75.0,ml=200).SelectEvery(1,-3)    # n interp from src n-3 & n+1 @ 75.0% (n-3 shifted to n)
        #
        bv        = Superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=5)# DELTA 5
        fv        = Superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=5)
        bv        = Super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
        fv        = Super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
        Global M41@@@=c.MFlowInter(Super,bv,fv,time=20.0,ml=200).SelectEvery(1,-1)    # n interp from src n-1 & n+4 @ 20.0% (n-1 shifted to n)
        Global M42@@@=c.MFlowInter(Super,bv,fv,time=40.0,ml=200).SelectEvery(1,-2)    # n interp from src n-2 & n+3 @ 40.0% (n-2 shifted to n)
        Global M43@@@=c.MFlowInter(Super,bv,fv,time=60.0,ml=200).SelectEvery(1,-3)    # n interp from src n-3 & n+2 @ 60.0% (n-3 shifted to n)
        Global M44@@@=c.MFlowInter(Super,bv,fv,time=80.0,ml=200).SelectEvery(1,-4)    # n interp from src n-4 & n+1 @ 80.0% (n-4 shifted to n)
        #
        bv        = Superfilt.MAnalyse(isb=true, blksize=16,overlap=4,search=3,delta=6)# DELTA 6
        fv        = Superfilt.MAnalyse(isb=false,blksize=16,overlap=4,search=3,delta=6)
        bv        = Super.MRecalculate(bv,blksize=8,overlap=2,thSAD=100)
        fv        = Super.MRecalculate(fv,blksize=8,overlap=2,thSAD=100)
        Global M51@@@=c.MFlowInter(Super,bv,fv,time=100.0/6,ml=200).SelectEvery(1,-1)  # n interp from src n-1 & n+5 @ 16.67% (n-1 shifted to n)
        Global M52@@@=c.MFlowInter(Super,bv,fv,time=200.0/6,ml=200).SelectEvery(1,-2)  # n interp from src n-2 & n+4 @ 33.33% (n-2 shifted to n)
        Global M53@@@=c.MFlowInter(Super,bv,fv,time=300.0/6,ml=200).SelectEvery(1,-3)  # n inter from src n-3 & n+3 @50.00% (n-3 shifted to n)
        Global M54@@@=c.MFlowInter(Super,bv,fv,time=400.0/6,ml=200).SelectEvery(1,-4)  # n inter from src n-4 & n+2 @ 66.67% (n-4 shifted to n)
        Global M55@@@=c.MFlowInter(Super,bv,fv,time=500.0/6,ml=200).SelectEvery(1,-5)  # n inter from src n-5 & n+1 @ 83.33% (n-4 shifted to n)
        #
        SupEos    = c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
        BvEos     = SupEos.MAnalyse(isb=True,  delta=1,blksize=16)
        FvSos     = SupEos.MAnalyse(isb=False, delta=1,blksize=16)
        EOS = c.MSCDetection(BvEos,thSCD1=400,thSCD2=130).Crop(0,0,16,16) EOS=(IsAvs26)?EOS.ConvertToY8:EOS.ConvertToYV12
        SOS = c.MSCDetection(FvSos,thSCD1=400,thSCD2=130).Crop(0,0,16,16) SOS=(IsAvs26)?SOS.ConvertToY8:SOS.ConvertToYV12
        Global EOSOS@@@ = MT_Lutxy(EOS,SOS,yexpr="y 0 == x 0 == 0 1 ? x 0 == 2 3 ? ?",u=-128,v=-128)
        ARGS = "dc,DB,Th,ThMin,MinLen,MaxLen,ProcSingles,Show,Chop,SurgeonFile"
        ScriptLine="Fn@@@(last, "+ARGS+")"
        c.GScriptClip(ScriptLine, local=true, args=ARGS)
        Return Last
    """
    GIFunc="DirtBox_MI"                # Function Name, Supply unique name for your multi-instance function.
    GIName=GIFunc+"_InstanceNumber"    # Name of the Instance number Global
    RT_IncrGlobal(GIName)              # Increment Instance Global (init to 1 if not already exists)
    GID = GIFunc + "_" + String(Eval(GIName))
    InstS = RT_StrReplace(Func_S,"@@@","_"+GID)
#   RT_WriteFile("DEBUG_"+GID+".TXT","%s",InstS)
    HasGScript ? GScript(InstS) : Eval(InstS)   # Use GSCript if installed (loaded plugs override builtin)
    # if CallCmd available, Auto delete DBase file on clip closure.
    HasCallCmd?CallCmd(close=RT_String("""CMD /C chcp 1252 && del "%s" """,DB), hide=true, Synchronous=7):NOP
    Return Last
}
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 1st September 2018 at 21:45.
StainlessS is offline   Reply With Quote
Old 1st September 2018, 21:22   #29  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Part #3 of 3 (client script)

Code:
ORG=AVISource("D:\GreyMouse.avi").ConvertToYV12

############    Config   ################
TH          = 1.3    # If either DC LRat or RRat greater or equal this then frame is bad.
THMIN       = 0.5
MINLEN      = 1
MAXLEN      = 2
PROCSINGLES = True # Process single frame scene/cut
SHOW        = True
CHOP        = 0    # 0)=fix whole frame, 1) Fix only Left half of frame (Only when Show=true)
STACK       = True
USE_DC      = True # Use Zebra Bars as DC detect clip
###
DC_PIXELS    = 16  # Zebra Bar width, multiple of 4 (Used only if STACK and USE_DC, else 4)
DC_SKIPBARS  = 1   # Skip YPlaneMin Bars (2 also skips YPLaneMax bar)
DC_THRESHOLD = 0   # As Zebra Default
DC_LO        = 128 # As Zebra Default
DC_HI        = 255 # As Zebra Default
#########################################
ORG

# Dont use YPlaneMin Bar (on Greymouse clip is always near black, watering down metrics).
# Zebra:- https://forum.doom9.org/showthread.php?t=167663
DC=ORG.Zebra(pix=STACK&&USE_DC?DC_PIXELS:4,Threshold=DC_THRESHOLD,lo=DC_Lo,hi=DC_HI).Crop(DC_SKIPBARS*DC_PIXELS,0,0,0)
SEP=DC.BlankClip(Width=4,Color=$FF00FF)
Clean = Last.DirtBox_MI(dc=USE_DC?DC:ORG,Th=TH,ThMin=THMIN,MinLen=MINLEN,MaxLen=MAXLEN,ProcSingles=PROCSINGLES,Show=SHOW,Chop=CHOP)
Return (STACK && USE_DC)
    \ ? StackHorizontal(Clean,SEP,DC,SEP,ORG.RT_Subtitle("BadSrc"))
    \ : STACK ? StackHorizontal(Clean,SEP,ORG.RT_Subtitle("BadSrc"))
    \ : Clean
EDIT: If set MaxLen to 4, then luckily fixes seq at 51, where jumping pretty bad, sort of de-shakes it.
EDIT: Not too sprightly, getting ~20FPS on Core Duo 2.4Ghz.

EDIT:
Quote:
Originally Posted by greymouse View Post
the noise I refer to are on frames
71,88,94,116,167
Actually, 167 should be 166 and 167, 2 frame bad pair.
Results in FrameSurgeonCmd.txt
Code:
###
# FrameSurgeon() Command file [ Generated by DirtBox() ]
###

I1 71
I1 88
I1 94
I1 116
I2 166 # EDIT: I2 = 2 bad frames starting at 166




EDIT: On 2nd thoughts, probably will not work OK with flash frames, as will likely be detected as End Of Scene / Start of Scene
and screw things up. I'll try to figure out what the rules are.

EDIT: See new thread and updated script here DirtBox_MI_v0.01 :- https://forum.doom9.org/showthread.php?t=175708
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 9th November 2022 at 18:49.
StainlessS is offline   Reply With Quote
Old 5th September 2018, 18:27   #30  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
John, here your posted script converted to Script function, think it works exactly the same, but fixed the WriteFile logic.

Also note, I've made available arg AND, so can use either AND or OR logic.
You might want to change defaults or something. (NOTE, Metrics=True, will output metrics, otherwise, Filename = "" will output the fixed clip, else frame numbers)

DirtyJohn.avs
Code:
Function DirtyJohn(clip c,Float "Th",Float "ThMin",Bool "Metrics",Bool "ShowDot",String "FileName",Bool "AND") {
    c
    Th          = Default(th,1.3)
    ThMin       = Default(ThMin,0.5)
    Metrics     = Default(Metrics,True)
    ShowDot     = Default(ShowDot,False)
    FileName    = Default(FileName,"")
    And         = Default(And,False)           # NOTE, Default is 'either bad' for badframe, ie OR logic
    ###
    Even        = c.SeparateFields().SelectEven()
    Super_Even  = ShowDot ? Even.Subtitle("***").MSuper(pel=2) : Even.MSuper(pel=2)
    vfe         = MAnalyse(Super_Even,truemotion=true,isb=false,delta=2)
    vbe         = MAnalyse(Super_Even,truemotion=true,isb=true,delta=2)
    Filldrops_E = MFlowInter(Even,Super_Even,vbe,vfe,Time=50)
    #
    Odd         = c.SeparateFields().SelectOdd()
    Super_Odd   = ShowDot ? Odd.Subtitle("***").MSuper(pel=2) : Odd.MSuper(pel=2)
    vfo         = MAnalyse(Super_Odd,truemotion=true,isb=false,delta=2)
    vbo         = MAnalyse(Super_Odd,truemotion=true,isb=true,delta=2)
    Filldrops_O = MFlowInter(Odd,Super_Odd,vbo,vfo,Time=50)
    ###
    Script_Init= """
        PrvDif    = YDifferenceFromPrevious
        PPrvDif   = YDifferenceFromPrevious(Selectevery(1, -1))
        PrvRatio  = PrvDif / Max(PPrvDif,0.001)
        NxtDif    = YDifferenceToNext
        NNxtDif   = YDifferenceToNext(Selectevery(1, 1))
        NxtRatio  = NxtDif / Max(NNxtDif,0.001)
        PBad      = PrvDif > ThMin && PrvRatio > Th
        NBad      = NxtDif > ThMin && NxtRatio > Th
    """
    Bad_Logic = (AND) ? "BadFrame  = PBad && NBad" : "BadFrame  = PBad || NBad"
    Script_Base = Script_Init + Bad_Logic + Chr(10)
    Script_Met  = """
        S1=String(current_frame,"%.0f] ")
        S2=BadFrame ? "***\n" : "\n"
        S3=String(PrvDif  ,"PrevDiff = %f") + String(NxtDif,  " : NextDiff = %f\n")
        S4=String(PrvRatio,"PrevRatio= %f") + String(NxtRatio," : NextRatio= %f")
        Return Subtitle(S1+S2+S3+S4,lsp=0,font="CourierNew",size=20)
    """
    Script_Wr   = Script_Base+"BadFrame"
    Script_Cond = Script_Base+"BadFrame ? 1 : 0"
    ###
    Replacement_Clip = Interleave(Filldrops_E,Filldrops_O).Weave
    Return
        \   (Metrics)      ? ScriptClip(Script_Base+Script_Met)
        \ : (FileName!="") ? WriteFileIf(FileName,Script_Wr,"Current_frame",Append=False)
        \ :                ConditionalSelect(Script_Cond,c,Replacement_Clip.SelectEvery(1,-1))
}
DirtyJohn_Client.avs
Code:
############    Config   ################
VideoFile  = "GreyMouse.avi"
INTERLACED = FALSE     # You decide
TH         = 1.2       # Set METRICS=TRUE to determine best value
THMIN      = 0.5       # 0.5,
SHOWDOT    = True      # TRUE will add "***" to each replacment frame (for troubleshooting)
METRICS    = True      # TRUE will show Metrics ONLY (i.e., TRUE overrides all other selctions)
FILENAME   = ""        # Set to name and location where you want the frame numbers stored, If "" then fix clip instead of Write.
AND        = False     # True uses && logic instead of || logic in detector.
STACK      = True      # Return Stacked Window
##########################################
AVISource("D:\"+VideoFile).ConvertToYV12(Interlaced=INTERLACED)#.killaudio()
ORG=Last
DirtyJohn(Th=Th,ThMin=ThMin,Metrics=Metrics,ShowDot=ShowDot,FileName=FileName,And=AND)

Return STACK ? StackVertical(Last,ORG) : Last
EDIT: Oops, AND logic was OR for both AND=True and AND=False, fixed.
EDIT: Added STACK setting to client

EDIT: Can call with ThMin=0.0 if not required, but almost certainly better having it above 0.0
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 6th September 2018 at 01:53.
StainlessS is offline   Reply With Quote
Old 5th September 2018, 19:59   #31  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,695
Thanks for giving me the "DirtyJohn" moniker.

I don't have any current project on which to use it, but replacing bad frames is such a common problem that I'm sure I'll get around to testing the in the near future.

Thansk!!
johnmeyer is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 23:58.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.