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.

Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se

 

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

Reply
 
Thread Tools Search this Thread Display Modes
Old 3rd June 2025, 00:59   #521  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
SecurityCamExtractMotion.AVS [Part 2 of 2 - Glue them together]

Code:
    FuncS="""
        Function Fn@@@(clip clp,Float th,Float dth,int BlkW,int BlkH,int x,int y,int w,int h,
                \ Float CW,bool AltScan,bool CI,int Matrix,int OLapX,int OLapY,Int Lag,
                \ clip dclip,bool ShowMiss,clip MissMrk,clip HitMrk,clip HoldMrk,clip MissMsk,clip HitMsk,clip HoldMsk,bool Verbose,
                \ String Fmt,String vFmt,String Prefix,string OutCS,
                \ String KeepFN,String DropFN,String DupeFN,String HoldFN,
                \ bool Hide) {
            clp
            n=current_frame
            if(PrevN@@@ != n) {
                # Always check against n-1 for DROP and KEEP
                cmp = n-1
                if(PrevN@@@!=cmp) {                                                             # Reset (jump about or frame 0)
                    cmp = max(n-1,0)
                    Global RecentKeep@@@=cmp                                                    # Most recent KEEP frame number
                    Global PrevMat@@@=1                                                         # Prev vist match type DROP
                    Global CurrXOff@@@=-6666                                                    # Invalid Coords of current KEEP or HOLD
                    Global HoldXOff@@@=-6666                                                    # Invalid Coords of Most recent KEEP or HOLD
                }
                dif=RT_FrameMovement(dclip,dclip,n,cmp,CW,x,y,w,h,x,y,altscan,CI,Matrix,BlkW,BlkH,OLapX,OLApY,Th,Prefix)
                mat=(dif>dth) ? (dif<th?1:2) : (n==0) ? 2 : 0   # 0=DUPE : 1=DROP : 2=KEEP : 3=HOLD(Not used here)

                if(Lag>1 && mat==1 && cmp-RecentKeep@@@>=1) {
                    # If DROP will be converted to HOLD, then dont compare LAG frame
                    if(MOTD_XOff<HoldXOff@@@-BlkW || MOTD_XOff>HoldXOff@@@+BlkW || MOTD_YOff<HoldYOff@@@-BlkH || MOTD_YOff>HoldYOff@@@+BlkH) {
                        # Limit RecentKeep@@@ usage to inital lag,
                        # avoid small remnants of objects moving out of frame from being used in later compare
                        cmp = (n-RecentKeep@@@==2) ? RecentKeep@@@ : max(RecentKeep@@@+1,n-Lag)
                        dif=RT_FrameMovement(dclip,dclip,n,cmp,CW,x,y,w,h,x,y,altscan,CI,Matrix,BlkW,BlkH,OLapX,OLApY,Th,Prefix)
                        mat=(dif>dth) ? (dif<th?1:2) : 0
                    }
                }

                if(mat==0) {        # Dupe
                    (DupeFN!="") ? RT_WriteFile(DupeFN,"%d",n,append=true) : NOP
                } else if(mat==1) { # Drop
                    if(HoldXOff@@@ >= 0) {    # HOLD Disabled ? (will quite often be disabled)
                        if(   MOTD_XOff>=HoldXOff@@@-BlkW && MOTD_XOff<=HoldXOff@@@+BlkW &&
                            \ MOTD_YOff>=HoldYOff@@@-BlkH && MOTD_YOff<=HoldYOff@@@+BlkH) {
                            mat=3 # Convert to HOLD
                            (HoldFN!="") ? RT_WriteFile(HoldFN,"%d",n,append=true) : NOP
                        } else { # Wandered too far from most recent hold coords, Disable HOLD locking
                            Global HoldXOff@@@ = -6666
                        }
                    }
                    (DropFN!="") ? RT_WriteFile(DropFN,"%d",n,append=true) : NOP
                    Global PrevMat@@@ = 1
                } else {         # Keep
                    if(n!=0 || PrevN@@@==-6666) {   # Block nasty VDub Analysis pass writing 0 on re-seek to 0 at end
                        (KeepFN!="") ? RT_WriteFile(KeepFN,"%d",n,append=true) : NOP
                        (HoldFN!="") ? RT_WriteFile(HoldFN,"%d",n,append=true) : NOP
                    }
                    Global PrevMat@@@    = 2
                    Global RecentKeep@@@ = n
                    Global HoldXOff@@@   = MOTD_XOff        # From Locals set by RT_FrameMovement()
                    Global HoldYOff@@@   = MOTD_YOff
                }

                if(!Hide) {
                    Global CmpFrm@@@            = cmp
                    Global Mat@@@               = mat
                    Global Dif@@@               = dif
                    Global CurrXOff@@@          = MOTD_XOff
                    Global CurrYOff@@@          = MOTD_YOff
                    if(mat==0) {
                        Global nDupe@@@         = nDupe@@@ + 1
                        Global DupeMax@@@       = max(dif,DupeMax@@@)
                    } else if(mat==1) {
                        Global nDrop@@@         = nDrop@@@ + 1
                        Global KeepMin@@@       = 255.0
                        Global DropMax@@@       = max(dif,DropMax@@@)
                    } else if(mat==2) {
                        Global nKeep@@@         = nKeep@@@ + 1
                        Global KeepMin@@@       = min(dif,KeepMin@@@)
                        Global DropMax@@@       = 0.0
                        Global nHold@@@         = nHold@@@ + 1
                    } else {
                        Global nHold@@@         = nHold@@@ + 1
                    }
                    if(VerBose) {
                        Global TotalBlks@@@     = MOTD_TotalBlks
                        Global BlkAveDf@@@      = MOTD_BlkAveDf
                        Global nAboveTh@@@      = MOTD_nAboveTh
                        Global PercAboveTh@@@   = MOTD_PercAboveTh
                    }
                }
            }

            if(!Hide) {
                mat = Mat@@@
                z=RT_Ord("-123",mat+1)
                RT_SubTitle(Fmt,n,(mat==0)?"DUPE":(mat==1)?"DROP":(mat==2)?"KEEP":"HOLD",
                    \ z,Dif@@@,max(n-CmpFrm@@@,0),CmpFrm@@@,
                    \ nKeep@@@, nKeep@@@*100.0 / (n+1.0),KeepMin@@@,
                    \ nDrop@@@, nDrop@@@*100.0 / (n+1.0),DropMax@@@,
                    \ nDupe@@@, nDupe@@@*100.0 / (n+1.0),DupeMax@@@,
                    \ nHold@@@, nHold@@@*100.0 / (n+1.0),RecentKeep@@@
                    \ )
                Verbose ? RT_Subtitle(vFmt,TotalBlks@@@,BlkAveDf@@@,nAboveTh@@@,PercAboveTh@@@,th,dth,CW,(altScan)?84:70,BlkW,BlkH,OLapX,OLapY,Align=1) : NOP
                if((mat>0 && (mat!=1||ShowMiss)) && n>0) {
                    Overlay(mat==1?MissMrk:mat==2?HitMrk:HoldMrk,x=x+CurrXOff@@@,y=y+CurrYOff@@@,
                        \ Mask=mat==1?MissMsk:mat==2?HitMsk:HoldMsk,Mode="Blend",output=OutCS)
                }
            }
            Global PrevN@@@ = n
            return Last
        }
        #######################################
        # Unique Global Variables Initialization
        #######################################
        Global PrevN@@@=-6666                                                                   # Previously visited Frame Number
        Global RecentKeep@@@=0                                                                  # Most recent KEEP frame number
        Global PrevMat@@@=1                                                                     # Prev vist match type (1,2,only, not DUPE)
        Global HoldXOff@@@=-6666                                                                # Coords of Most recent KEEP or HOLD
        Global HoldYOff@@@=-6666
        # Required for Metrics ONLY
        Global CmpFrm@@@=0                                                                      # Current comparison frame for decision
        Global Mat@@@=0                                                                         # Current visit Match type
        Global Dif@@@=0.0                                                                       # Current visit dif
        Global TotalBlks@@@=0
        Global BlkAveDf@@@=0.0
        Global nAboveTh@@@=0
        Global PercAboveTh@@@=0.0
        Global CurrXOff@@@=-6666                                                                # Current Coords
        Global CurrYOff@@@=-6666
        Global nKeep@@@=0       Global nDrop@@@=0       Global nDupe@@@=0    Global nHold@@@=0  # Counts
        Global KeepMin@@@=0.0   Global DropMax@@@=0.0   Global DupeMax@@@=0.0                   # Dif limits
        Prefix="MOTD_"
        #######################################
        # Unique Runtime Call, GScriptClip must be a one-liner:
        #######################################
        ARGS = "th,dth,BlkW,BlkH,x,y,w,h,CW,AltScan,CI,Matrix,OLapX,OLapY,Lag," +
            \  "dclip,ShowMiss,MissMrk,HitMrk,HoldMrk,MissMsk,HitMsk,HoldMsk,Verbose,Fmt,vFmt,Prefix,OutCS," +
            \  "KeepFN,DropFN,DupeFN,HoldFN,Hide"
        Last.GScriptClip("Fn@@@(last, "+ARGS+")", local=true, args=ARGS)
    """
    #######################################
    # Unique Identifier Definition
    #######################################
    GIFunc ="MOTD"                                  # 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(FuncS,"@@@","_"+GID)
#   RT_WriteFile("DEBUG_"+GID+".TXT","%s",InstS)    # Resulting Instance script, for debug perusal.
    IsAvsPlus?Eval(InstS):HasGScript?GScript(InstS):Assert(False,RT_String("%sNeed either GScript or AVS+",myName))
    Return KillAudio
}


Function Hit_Marker(int W, Int H, Bool "Hit", Int "BW", Int "BH",Int "PW",Int "PH",Bool "YV12",Bool "Mod2") {
/*
    Req RT_Stats & mt_tools v2.     http://forum.doom9.org/showthread.php?t=174527
    Creates a marker mask WxH, for use with Overlay as Mask arg.
    Intended for use via some kind of detector to show detection Hit, or Miss.
    Returns Single frame clip with null audio, the marker top left hand side is aligned to 0,0.
            Default return clip colorspace is Y8 for Avisynth v2.6 and above, or YV12 if defunct version.
    Args:-
        W,H,    Size of marker mask (can be odd), return clip dimensions are rounded up to next multiple of 2 if YV12 return clip.
                  Bare minimum usable size is 4x4 with defaulted BW, BH, PW, PH.
        HIT,    Default False, returns marker as angled corners (Thickness set by BW and BH).
                        True,  returns marker as angled corners + outer perimeter where perimeter thickness set by PW and PH.
        BW,     Default Max(W/8,1). Horizontal thickness of the marker corners.
        BH,     Default Max(H/8,1). Vertical   thickness of the marker corners.
        PW,     Default Max(BW/8,1). Horizontal thickness of the vertical perimeter.
        PH,     Default Max(BH/8,1). Vertical thickness of the horizontal perimeter.
        YV12,   Default False if Avisynth version 2.6 or greater(Y8), else true(YV12). Selects return clip colorspace.
        Mod2,   Default True. If Y8 then round odd dimensions up modulo 2 (the mask is still WxH).

    Example:-
        Import("Hit_Marker.avs")
        WW=128  HH=WW   HIT=True
        BlankClip
        Yell=Last.BlankClip(Width=WW,Height=HH,Length=1,Color=$FFFF00)
        Return OverLay(Yell,x=(Width-WW)/2,y=(Height-HH)/2,mask=Hit_Marker(WW,HH,HIT))
*/
    Hit=Default(hit,False)                    BW=Max(Default(BW,W/8),1)   BH=Max(Default(BH,H/8),1)
    BW2=(W>4)?BW*2:BW                         BH2=(H>4)?BH*2:BH
    PW=Max(Default(PW,BW/8),1)                PH=Max(Default(PH,BH/8),1)  is26 = VersionNumber>=2.6
    YV12=(!is26) ? True : Default(YV12,False) Mod2=Default(Mod2,True)     Mod = (YV12||Mod2) ? 2 : 1
    CanvasW=(W+Mod-1)/Mod*Mod                 CanvasH=(H+Mod-1)/Mod*Mod
    Rpn= RT_String("x %d < x %d >= | y %d < | y %d >= | x %d < x %d >= | & y %d < y %d >= | & ",BW,W-BW,BH,H-BH,BW2,W-BW2,BH2,H-BH2)
    Rpn= (Hit) ? Rpn + RT_String("x %d < x %d >= | y %d < | y %d >= | | ",PW,W-PW,PH,H-PH) : Rpn
    Rpn= Rpn + RT_String("x %d < y %d < & & 255 0 ?",W,H)
    Blankclip(width=CanvasW,height=CanvasH,Length=1,pixel_type=YV12?"YV12":"Y8").Killaudio
    return mt_lutspa(relative = false,yExpr=Rpn, chroma = "-128")
}


Function MaxContrast(clip c,int "Samples",Float "Ignore",Float "Gamma",Bool "Show") {   # PC Levels Max Contrast
    c       Gamma=Float(Default(Gamma,1.0))     Show=Default(Show,False)
    Eval(RT_QueryLumaMinMax(Samples=Samples,Ignore=Ignore,X=4,Y=4,W=-4,H=-4,Debug=Show))
    Doit = (QLMMMin!=0 || QLMMMax != 255)
    RT_DebugF("Levels(%3d,%.2f,%3d,%d,%d,Coring=False)",QLMMMin,Gamma,QLMMMax,0,255,name="MaxContrast: ")
    (Doit && Show) ? RT_Subtitle("%sLevels(%3d,%.2f,%3d,%d,%d,Coring=False)","MaxContrast: ",QLMMMin,Gamma,QLMMMax,0,255)  : NOP
    (Doit) ? Levels(QLMMMin,Gamma,QLMMMax,0,255,Coring=False) : NOP
    Return Last
}

Function SelectFrames(clip c,String Fn,bool "Show",bool "Showtime",bool "Reject") {
    c   Show=Default(Show,False)    ShowTime=Default(ShowTime,False) Reject=Default(Reject,False)
    (ShowTime) ? ShowTime() : NOP   FrameSel(CMD=Fn,show=Show,reject=Reject)            # Returns NO audio
}

Function AutoGetFrames(clip c,float th,Float "dth", int "BlkW",int "BlkH",int "X",int "Y",int "W",int "H",
    \ Float "CW",Bool "AltScan",Bool "ChromaI",int "Matrix",int "OLapX",int "OLapY", Int "Lag",
    \ clip "dclip",String "KeepFN",String "DropFN",String "DupeFN",String "HoldFN",
    \ bool "Show",Bool "Showtime",String "ReturnFN",Bool "Reject"
    \ ) {
    Default(dclip,c)                            # Use detection clip (denoised or whatever) for making frames command files.
    KeepFN   = Default(KeepFN,"Keep.txt")       # Filename for Keep Frames
    ReturnFN = Default(ReturnFN,KeepFN)         # Use ReturnFN if given else KeepFN
    Reject   = Default(Reject,False)
    START = RT_TimerHP()
    # Make the command file for FrameSel()
    MotDetect(Last,th,dth,BlkW,BlkH,X,Y,W,H,CW,AltScan,ChromaI,Matrix,OLapX,OLapY,Lag,Last,
        \ KeepFN=KeepFN,DropFN=DropFN,DupeFN=DupeFN,HoldFN=HoldFN,Hide=True)
    RT_ForceProcess(Debug=True)                 # Scan entire clip forcing command files to be written.
    T = RT_TimerHP() - START
    RT_DebugF("AutoGetFrames: %.2fsecs (%.2fmins) %.2fFPS",T,T/60.0,FrameCount/T)
    c.SelectFrames(ReturnFN,Show=Show,showtime=Showtime,Reject=Reject)      # Extract ReturnFN source frames and return to client
}
EDIT: When using AutoGetFrames(), Progress/Speed FPS shown via DebugView[From Micro$oft]:- https://learn.microsoft.com/en-us/sy...oads/debugview
__________________
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; 3rd June 2025 at 02:14.
StainlessS is offline   Reply With Quote
Old 3rd June 2025, 10:22   #522  |  Link
rgr
Registered User
 
Join Date: Jun 2022
Posts: 299
Quote:
Originally Posted by StainlessS View Post
RT_LumaPixelsDifferent/Count(Thresh=ThP) > 0, ie ANY single pixel diff greater than ThP is a detect, the actual number does not matter, any one of them is a detect.
As I wrote, the problem is that it applies to the entire image, not the block.

Quote:
EDIT: The result of RT_LumaPixelsDifferent(ThP) or RT_LumaPixelsDifferentCount(ThP) could be shown in metrics and help to select good ThP, but the actual detect should only be if > 0.
This approach isn't perfect -- I do it comprehensively by comparing the differences in frames next to each other, so I don't have to have a perfect result. But I do have to have a comparable result, not one where duplicates can generate such different results.

Quote:
Same with the RT_FrameMovement(Prefix="FM_") style extra global vars, can show in metrics where can asisist in choosing good thresholds for a particular source. (see metrics in following post image, eg nAboveTh).
They don't help at all, because they can't. They don't show what contributed to the block measurement result.
rgr is offline   Reply With Quote
Old 3rd June 2025, 12:29   #523  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
I guess that its down to you writing your own routine then,
Good luck.
__________________
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 ???
StainlessS is offline   Reply With Quote
Old 4th June 2025, 13:53   #524  |  Link
rgr
Registered User
 
Join Date: Jun 2022
Posts: 299
Quote:
Originally Posted by StainlessS View Post
I guess that its down to you writing your own routine then,
Good luck.
Unfortunately, it's not for me anymore
rgr is offline   Reply With Quote
Old 16th August 2025, 20:52   #525  |  Link
Selur
.
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 7,854
Any plans to port RT_Stats to Vapoursynth?
__________________
Hybrid here in the forum, homepage, its own forum
Selur is offline   Reply With Quote
Old 16th August 2025, 20:57   #526  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Quote:
Any plans to port RT_Stats to Vapoursynth?
I would not hold your breath, (I dont use Vapoursynth),
and have cold sweats just thinking about making it HBD for avisynth.
(also, dont think I've done any C/CPP coding at all since Covid).
__________________
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 ???
StainlessS is offline   Reply With Quote
Old 18th October 2025, 19:58   #527  |  Link
qyot27
...?
 
qyot27's Avatar
 
Join Date: Nov 2005
Location: Florida
Posts: 1,501
Due to the issue reported in https://forum.doom9.org/showthread.php?t=186549, I needed to run RT_Stats on Linux. I saw the post from a few years ago that mentioned doing this, but the repository had been deleted in the time since.

Thankfully, the Internet Archive had preserved it, so I was able to reconstruct the changes (with the Linux patch being its own commit). The result is here:
https://github.com/qyot27/RT_Stats

Whether the change in behavior I noted in the thread above is the result of the changes involved in the patch for Linux or not, I don't know.
qyot27 is offline   Reply With Quote
Old 19th October 2025, 04:01   #528  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
From the linked thread,
Code:
RT_DebugF("TestRecursion : Debut")
    i = Compte(0,1000,1)
    RT_DebugF("TestRecursion Fin : %d",i)
    Return BlankClip(pixel_type="YUV420P8").Subtitle("Fini !")

    Function Compte(Int Ind,Int Fin, Int Incr) {
    RT_DebugF("TestRecursion : %d",Ind)
    Return (Ind < Fin) ? Compte(Ind+Incr,Fin,Incr) : Ind
}
I get this [on W10 x64]
Code:
00000102	01:51:05	[3576] RT_DebugF: TestRecursion : Debut
00000103	01:51:05	[3576] RT_DebugF: TestRecursion : 0
00000104	01:51:05	[3576] RT_DebugF: TestRecursion : 1
00000105	01:51:05	[3576] RT_DebugF: TestRecursion : 2
00000106	01:51:05	[3576] RT_DebugF: TestRecursion : 3
00000107	01:51:05	[3576] RT_DebugF: TestRecursion : 4

# cut

00000641	01:51:05	[3576] RT_DebugF: TestRecursion : 538
00000642	01:51:05	[3576] RT_DebugF: TestRecursion : 539
00000643	01:51:05	[3576] RT_DebugF: TestRecursion : 540
00000644	01:51:05	[3576] RT_DebugF: TestRecursion : 541

VDub2 disappears here.
__________________
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; 19th October 2025 at 04:06.
StainlessS is offline   Reply With Quote
Reply

Tags
averageluma, correlation, lumadifference, runtime

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 11:40.


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