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 4th January 2015, 04:24   #1  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
DBSC v0.051, Scene Change Detection - Work-in-Progress

Post #1 of Many.

Updated: v0.051
http://www.mediafire.com/download/c9...BSC-v0.051.zip


Basic Info
Code:
/*
  DBSC.avs v0.04, by StainlessS @ Doom9    
    
  A Scene Change Detection Tool set/kit/box. (Work In Progress - guinea pigs required)
    
  Currently Implemented: (to some degree):-
    
    Scenechange detection:-
      DBSC_CreateInfo(), creates fast scan RT_Stats INFO DBase.
        For each frame stores RT_YPlaneMin, RT_YPlaneMax, RT_YPlaneMinMaxDifference, RT_YPlaneMedian, RT_AverageLuma, RT_YPlaneStdev
         and RT_FrameDifference(n<->n+1). Could also be useful for other purposes.
          
      DBSC_Scan(), Using INFO DBase, creates a second SCAN DBase containing Scene Change detection data.
        Single Flash frame tolerant.
        Fade-To-Black Scene changes detected.

      DBSC_Override(), Using SCAN DBase and Overrides.txt, allows user to set additional Scene Change or remove erroneous ones
        from the SCAN DBase. Additional overrides set/unset without re-creating ScanDB.

    Scenechange Utility:-
      DBSC_WriteFiles(), Using SCAN DBase, Writes Start, End, Mid, And/Or Range Files for Scene Changes.
        Also writes a ClipClop command file for Start (ClipClop clip 1) and End (clip 2) frames, used by DBSC_Select().
    
      DBSC_SubsClip(), Returns clip optionally subtitled (metrics And/Or START OF SCENE / END OF SCENE / SINGLE FRAME SCENE subtitles)
            
      DBSC_StackSceneChanges(), Returns clip, End frame of a scene together with Stacked Start frame of following scene.
        (Check detections).

      DBSC_Select(), Similar-ish to SCSelect.
      
    Dynamically Changing Borders:-
      DBSC_DynaCrop(), Detect Dyanamically changing borders using ScanDB and create a SpliceDB for DBSC_DynaSplice().       

      DBSC_DynaSplice(), Trim, Crop, Resize and Splice, dynamically changing borders. Option to call user defined function
        on each trim, after it has been cropped and resized, and before splicing back together again.
      
      DBSC_Levels(), Function to DEMO a User Function as called by DBSC_DynaSplice().
                  
  TODO:-
    Improve detection.
    Blended Scene Change Detection (Well I can dream cant I, anybody any ideas ? )
    + whatver else I (or you) can think of. 
    
  Required:-
      Frame Accurate seekable source clip.
      RT_Stats, http://forum.doom9.org/showthread.php?t=165479
      GSCript,  http://forum.doom9.org/showthread.php?t=147846 
      Grunt,    http://forum.doom9.org/showthread.php?t=139337
      FrameSel, http://forum.doom9.org/showthread.php?t=167971
      ClipClop, http://forum.doom9.org/showthread.php?t=162266
      RoboCrop  http://forum.doom9.org/showthread.php?t=168053
      DebugView http://technet.microsoft.com/en-gb/sysinternals/bb896647.aspx (viewing Debug Output in real time)
*/
EDIT: Spell check and auto link insertion broken on site again (both worked fine a few days ago)
__________________
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 February 2015 at 12:05. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:25   #2  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #2 of many

Internal Use Functions
Code:
####################################################
###            INTERNAL USE ONLY FUNCTIONS       ***    
####################################################

Function DBSC_Str2ID(String IDS) {
    Assert(Strlen(IDS)==4,RT_String("%sMust be 4 character string('%s')","DBSC_Str2ID: ",IDS))
    Return(((RT_Ord(IDS,4)*256+RT_Ord(IDS,3))*256 + RT_Ord(IDS,2))*256) +RT_Ord(IDS,1)
}

Function DBSC_ColorSpaceIx(clip c) {
    cs=c.IsRGB24?0:c.IsRGB32?1:c.IsYUY2?2:c.IsYV12?3:-1
    return(cs>=0||VersionNumber<2.6)?cs:c.IsY8?4:c.IsYV16?5:c.IsYV24?6:c.IsYV411?7:-1
}


Function DBSC_InfoValidate(String InfoDB,Bool "MustExist",String "name") {
/*
    DBSC_InfoValidate(), Returns InfoDB valid status True/False.    
    True return signifies that the InfoDB exists and is of type InfoDB.
    If InfoDB does not exist and MustExist==True(Default), then throws error alert.
    Name, allows display of client function name instead of this function name in error alerts.    
*/
    myName=Default(name,"DBSC_InfoValidate: ")
    Assert(InfoDB!="",RT_String("%sMust provide an InfoDB filename",myName))
    Valid = Exist(InfoDB)
    GSCript("""
        if(Valid) {
            Valid = RT_DBaseFields(InfoDB)==7 && RT_VarIsSame(RT_DBaseGetID(InfoDB,0),DBSC_Str2ID("DBSC")) &&
                \ RT_VarIsSame(RT_DBaseGetID(InfoDB,1),DBSC_Str2ID("INFO"))    
            if(!Valid) {
                RT_DebugF("InfoDB failed Basic validation",name=myName)            
                !Valid?Assert(RT_DBaseGetID(InfoDB,1)!=DBSC_Str2ID("SCAN"),RT_String("%sWe Require the InfoDB, not the ScanDB",myName)):NOP
            }
        } Else {Assert(!Default(MustExist,True),RT_String("%sInfoDB does NOT exist\n'%s'",myName,InfoDB))}    
    """)
    Return Valid
}


Function DBSC_ScanValidate(String ScanDB,Bool "MustExist",String "name") {
/*
    DBSC_ScanValidate(), Returns ScanDB valid status True/False.    
    True return signifies that the ScanDB exists and is of type ScanDB.
    If ScanDB does not exist and MustExist==True(Default), then throws error alert.
    Name, allows display of client function name instead of this function name in error alerts.    
    No Check on whether ScanDB scene changes have been user overridden.
*/
    myName=Default(name,"DBSC_ScanValidate: ")
    Assert(ScanDB!="",RT_String("%sMust provide a ScanDB filename",myName))
    Valid = Exist(ScanDB)
    GSCript("""
        if(Valid) {
            Valid = RT_DBaseFields(ScanDB)==5 && RT_VarIsSame(RT_DBaseGetID(ScanDB,0),DBSC_Str2ID("DBSC")) &&
                \ RT_VarIsSame(RT_DBaseGetID(ScanDB,1),DBSC_Str2ID("SCAN"))    
            if(!Valid) {
                RT_DebugF("ScanDB failed Basic validation",name=myName)            
                !Valid?Assert(RT_DBaseGetID(ScanDB,1)!=DBSC_Str2ID("INFO"),RT_String("%sWe Require the ScanDB, not the InfoDB",myName)):NOP
            }
        } Else {Assert(!Default(MustExist,True),RT_String("%sScanDB does NOT exist\n'%s'",myName,ScanDB))}    
    """)
    Return Valid
}


Function DBSC_QueryOveridden(String ScanDB) {
/*
    DBSC_QueryOveridden(), Returns TOTAL number of Overides set on a ScanDB.
    Uses third last RT_DBase attribute to store the number of user set Overrides (User attribute count currently 1024). 
*/
    myName="DBSC_QueryOveridden: "
    Assert(DBSC_ScanValidate(ScanDB,MustExist=True,name=myName),RT_String("%sScanDB Invalid\n'%s'",myName,ScanDB))
    nAttribs=RT_DBaseGetAttrib(ScanDB,-1)
    Return RT_DBaseGetAttrib(ScanDB,nAttribs-4)
}
__________________
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; 4th February 2015 at 07:49. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:26   #3  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #3 of many

User Functions:
Create INFO DBase

Code:
####################################################
###                USER FUNCTIONS                ***    
####################################################

Function DBSC_CreateInfo(clip c,String InfoDB,int "Matrix",Float "ChromaWeight",Float "Thresh",Bool "RecycleDB",Bool "DEBUG") {
/*
    DBSC_CreateInfo()
    Create DBase to assist in scanning clip to extract various data.
    c source clip.
    InfoDB, DBase Filename to create.
    Matrix: Conversion matrix for conversion of RGB to YUV-Y Luma.  0=REC601 : 1=REC709 : 2 = PC601 : 3 = PC709,
        Default = (Width > 1100 OR Height>600) then 3(PC709) else 2(PC601). YUV not used
    ChromaWeight, Default 0.333333 ChromaWeight range 0.0->1.0. Default gives twice as much weight to luma as combined chroma. (YUV Only).
    Thresh, Default 0.2.
    RecycleDB, Default True. False, recreate DBase even if already exists. True, Try to re-use existing DBase where possible. 
*/
    c
    myName="DBSC_CreateInfo: "
    START_TIME = RT_TimerHP
    Assert(RT_FunctionExist("GScript"),myName+"Essential GScript plugin installed, http://forum.doom9.org/showthread.php?t=147846")
    Matrix       = Default(Matrix,(Width>1100||Height>600)?3:2)
    ChromaWeight = Float(Default(ChromaWeight,1.0/3.0))   # Weighting for combined U + V Channels. Suggest about 1.0/3.0 -> 1.0/2.0
    Thresh       = Float(Default(Thresh,0.2))    
    RecycleDB=Default(RecycleDB,True)
    DEBUG=Default(DEBUG,True) 
    Assert(Matrix>=0&&Matrix<=3,RT_String("%sMatrix 0->3",myName))
    Assert(ChromaWeight>=0.0 && ChromaWeight<=1.0,RT_String("%sChromaWeight 0.0->1.0",myName))
    Assert(Thresh>=0.0 && Thresh<=1.0,RT_String("%sThresh 0.0->1.0",myName))
    InfoDB = RT_GetFullPathName(InfoDB)                           # FullPath name, convert '/' to '\'
    FC = FrameCount
    #
    GScript("""
        InfoValid = DBSC_InfoValidate(InfoDB,MustExist=False,name=myName) ? RecycleDB : False
        if(InfoValid&&RecycleDB) {
            InfoValid =   
              \ RT_VarIsSame(RT_DBaseGetID(InfoDB,2),Width) && RT_VarIsSame(RT_DBaseGetID(InfoDB,3),Height) &&
              \ RT_VarIsSame(RT_DBaseGetID(InfoDB,4),DBSC_ColorSpaceIx(c)) &&
              \ RT_VarIsSame(RT_DBaseRecords(InfoDB),FrameCount)
            if(!InfoValid) {           
                (DEBUG) ? RT_DebugF("InfoDB failed Match To Clip validation\n'%s'",InfoDB,name=myName) : NOP            
            } Else {
                InfoValid = RT_VarIsSame(RT_DBaseGetID(InfoDB,5),Matrix) && 
                    \ RT_VarIsSame(RT_DBaseGetID(InfoDB,6),ChromaWeight) &&
                    \ RT_VarIsSame(RT_DBaseGetID(InfoDB,7),Thresh)
                if(!InfoValid) {
                    (DEBUG) ? RT_DebugF("InfoDB failed Match Matrix/ChromaWeight/Thresh validation\n'%s'",InfoDB,name=myName) : NOP                
                }
            }
        }
        if(!RecycleDB||!InfoValid) {
            (DEBUG) ? RT_DebugF("Initializing INFO DBase %s",InfoDB,name=myName) : NOP
            RT_DBaseAlloc(InfoDB,FC,"iiiifff")
            # Info for Frame Number n ie record number    
            # INT YStats Flags Full name                          Local Var     Range
            # 0  1($01)        RT_YPlaneMin()                     "yMin"        (0->255)
            # 1  2($02)        RT_YPlaneMax()                     "yMax"        (0->255)
            # 2  4($04)        RT_YPlaneMinMaxDifference()        "yMinMaxDiff" (0->255)
            # 3  8($08)        RT_YPlaneMedian()                  "yMed"        (0->255)
            # FLOAT
            # 4 16($10)        RT_AverageLuma()                   "yAve"        (0.0->255.0)
            # 5 32($20)        RT_YPlaneStdev()                   "yStdev"      (0.0->255.0)
            # -
            # 6  RT_FrameDifference(n <-> n+1)                                  (0.0->255.0)
            pcf = FC / 20.0
            nxtn = Round(pcf)
            FMT="%d ] %.0f%% Complete"
            for(n=0,FC-1) {
                # Flgs = YPlaneMin=1,YPlaneMax=2,YPlaneMinMaxDifference=4,YPlaneMedian=8,AverageLuma=16,YPlaneStdev=32
                RT_Ystats(Last,n,flgs=$3F,Threshold=Thresh,Matrix=Matrix)
                FD=RT_FrameDifference(Last,Last,n,n+1,ChromaWeight)
                RT_DBaseSet(InfoDB,n,YS_yMin,YS_yMax,YS_yMinMaxDiff,YS_yMed,YS_yAve,YS_yStdev,FD)
                
                if(DEBUG && n>=nxtn) {
                     RT_DebugF(FMT,n,Round((n+1)*100.0/FC),name=myName)
                     nxtn=Round(n+pcf)
                }
            }
            RT_DBaseSetID(InfoDB,0,DBSC_Str2ID("DBSC"))
            RT_DBaseSetID(InfoDB,1,DBSC_Str2ID("INFO"))
            RT_DBaseSetID(InfoDB,2,Width)
            RT_DBaseSetID(InfoDB,3,Height)
            RT_DBaseSetID(InfoDB,4,DBSC_ColorSpaceIx(c))
            RT_DBaseSetID(InfoDB,5,Matrix)
            RT_DBaseSetID(InfoDB,6,ChromaWeight)
            RT_DBaseSetID(InfoDB,7,Thresh)
        } Else {
            (DEBUG) ? RT_DebugF("INFO DBase Recycled '%s'",InfoDB,name=myName) : NOP
        }
        T = RT_TimerHP - START_TIME
        (DEBUG) ? RT_DebugF("Total Time taken = %.2f Seconds (%.2f Mins)",T,T/60.0,name=myName) : NOP 
    """)
    return RecycleDB
}
__________________
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; 4th February 2015 at 07:50. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:27   #4  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #4 of many

Create SCAN DBase {PART_1, (too big)}

Code:
Function DBSC_Scan(clip c,String InfoDB,String ScanDB,Float "dFact",Float "dMinim",Int "dMinLen",Float "dCorr",Float "DupTh",Float "POV",
        \ Int "dFlashFrames", Bool "RecycleDB",Bool "DEBUG") {
/*
    DBSC_Scan().
      InfoDB, EXISTING INFO DBSC_CreateInfo created DBase 
      ScanDB, Name of Scene Change SCAN DBase, created by this function.
      dFact, Default 1.5 (greater than 1.0)
      dMinim, Default 8.0, (greater than 0.1) dFact and dMinim , Control how much bigger difference between Curr->Next has to be compared
        to Prev->Curr and Next->Next+1, to detect scene change.
        Curr->Next has to be greater than (dFact * 'Prev->Curr' + dMinim), and also greater than (dFact * 'Next->Next+1' + dMinim)
      Dfact=1.4, works pretty good but is on a hair trigger ie very sensitive, dMinim=8.0 reduces/controls that sensitivity.
        If clip is anime, then is quite likely that some frame differences are 0.0, so even a small difference next to 0.0 diff frames
        will be infinitely greater than 0.0, in this situation dMinim will be the sole govenor of scene detection and so should be of
        reasonable value, maybe about 8.0 -> 12.0 would be good choices.
      dMinLen, Default 12. Minimum frame length of current scene that qualifies for scene change detection.
      DupTh, Default 0.5.
      POV, Default 60.0.
      RecycleDB, Default True. False, recreate DBase even if already exists. True, Try to re-use existing DBase where possible. 
    
    Created ScanDB SCAN DBase Fields
      0 ) SOSix, Start Of Scene frame(record)
      1 ) EOSix, End Of Scene frame(record)
      2 ) Type(1=SOS,2=EOS,3=SOS and EOS(single frame scene),0=none)
      3 ) SceneNo(Zero Rel)
      4 ) FLGS, Detection Reason code 
*/
    c
    myName="DBSC_Scan: "
    START_TIME = RT_TimerHP
    Assert(RT_FunctionExist("GScript"),myName+"Essential GScript plugin installed, http://forum.doom9.org/showthread.php?t=147846")
    dFact        = Float(Default(dFact,1.25))   # Lower more false +ve's, Higher fewer scene changes (Dfact=1.5 dMinim=8.0 works pretty good)
    dMinim       = Float(Default(dMinim,6.0))  # Scene Change, avoid silly numbers (very small) on static scenes causing false +ve
    dMinLen      = Default(dMinLen,6)          # Minimum length of scene for scene change detection to be valid (ignore short scenes)
    dCorr        = Float(Default(dCorr,0.75))
    DupTh        = Float(Default(DupTh,0.5))    # 
    POV          = Float(Default(POV,60.0))     # 
    dFlashFrames = Default(dFlashFrames,dMinLen-1)
    RecycleDB=Default(RecycleDB,True)
    DEBUG=Default(DEBUG,True)
    Assert(dFact>1.0 ,RT_String("%sdFact MUST be greater than 1.0",myName))
    Assert(dMinim>=1.0,RT_String("%sdMinim MUST be greater or equal to 1.0",myName))
    Assert(dMinLen>=2,RT_String("%sdMinLen MUST be greater or equal to 2",myName)) # Cannot detect single frame scene.
    Assert(dCorr>=0.6,RT_String("%sdCorr 0.6 -> 1.0",myName))
    Assert(DupTh>0.0&&DupTh<=1.0,RT_String("%sdDupTh 0.0 -> 1.0",myName))
    Assert(POV>=0.0&&POV<=100.0,RT_String("%sPOV 0.0 -> 100.0",myName))
    Assert(dFlashFrames>=1&&dFlashFrames<dMinLen,RT_String("%sdFlashFrames 1 -> dMinLen-1 (%d)",myName,dMinLen-1))
    InfoDB = RT_GetFullPathName(InfoDB)               # FullPath name, convert '/' to '\'
    ScanDB = RT_GetFullPathName(ScanDB)
    FC = FrameCount
    #
    GScript("""
        InfoValid = DBSC_InfoValidate(InfoDB,MustExist=True,name=myName)
        Assert(InfoValid,RT_String("%sInfoDB failed Basic validation\n'%s'",myName,InfoDB))
        InfoValid =   
          \ RT_VarIsSame(RT_DBaseGetID(InfoDB,2),Width) && RT_VarIsSame(RT_DBaseGetID(InfoDB,3),Height) &&
          \ RT_VarIsSame(RT_DBaseGetID(InfoDB,4),DBSC_ColorSpaceIx(c)) &&
          \ RT_VarIsSame(RT_DBaseRecords(InfoDB),FC)
        Assert(InfoValid,RT_String("%sInfoDB failed Match To Clip validation\n'%s'",myName,InfoDB))
        Matrix       = RT_DBaseGetID(InfoDB,5)
        ChromaWeight = RT_DBaseGetID(InfoDB,6)
        Thresh       = RT_DBaseGetID(InfoDB,7)
        #
        ScanValid = DBSC_ScanValidate(ScanDB,MustExist=False,name=myName) ? RecycleDB : False
        if(ScanValid&&RecycleDB) {
            ScanValid =   
              \ RT_VarIsSame(RT_DBaseGetID(ScanDB,2),Width) && RT_VarIsSame(RT_DBaseGetID(ScanDB,3),Height) &&
              \ RT_VarIsSame(RT_DBaseGetID(ScanDB,4),DBSC_ColorSpaceIx(c)) &&
              \ RT_VarIsSame(RT_DBaseRecords(ScanDB),FC)
            if(!ScanValid) {
                (DEBUG) ? RT_DebugF("ScanDB failed Match To Clip validation\n'%s'",ScanDB,name=myName) : NOP            
            } Else {
                nAttribs=RT_DBaseGetAttrib(ScanDB,-1)
                ScanValid = RT_VarIsSame(RT_DBaseGetAttrib(ScanDB,nAttribs-1),Matrix) &&
                    \ RT_VarIsSame(RT_DBaseGetAttrib(ScanDB,nAttribs-2),ChromaWeight) &&              
                    \ RT_VarIsSame(RT_DBaseGetAttrib(ScanDB,nAttribs-3),Thresh)              
                if(!ScanValid) {
                    (DEBUG) ? RT_DebugF("ScanDB failed Match Matrix/ChromaWeight/Thresh to InfoDB\n'%s'",ScanDB,name=myName) : NOP                
                } else {
                    ScanValid = 
                      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,5),dFact)         &&
                      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,6),dMinim)        &&
                      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,7),dMinLen)       &&
                      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,8),dCorr)         &&                      
                      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,9),DupTh)         &&
                      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,10),POV)          &&
                      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,11),dFlashFrames)                      
                    if(!ScanValid) {
                        (DEBUG) ? RT_DebugF("ScanDB failed Match Argument validation\n'%s'",ScanDB,name=myName) : NOP                
                    }            
                }
            }
        }
        if(!RecycleDB||!ScanValid) {
            (DEBUG) ? RT_DebugF("Initializing Scenechange Scan DBase %s",ScanDB,name=myName) : NOP
            RT_DBaseAlloc(ScanDB,FC,"iiiii")                      # SOSix, EOSix, Type(1=SOS,2=EOS,0=non), SceneNo(Zero Rel), FLGS 
            (DEBUG) ? RT_DebugF("Creating Scan DBase",name=myName) : NOP
            Start=0 B=0.0 C=0.0 
            # Find scene changes, marking EOSix(End Of Scene) of scene start frame(record). (ie set EOSix at SOS record)
            # Also set FLGS field at EOS (End frame record).
            # A=Diff(n-1<->n) B=Diff(n<->n+1), C=Diff(n+1<->n+2)
            # We are detecting scene change between current and next frames, ie when n at End Of Scene
            # (@ EOS we already know current SOS, and also next scene SOS is EOS + 1).
            #
            # For Anime, if Diff(n-1,n) < DupTh, we assume duplicate frame and instead use n-2 in comparisons [same for Diff(n+1,n+2)]
            #
            dPOV = POV *255.0 / 100.0                                  # Convert range [0.0,100.0] to [0.0,255.0] 
            C = RT_DBaseGetField(InfoDB,-1 + 1, 6)                     # Prep
                     
            NextPossEnd = dMinLen - 1
            for(n=0,FC-2) {
                A=B  B=C C=RT_DBaseGetField(InfoDB,Min(n+1,FC-1),6)    # Re-use B and C from previous iteration, new C = Diff(n+1 <-> n+2)
                if(n >= NextPossEnd) {
                    Cx = (C<DupTh)?Max(RT_FrameDifference(Last,Last,n+1,n+3,ChromaWeight),C): C # If Diff(n+1,n+2) too low, use Diff(n+1,n+3)                                                                   
                    if((dFact*Cx+dMinim) < B) {                        # sufficiently bigger than 'Next->Next+1' (RHS) ?                    
                        # Here, RHS STANDARD DETECT SCENE CHANGE: n+1 CANNOT be a single flash frame
                        # If fewer than dPOV luma pixels changed by at least 1 luma level, then NOT a scene change
                        PxDf=RT_LumaPixelsDifferent(Last,Last,n=n,n2=n+1,Thresh=1)
                        if(PxDf >= dPOV) { # Here, Possible RHS scene change
                            PxDf2 = RT_LumaPixelsDifferent(Last,Last,n=n,n2=n-1,Thresh=1)                        
                            if(PxDf2 < PxDf) { # WOULD LHS be Pixlcount Overridden ? (at previous frame)
                                C_DR = RT_DBaseGetField(InfoDB,n,2)                # MinMaxDifY(n)
                                N_DR = RT_DBaseGetField(InfoDB,Min(n+1,FC-1),2)    # MinMaxDifY(n+1) : ie FROM NEXT FRAME/RECORD                                                                                    
                                if(Abs(N_DR-C_DR)>4) {
                                    # Look for Flash frames, if found disable detect until reached flash frame,
                                    # can then redetect incl flash frames again from that point.
                                    FlashLim = Min(n+dFlashFrames,FC-2)   # MUST HALT on or before last frame where valid n+1 scene is dMinLen
                                    for(i=FlashLim,n+2,-1) {
                                       mfpdf=RT_LumaPixelsDifferent(Last,Last,n=n,n2=i,Thresh=16)
                                       mfcorr=RT_LumaCorrelation(Last,Last,n=n,n2=i)
                                       if(mfpdf<64.0 && mfcorr>dCorr) { 
                                            (DEBUG) ? RT_DebugF("%d ] MULTIFLASH: @ %d LumaPixdifCnt=%.2f%% LumaCorr=%.2f",
                                                    \ n,i,mfpdf*100.0/255.0,mfcorr,name=myName) : NOP                                        
                                            NextPossEnd = i                    # No more detections until detected flash frame
                                            RT_DBaseSetField(ScanDB,n,4,$20001)# FLGS reason to Standard detect Override by Multiflash                                                                
                                            i = -1                             # BREAK                                                                                    
                                       }
                                    }
                                }
                                if(n >= NextPossEnd) {                            
                                    RT_DBaseSetField(ScanDB,n,4,1)     # FLGS reason to Standard detect                        
                                    RT_DBaseSetField(ScanDB,Start,1,n) # Set Start of scene frame/Record EOSix(End OF Scene) to this frame.
                                    NextPossEnd = n + dMinLen                                
                                    Start   = n + 1                    # Next frame, SOS follows this EOS
                                }
                            } else { # HERE, decide not detected, OR Reason PixelCount overriden
                                # sufficiently bigger than 'Prev->Curr'   (LHS) ? :  # If Diff(n,n-1) too low, use Diff(n,n-2)
                                Ax = (A<DupTh)?Max(RT_FrameDifference(Last,Last,n,n-2,ChromaWeight),A): A
                                if((dFact*Ax+dMinim) < B) {
                                    RT_DBaseSetField(ScanDB,n,4,$10001)    # FLGS reason to Standard detect Overridden by Pixel count
                                    (DEBUG) ? RT_DebugF("%d ] n-1->n Luma Pixel Diff Count OVERRIDE(too low) = %.2f%%",
                                        \ n,PxDf2*100/255.0,name=myName) : NOP                        
                                }
                            }                            
                        } else {
                            RT_DBaseSetField(ScanDB,n,4,$10001)    # FLGS reason to Standard detect Overridden by Pixel count                        
                            (DEBUG) ? RT_DebugF("%d ] n->n+1 Luma Pixel Diff Count OVERRIDE(too low) = %.2f%%",
                                    \ n,PxDf*100/255.0,name=myName) : NOP                        
                        }                       
                    }                   
                }            
            }
            # Do the last frame (n = FC-1, moved out of above loop to avoid conditional branch
            RT_DBaseSetField(ScanDB,Start,1,FC-1)                      # Set Start of scene frame/Record EOSix to this last frame.                       
            #
__________________
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; 4th February 2015 at 07:53. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:28   #5  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #5 of many

Create SCAN DBase {PART_2, (too big)}
Code:
            # Rescan to do Fadeout->FadeIn Scene Changes : Set only EOSix @ Start frame/record of Scene Change, and ALSO FLGS
            (DEBUG) ? RT_DebugF("ReScan for Fade-to-Black SceneChanges:",name=myName) : NOP
            for(n=0,FC-1) {
                Start = n                                                               # SOSix for this scene
                End   = RT_DBaseGetField(ScanDB,Start,1)                                # EOSix for this scene
                Len   = End-Start+1
                if(Len >= Max(dMinLen*2,24)) {
                    # Start and End with YPlaneMinMaxDifference >= 16
                    if(RT_DBaseGetField(InfoDB,Start,2) >= 16 && RT_DBaseGetField(InfoDB,End,2) >= 16) {
                        for(j=Start+dMinLen,End - dMinLen) {
                            mnmxdf=RT_DBaseGetField(InfoDB,j,2)
                            if(mnmxdf <= 6-2) {                                          # 4 or below FADEOUT, 4->6 no mans land (still faded)
                                je=j
                                for(k=j+1,End-dMinlen) {                                 # Hunt fade end, No mans land(4->6), remains faded
                                    mnmxdf=RT_DBaseGetField(InfoDB,k,2)                  # YMinMaxDiff
                                    if(mnmxdf <= 6-0) {
                                        je=k                                             # still fade
                                    } else {
                                        k=End                                            # Not faded any more
                                    }                             
                                }
                                m = (j + je) / 2                                         # middle faded frame (approx)
                                if(m < End - dMinLen) {
                                    RT_DebugF("%d ] FADE SCENECHANGE @ %d",n,M,name=myName)                            
                                    FLGS=RT_DBaseGetField(ScanDB,m-1,4)                                
                                    RT_DBaseSetField(ScanDB,m-1,4,RT_BitOR(FLGS,$00008000)) # EOSix of prev scene FLGS set to Reason=Fade-To-Black                                
                                    RT_DBaseSetField(ScanDB,Start,1,m-1)                    # Adjust EOSix @ Start Frame                                
                                    Start=m                                                 # New Start frame                           
                                    RT_DBaseSetField(ScanDB,Start,1,End)                    # Adjust End @ NEW Start Frame                                
                                }
                                # Retry for another FADE SceneChange in original scene
                                je = Max(m+dMinLen,je)
                                for(k=je+1,End-dMinLen) {                                # Scan till MinMaxDif(je+1) is above 16+Leeway
                                    mnmxdf=RT_DBaseGetField(InfoDB,k,2)                                
                                    if(mnmxdf >=16+8) {
                                        (DEBUG) ? RT_DebugF("%d ] FADE SCENECHANGE RETRY SCAN @ %d",n,je+1,name=myName) : NOP                            
                                        k=End
                                    } else {
                                        je=k
                                    }                            
                                }
                                j = je                                                   # j = je + 1 at next iteration, next frame RETRY scan
                            }
                        }
                    }    
                }
                n = End                                                                   # End + 1 at next iteration            
            }
    
            # At this point only EOSix at start of scene frame set, AND ALSO reason FLGS for Last frame of scene         
            (DEBUG) ? RT_DebugF("Writing Full SceneChange DBase Data",name=myName) : NOP
            SceneNo=-1  # Write Scene Number (Zero Relative)
            FLGS = 0
            for(n=0,FC-1) {
                Start   = n
                End     = RT_DBaseGetField(ScanDB,Start,1)
                SceneNo = SceneNo + 1
                (DEBUG) ?  RT_DebugF("%d] START=%d End=%d SceneNo=%d",n,Start,End,SceneNo,name=myName) : NOP
                # SOSix, EOSix, Type(1=SOS,2=EOS,3=SOS+EOS,0=non), SceneNo(Zero Rel), FLGS
                for(j=Start,End) {                                                       # Leave Reason FLGS intact
                    RT_DBaseSetField(ScanDB,j,0,Start)
                    RT_DBaseSetField(ScanDB,j,1,End)
                    RT_DBaseSetField(ScanDB,j,2,0)
                    RT_DBaseSetField(ScanDB,j,3,SceneNo)
                }
                RT_DBaseSetField(ScanDB,Start,4,FLGS)                                    # Rewrite FLGS from previous EOS
                RT_DBaseSetField(ScanDB,Start,2,1)                                       # Rewrite Type, Start Of Scene
                Type = (Start==End) ? 3 : 2                                              # Single frame scene at last frame ? (SOS & EOS)
                RT_DBaseSetField(ScanDB,End  ,2,Type)                                    # ReWrite Type, End Of Scene                 
                FLGS = RT_DBaseGetField(ScanDB,End,4)                                    # Current scene FLGS, next time Prev scene FLGS
                n = End                                                                  # Next iteration n = End + 1
            }
            RT_DBaseSetID(ScanDB,0,DBSC_Str2ID("DBSC"))
            RT_DBaseSetID(ScanDB,1,DBSC_Str2ID("SCAN"))
            RT_DBaseSetID(ScanDB,2,Width)
            RT_DBaseSetID(ScanDB,3,Height)
            RT_DBaseSetID(ScanDB,4,DBSC_ColorSpaceIx())            
            nAttribs=RT_DBaseGetAttrib(ScanDB,-1)
            RT_DBaseSetAttrib(ScanDB,nAttribs-1,Matrix)
            RT_DBaseSetAttrib(ScanDB,nAttribs-2,ChromaWeight)
            RT_DBaseSetAttrib(ScanDB,nAttribs-3,Thresh)
            RT_DBaseSetID(ScanDB,5,dFact)
            RT_DBaseSetID(ScanDB,6,dMinim)
            RT_DBaseSetID(ScanDB,7,dMinLen)
            RT_DBaseSetID(ScanDB,8,dCorr)
            RT_DBaseSetID(ScanDB,9,DupTh)
            RT_DBaseSetID(ScanDB,10,POV)
            RT_DBaseSetID(ScanDB,11,dFlashFrames)
        } Else {
            (DEBUG) ? RT_DebugF("SCScan DBase Recycled '%s'",ScanDB,name=myName) : NOP
        }
        T = RT_TimerHP - START_TIME
        (DEBUG) ? RT_DebugF("Total Time taken = %.2f Seconds  (%.2f Mins)",T,T/60.0,name=myName) : NOP 
    """)
}
__________________
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; 4th February 2015 at 07:54. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:29   #6  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #6 of many

Scene Change Utility funcs, Part 1
Code:
##################
# UTILITY
##################

Function DBSC_Override(String ScanDB,String Override_Fn,Bool "DEBUG") {
/*
  DBSC_Override(), Using SCAN DBase and Overrides.txt, allows user to set additional Scene Change or remove erroneous ones
    from the SCAN DBase. 

  ScanDB, INFO DBase created by DBSC_Scan.
  Override_fn filename: If first character == '*' then uses text in the Override_fn string and does not load file.
      When using Override_fn as string, then each override should be on separate line (same format as file).
    FORMAT: One frame numer command on each line. 
      Any +ve frame number sets START Of Scene Change frame.
      Any -ve frame number REMOVES a scene change at that frame (START or END).
*/
    myName="DBSC_Override: "
    START_TIME = RT_TimerHP
    DEBUG=Default(DEBUG,True)
    Assert(Override_Fn!="",RT_String("%sMust provide a Override filename",myName))
    GSCript("""
        Assert(DBSC_ScanValidate(ScanDB,MustExist=True,name=myName),RT_String("%sScanDB Invalid\n'%s'",myName,ScanDB))
        if(RT_Ord(Override_Fn)!=RT_Ord("*")) {
            Assert(Exist(Override_Fn),RT_String("%sOverride_Fn Does NOT exist\n'%s'",myName,Override_Fn))
            (DEBUG) ? RT_DebugF("Reading Override File '%s'",Override_Fn,name=myName) : NOP
            OVS = RT_ReadTxtFromFile(Override_Fn)
        } Else {
            OVS = MidStr(Override_Fn,2) 
        }
        OVS=(RT_Ord(OVS)==0) ? "#" : OVS                    # Avoid error in RT_StrReplaceMulti for Empty string ""
        Fnd_S=RT_String("\t\n  \n")                         # Replace TAB and double SPACE with Single SPACE
        Rep_S=RT_String(" \n \n")
        OVS=RT_StrReplaceMulti(OVS,Fnd_S,Rep_S)
        NLINES = RT_TxtQueryLines(OVS)                      # Lines of text in OVS
        (DEBUG) ? RT_DebugF("Scanning Overrides",name=myName) : NOP
        FC=RT_DBaseRecords(ScanDB)
        INSERTED=0
        DELETED =0
        RT_DBaseSetID(ScanDB,1,-1)                          # Disable ScanDB validity until finished without error
        for(i=0,NLINES-1) {
            STR = RT_TxtGetLine(OVS,i)                      # Without trailing n/l
            While(RT_Ord(STR)==32) { STR=MidStr(STR,2) }    # Eat White
            S=STR
            if(RT_Ord(S)!=RT_Ord("#")&&RT_Ord(S)!=0) {      # Ignore comment ONLY or Empty lines
                Neg=False
                n=-1
                if(RT_Ord(S)==RT_Ord("-")) {
                    Neg=True
                    S=MidStr(S,2)
                    While(RT_Ord(S)==32) { S=MidStr(S,2) }  # Eat White
                } Else if(RT_Ord(S)==RT_Ord("+")) {
                    S=MidStr(S,2)
                    While(RT_Ord(S)==32) { S=MidStr(S,2) }  # Eat White
                }
                if(RT_Ord(S)>=RT_Ord("0") && RT_Ord(S)<=RT_Ord("9")) {
                    n=RT_NumberValue(S)
                    While(RT_Ord(S)>=RT_Ord("0") && RT_Ord(S)<=RT_Ord("9")) { S=MidStr(S,2) }         # Eat Digits
                    While(RT_Ord(S)==32) { S=MidStr(S,2) }                                            # Eat White
                    if(RT_Ord(S)==RT_Ord("#")) {S=""}                                                 # Eat remaining Comment                    
                }
                Assert(S=="",RT_String("%sLINE %d : Non Parse @'%s'\n'%s'",myName,i+1,S,STR))
                Assert(n>=0 && n<FC,RT_String("%sLINE %d : Frame %d Does Not Exist @'%s'\n'%s'",myName,i+1,n,S,STR))
                Assert(n!=0 && n!=FC-1,RT_String("%sLINE %d : Cannot Override First or Last frame %d @'%s'\n'%s'",myName,i+1,n,S,STR))
                # ScanDB Fields: SOSix, EOSix, Type(1=SOS,2=EOS,0=non), SceneNo(Zero Rel), FLGS
                Start=RT_DBaseGetField(ScanDB,n,0)
                End  =RT_DBaseGetField(ScanDB,n,1)
                Type =RT_DBaseGetField(ScanDB,n,2)
                Single=(Start==End && Start == n && Type==3)
                if(Neg) {
                    if(n!=Start && n != End) {
                        (DEBUG||Type!=0) ? RT_DebugF("LINE %d : DEL SC, Frame %d Neither Start nor End Of Scene, Ignoring",i+1,n,name=myName) : NOP
                        Assert(Type==0,RT_String("%sLINE %d : INTERNAL ERROR, Frame %d Type non-zero(%d)",myName,i+1,n,Type))
                    } Else {
                        if(Single) {
                            # Single Frame Scene is melded with previous scene
                            (DEBUG) ? RT_DebugF("LINE %d : DEL SC, Frame %d Removing Single Frame Scene",i+1,n,name=myName) : NOP
                            NewStart = RT_DBaseGetField(ScanDB,n-1,0)               # SOSix from previous scene
                            NewEnd   = End                                          # EOSix from current scene (ie n)
                            NewType=(NewStart==n-1)?1:0                             # Previous is single frame scene 
                            RT_DBaseSetField(ScanDB,n-1,2,NewType)                  # Change n-1 to Type NewType (SOS OR none)
                            FLGS=RT_DBaseGetField(ScanDB,n-1,4)                     # n-1 FLGS
                            RT_DBaseSetField(ScanDB,n-1,4,RT_BitOR(FLGS,$40000000)) # FLGS User Deleted                         
                            FLGS=RT_DBaseGetField(ScanDB,n,4)                       # n FLGS
                            RT_DBaseSetField(ScanDB,n,4,RT_BitOR(FLGS,$40000000))   # FLGS User Deleted                                                 
                        } Else if(Start==n) {
                            (DEBUG||Type!=1) ? RT_DebugF("LINE %d : DEL SC, Frame %d Removing Start Of Scene",i+1,n,name=myName) : NOP
                            Assert(Type==1,RT_String("%sLINE %d : INTERNAL ERROR, Frame %d Type non-1(%d)",myName,i+1,n,Type))
                            NewStart = RT_DBaseGetField(ScanDB,n-1,0)               # SOSix from previous scene
                            NewEnd   = End                                      # EOSix from current scene 
                            RT_DBaseSetField(ScanDB,n-1,2,0)                        # Change n-1 to Type=None
                            FLGS=RT_DBaseGetField(ScanDB,n-1,4)                     # n-1 FLGS
                            RT_DBaseSetField(ScanDB,n-1,4,RT_BitOR(FLGS,$40000000)) # FLGS User Deleted                         
                            FLGS=RT_DBaseGetField(ScanDB,n,4)                       # n FLGS
                            RT_DBaseSetField(ScanDB,n,4,RT_BitOR(FLGS,$40000000))   # FLGS User Deleted                         
                        } Else {
                            (DEBUG||Type!=2) ? RT_DebugF("LINE %d : DEL SC, Frame %d Removing End Of Scene",i+1,n,name=myName) : NOP
                            Assert(Type==2,RT_String("%sLINE %d : INTERNAL ERROR, Frame %d Type non-2(%d)",myName,i+1,n,Type))
                            NewStart = Start                                    # SOSis from current scene
                            NewEnd   = RT_DBaseGetField(ScanDB,n+1,1)               # EOSix from next scene                         
                            RT_DBaseSetField(ScanDB,n+1,2,0)                        # Change n+1 to Type=None
                            FLGS=RT_DBaseGetField(ScanDB,n,4)                       # n FLGS
                            RT_DBaseSetField(ScanDB,n,4,RT_BitOR(FLGS,$40000000))   # FLGS User Deleted                         
                            FLGS=RT_DBaseGetField(ScanDB,n+1,4)                     # n+1 FLGS
                            RT_DBaseSetField(ScanDB,n+1,4,RT_BitOR(FLGS,$40000000)) # FLGS User Deleted                         
                        }
                        for(j=NewStart,NewEnd) {
                            RT_DBaseSetField(ScanDB,j,0,NewStart)                   # Change all of scene SOSix to new Start                            
                            RT_DBaseSetField(ScanDB,j,1,NewEnd)                     # Change all of scene EOSix to new End                            
                        }
                        NewType=(Single)?2:0
                        RT_DBaseSetField(ScanDB,n,2,NewType)                        # Change n to Type=None OR EOS if Single Frame Scene
                        DELETED = DELETED + 1                                       # Removed a scene                                                        
                    }                     
                } Else {
                    If(Single) {
                        (DEBUG) ? RT_DebugF("LINE %d : INS SC, Frame %d already Single Frame Scene, Ignoring",i+1,n,name=myName) : NOP
                    } Else if(Start==n) {
                        (DEBUG||Type!=1) ? RT_DebugF("LINE %d : INS SC, Frame %d already Start Of Scene, Ignoring",i+1,n,name=myName) : NOP
                        Assert(Type==1,RT_String("%sLINE %d : INTERNAL ERROR, Frame %d Type non-1(%d)",myName,i+1,n,Type))
                    } Else {
                        if(End==n) {
                            (DEBUG||Type!=2) ? RT_DebugF("LINE %d : INS SC, Frame %d Changing End Of Scene to Single Frame Scene",i+1,n,name=myName) : NOP
                            Assert(Type==2,RT_String("%sLINE %d : INTERNAL ERROR, Frame %d Type non-2(%d)",myName,i+1,n,Type))
                        } Else {
                            (DEBUG||Type!=0) ? RT_DebugF("LINE %d : INS SC, Frame %d Changing Mid Scene to Start Of Scene",i+1,n,name=myName) : NOP
                            Assert(Type==0,RT_String("%sLINE %d : INTERNAL ERROR, Frame %d Type non-0(%d)",myName,i+1,n,Type))
                        }                    
                        for(j=Start,n-1) {
                            RT_DBaseSetField(ScanDB,j,1,n-1)                    # Change all of scene EOSix to new end                            
                        }
                        NewType=(Start==n-1)?3:2
                        RT_DBaseSetField(ScanDB,n-1,2,NewType)                  # Change n-1 to Type=Single Frame Scene OR End Of Scene
                        for(j=n,End) {
                            RT_DBaseSetField(ScanDB,j,0,n)                      # Change all of scene SOSix to new start                            
                        }
                        NewType=(End==n)?3:1
                        RT_DBaseSetField(ScanDB,n,2,NewType)                    # Change n to Type= Single Frame Scene OR Start Of Scene
                        FLGS=RT_DBaseGetField(ScanDB,n,4)                       # n FLGS
                        RT_DBaseSetField(ScanDB,n,4,RT_BitOR(FLGS,$80000000))   # FLGS User INSERTED START                         
                        FLGS=RT_DBaseGetField(ScanDB,n-1,4)                     # n-1 FLGS
                        RT_DBaseSetField(ScanDB,n-1,4,RT_BitOR(FLGS,$80000000)) # FLGS User INSERTED END (or Single Frame Scene)                         
                        INSERTED = INSERTED + 1                                 # Added new scene                                                        
                    }
                }                              
            }            
        }
        if(INSERTED!=0 || DELETED!=0) {
            (DEBUG) ? RT_DebugF("%d Overrides Processed",INSERTED+DELETED,name=myName) : NOP
            (DEBUG) ? RT_DebugF("ReScan to update SCAN DBase SceneNo",name=myName) : NOP
            SceneNo = -1
            for(n=0,FC-1) {
                S=n
                SceneNo = SceneNo + 1
                Start=RT_DBaseGetField(ScanDB,n,0)
                End  =RT_DBaseGetField(ScanDB,n,1)
                Type =RT_DBaseGetField(ScanDB,n,2)
                Single=(Start==End && Start == n && Type==3)
                Assert(S==Start,RT_String("%s%d ] UPDATE INTERNAL ERROR : Start SOSix Mismatch(%d,%d)",myName,n,S,Start))
                (!Single)?Assert(Type==1 ,RT_String("%s%d ] UPDATE INTERNAL ERROR : Start Type non-1(%d)",myName,n,Type)):NOP
                EStart=RT_DBaseGetField(ScanDB,End,0)
                EEnd  =RT_DBaseGetField(ScanDB,End,1)
                EType =RT_DBaseGetField(ScanDB,End,2)
                Assert(S==EStart,RT_String("%s%d ] UPDATE INTERNAL ERROR : End SOSix Mismatch(%d,%d)",myName,n,S,EStart))
                Assert(End==EEnd,RT_String("%s%d ] UPDATE INTERNAL ERROR : End MisMatch(%d,%d)",myName,n,End,EEnd))
                (!Single)?Assert(EType==2 ,RT_String("%s%d ] UPDATE INTERNAL ERROR : End Type non-2(%d)",myName,n,EType)):NOP
                (Single) ?Assert(EType==3 ,RT_String("%s%d ] UPDATE INTERNAL ERROR : End Type non-3(%d)",myName,n,EType)):NOP                
                RT_DBaseSetField(ScanDB,Start,3,SceneNo)                                    
                RT_DBaseSetField(ScanDB,End  ,3,SceneNo)                                    
                for(i=Start+1,End-1) {
                    SOSix=RT_DBaseGetField(ScanDB,i,0)
                    EOSix=RT_DBaseGetField(ScanDB,i,1)
                    Type =RT_DBaseGetField(ScanDB,i,2)
                    Assert(Start==SOSix,RT_String("%s%d ] UPDATE INTERNAL ERROR : Start SOSix Mismatch(%d,%d)",myName,n,Start,SOSix))
                    Assert(End==EOSix  ,RT_String("%s%d ] UPDATE INTERNAL ERROR : End MisMatch(%d,%d)",myName,n,End,EOSix))
                    Assert(Type==0     ,RT_String("%s%d ] UPDATE INTERNAL ERROR : Start Type non-1(%d)",myName,n,Type))
                    RT_DBaseSetField(ScanDB,i,3,SceneNo)                    
                }
                n = End                                 # Next iteration n = End + 1
            }
            nAttribs=RT_DBaseGetAttrib(ScanDB,-1)
            OVERRIDDEN = RT_DBaseGetAttrib(ScanDB,nAttribs-4)
            TotOVR = OVERRIDDEN+INSERTED+DELETED
            RT_DBaseSetAttrib(ScanDB,nAttribs-4,TotOVR) # Count of Overridden
            (DEBUG) ? RT_DebugF("Total Accumulated Overrides = %d",TotOVR,name=myName) : NOP
        }
        RT_DBaseSetID(ScanDB,1,DBSC_Str2ID("SCAN"))     # Re-enable ScanDB validity
        T = RT_TimerHP - START_TIME
        (DEBUG) ? RT_DebugF("Total Time taken = %.2f Seconds  (%.2f Mins)",T,T/60.0,name=myName) : NOP 
    """)
    Return 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; 4th February 2015 at 07:56. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:29   #7  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #7 of many

Scene Change Utility funcs, Part 2
Code:
Function DBSC_WriteFiles(String ScanDB,String "Start_Fn",String "End_Fn",String "Range_Fn",String "Mid_Fn",String "ClipClopCmd_Fn",
    \ Bool "Comment",Bool "Comma",String "VideoFileName") {
/*
    Write Scene info to output files:- Start, End, Mid Frame and Range.
    Also writes a ClipClop command file for Start (clip 1) and End (clip 2) frames, used by DBSC_Select().
    ScanDB, SCAN DBase file created via DBSC_Scan.
    Comment, Default True writes additional Hash (#) separated info to file. False, omits extra info.
    Comma, Default True, use Comma (,) range separator, Else False uses SPACE range separator.
    VideoFilename, can supply clip name, added to Comment Header.  
*/
    myName="DBSC_WriteFiles: "
    START_TIME = RT_TimerHP
    Start_Fn=Default(Start_Fn,"")   End_Fn=Default(End_Fn,"")   Range_Fn=Default(Range_Fn,"")
    Mid_Fn=Default(Mid_Fn,"")       ClipClopCmd_Fn=Default(ClipClopCmd_Fn,"")  
         
    Comment=Default(Comment,True)
    Comma=Default(Comma,True)
    VideoFileName=Default(VideoFileName,"")
    VideoFileName=(VideoFileName!="") ? RT_FilenameSplit(VideoFileName,12) : ""
    SEP = RT_Ord((Comma) ? "," : " ") 
    GSCript("""
        DBSC_ScanValidate(ScanDB,MustExist=True,name=myName)          
        (Start_Fn      !="" && Exist(Start_Fn))       ? RT_FileDelete(Start_Fn)       : NOP
        (End_Fn        !="" && Exist(End_Fn))         ? RT_FileDelete(End_Fn)         : NOP
        (Range_Fn      !="" && Exist(Range_Fn))       ? RT_FileDelete(Range_Fn)       : NOP        
        (Mid_Fn        !="" && Exist(Mid_Fn))         ? RT_FileDelete(Mid_Fn)         : NOP        
        (ClipClopCmd_Fn!="" && Exist(ClipClopCmd_Fn)) ? RT_FileDelete(ClipClopCmd_Fn) : NOP        
        (Start_Fn      !="") ? RT_DebugF("Writing Start_Fn File '%s'",Start_Fn,name=myName)               : NOP
        (End_Fn        !="") ? RT_DebugF("Writing End_Fn File '%s'",  End_Fn,  name=myName)               : NOP
        (Range_Fn      !="") ? RT_DebugF("Writing Range_Fn File '%s'",Range_Fn,name=myName)               : NOP
        (Mid_Fn        !="") ? RT_DebugF("Writing Mid_Fn File '%s'",  Mid_Fn,name=myName)                 : NOP
        (ClipClopCmd_Fn!="") ? RT_DebugF("Writing ClipClopCmd_Fn File '%s'",  ClipClopCmd_Fn,name=myName) : NOP
        if(Comment) {
            nAttribs    = RT_DBaseGetAttrib(ScanDB,-1)
            Matrix      = RT_DBaseGetAttrib(ScanDB,nAttribs-1)
            ChromaWeight= RT_DBaseGetAttrib(ScanDB,nAttribs-2)
            Thresh      = RT_DBaseGetAttrib(ScanDB,nAttribs-3)            
            OVrCnt      = RT_DBaseGetAttrib(ScanDB,nAttribs-4)
            dFact       = RT_DBaseGetID(ScanDB,5)
            dMinim      = RT_DBaseGetID(ScanDB,6)
            dMinLen     = RT_DBaseGetID(ScanDB,7)
            dCorr       = RT_DBaseGetID(ScanDB,8)
            DupTh       = RT_DBaseGetID(ScanDB,9)
            POV         = RT_DBaseGetID(ScanDB,10)
            dFlashFrames= RT_DBaseGetID(ScanDB,11)
            BAR =RT_StrPad("",86,"#")+Chr(10)
            HEAD=RT_String("#\n# DBSC: Scene Change @@@ Frames file : @ %s\n#\n",RT_LocalTimeString(File=False))
            VSTR=(VideoFileName=="") ? "" : RT_String("# SourceFile:- '%s'\n#\n",VideoFileName)
            ARG =RT_String("# dFact =%.2f : dMinim =%.2f : dMinLen   =%d : dCorr = %.2f\n# DupTh=%.2f : POV=%.2f : dFlashFrames=%d\n# Matrix=%d    : ChromaW=%.2f : Thresh = %.2f : Overides=%d\n#\n",
                \ dFact,dMinim,dMinLen,dCorr,DupTh,POV,dFlashFrames,Matrix,ChromaWeight,Thresh,OvrCnt)
            LAB=RT_StrPad("#             # SceneNo :  Start :    Mid :    End : Length",85)+"#"                        
            Z=RT_String("%s%s%s%s%s%s",BAR,HEAD,VSTR,ARG,BAR,LAB)
            Z=RT_StrReplace(Z,"@@@","%s") 
            (Start_Fn      !="") ? RT_WriteFile(Start_Fn,      Z,"START"       ,Append=True) : NOP
            (End_Fn        !="") ? RT_WriteFile(End_Fn,        Z,"END"         ,Append=True) : NOP
            (Range_Fn      !="") ? RT_WriteFile(Range_Fn,      Z,"RANGE"       ,Append=True) : NOP
            (Mid_Fn        !="") ? RT_WriteFile(Mid_Fn,        Z,"MID"         ,Append=True) : NOP
            (ClipClopCmd_Fn!="") ? RT_WriteFile(ClipClopCmd_Fn,Z,"CLIPCLOP_CMD",Append=True) : NOP
        }
        for(n=0,RT_DBaseRecords(ScanDB)-1) {
            Start=RT_DBaseGetField(ScanDB,n,0)  End  =RT_DBaseGetField(ScanDB,n,1)    SceneNo=RT_DBaseGetField(ScanDB,n,3)+1
            Mid = (Start + End)/ 2              Len = End-Start + 1
            if(!Comment) {
                (Start_Fn!="")       ? RT_WriteFile(Start_Fn,"%d"          ,Start        ,Append=True) : NOP            
                (End_Fn!="")         ? RT_WriteFile(End_Fn,  "%d"          ,End          ,Append=True) : NOP            
                (Range_Fn!="")       ? RT_WriteFile(Range_Fn,"%d%c%d"      ,Start,SEP,End,Append=True) : NOP            
                (Mid_Fn!="")         ? RT_WriteFile(Mid_Fn,  "%d"          ,Mid          ,Append=True) : NOP
                if(ClipClopCmd_Fn!="") {                    
                    RT_WriteFile(ClipClopCmd_Fn,  "%d%c%d",(Start==End)?3:1,SEP,Start,Append=True)
                    (Start!=End) ? RT_WriteFile(ClipClopCmd_Fn,  "2%c%d",SEP,End,Append=True) : NOP
                }                                        
            } Else {                
                Com = RT_String(" # %6d  : %6d : %6d : %6d : %6d",SceneNo,Start,Mid,End,Len)                 
                (Start_Fn!="") ? RT_WriteFile(Start_Fn,"%-13d%s", Start,Com,Append=True)       : NOP            
                (End_Fn!="")   ? RT_WriteFile(End_Fn  ,"%-13d%s", End,  Com,Append=True)     : NOP            
                (Range_Fn!="") ? RT_WriteFile(Range_Fn,"%s%s",RT_StrPad(RT_String("%d%c%d",Start,SEP,End),13),Com,Append=True) : NOP            
                (Mid_Fn!="")   ? RT_WriteFile(Mid_Fn  ,"%-13d%s", Mid,  Com,Append=True) : NOP
                if(ClipClopCmd_Fn!="") {                    
                    RT_WriteFile(ClipClopCmd_Fn,RT_String("%s%s",RT_StrPad(RT_String("%d%c%d",(Start==End)?3:1,SEP,Start),13),com),Append=True)
                   (Start!=End)?RT_WriteFile(ClipClopCmd_Fn,RT_String("%s%s",RT_StrPad(RT_String("%d%c%d",2,SEP,End),13),com),Append=True):NOP
                }                            
            }
            n    = End                                          # Next iteration n = End + 1, ie Start of Next Scene
        }
        T = RT_TimerHP - START_TIME
        RT_DebugF("Total Time taken = %.2f Seconds  (%.2f Mins)",T,T/60.0,name=myName) 
    """)             
}
__________________
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; 4th February 2015 at 07:57. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:31   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #8 of many

Clip Display funcs
Code:
Function DBSC_SubsClip(clip c,String InfoDB,String ScanDB,Bool "Subs",Bool "Metrics",Bool "Metrics2",String "name") {
/*
    DBSC_SubsClip(), Return clip optionally subtitled (metrics And/Or START OF SCENE : END OF SCENE Subtitles)
    InfoDB, INFO DBase file created via DBSC_CreateInfo().
    ScanDB, SCAN DBase as created via DBSC_Scan().
    Metrics,  Default True. Write RT_Subtitle Metrics to frame.
    Metrics2, Default True. Write RT_Subtitle Metrics2 to frame.
    Subs, Default True. Write Subtitles to frame, "START OF SCENE" and "END OF SCENE".
*/
    myName=Default(name,"DBSC_SubsClip: ")
    c
    FC=FrameCount
    Subs=Default(Subs,True)
    Metrics=Default(Metrics,True)
    Metrics2=Default(Metrics2,True)
    #
    InfoValid = DBSC_InfoValidate(InfoDB,MustExist=True,name=myName)
    Assert(InfoValid,RT_String("%sInfoDB failed Basic validation\n'%s'",myName,InfoDB))
    InfoValid =   
      \ RT_VarIsSame(RT_DBaseGetID(InfoDB,2),Width) && RT_VarIsSame(RT_DBaseGetID(InfoDB,3),Height) &&
      \ RT_VarIsSame(RT_DBaseGetID(InfoDB,4),DBSC_ColorSpaceIx(c)) &&
      \ RT_VarIsSame(RT_DBaseRecords(InfoDB),FC)
    Assert(InfoValid,RT_String("%sInfoDB failed Match To Clip validation\n'%s'",myName,InfoDB))
    Matrix      = RT_DBaseGetID(InfoDB,5)
    ChromaWeight= RT_DBaseGetID(InfoDB,6)
    Thresh      = RT_DBaseGetID(InfoDB,7)
    #
    ScanValid = DBSC_ScanValidate(ScanDB,MustExist=True,name=myName)
    Assert(ScanValid,RT_String("%sScanDB failed Basic validation\n'%s'",myName,ScanDB))
    ScanValid =   
      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,2),Width) && RT_VarIsSame(RT_DBaseGetID(ScanDB,3),Height) &&
      \ RT_VarIsSame(RT_DBaseGetID(ScanDB,4),DBSC_ColorSpaceIx(c)) &&
      \ RT_VarIsSame(RT_DBaseRecords(ScanDB),FC)
    Assert(ScanValid,RT_String("%sScanDB failed Match To Clip validation\n'%s'",myName,ScanDB))
    nAttribs=RT_DBaseGetAttrib(ScanDB,-1)    
    ScanValid = RT_VarIsSame(RT_DBaseGetAttrib(ScanDB,nAttribs-1),Matrix) && 
            \ RT_VarIsSame(RT_DBaseGetAttrib(ScanDB,nAttribs-2),ChromaWeight) &&
            \ RT_VarIsSame(RT_DBaseGetAttrib(ScanDB,nAttribs-3),Thresh)
    Assert(ScanValid,RT_String("%sScanDB failed Match Matrix/ChromaWeight/Thresh to InfoDB\n'%s'",myName,ScanDB))
    RT_Script = """
        n       = current_frame
        SC      = RT_DBaseGetField(ScanDB,n,2)
        @@  
        @@@  
        @@@@
        @@@@@
        @@@@@@
        Return Last    
    """
    RT_Met1 = """
        FC      = Framecount
        SOS     = RT_DBaseGetField(ScanDB,n,0)
        EOS     = RT_DBaseGetField(ScanDB,n,1)
        SceneNo = RT_DBaseGetField(ScanDB,n,3)+1
        FLGS    = RT_DBaseGetField(ScanDB,n,4) 
        A       = RT_DBaseGetField(InfoDB,Max(n-1,0),6)
        B       = RT_DBaseGetField(InfoDB,n,6)
        C       = RT_DBaseGetField(InfoDB,Min(n+1,FC-1),6)
        Ax = (A<DupTh)?Max(RT_FrameDifference(Last,Last,n,n-2,ChromaWeight),A): A
        Cx = (C<DupTh)?Max(RT_FrameDifference(Last,Last,n+1,n+3,ChromaWeight),C): C # If Diff(n+1,n+2) too low, use Diff(n+1,n+3)                                                                   
        PxDif   = RT_LumaPixelsDifferent(Last,Last,delta2=1,Thresh=1) * 100.0 / 255.0
        FLGS    = RT_DBaseGetField(ScanDB,n,4)
        CorrY   = RT_Lumacorrelation(Last,Last,n=n,n2=n+1)

        FS=(RT_BitAnd(FLGS,$C0000000)!=0)?"USER OVERRIDE":(RT_BitTst(FLGS,16))?"PIXELCOUNT OVERRIDE":
            \ RT_BitTst(FLGS,17)?"MULTIFLASH OVERRIDE" : (RT_BitTst(FLGS,15))?"FADE-TO-BLACK":""
    """
    RT_Met2="""
        Mn      = RT_DBaseGetField(InfoDB,n,0)
        Mx      = RT_DBaseGetField(InfoDB,n,1)
        MnMx    = RT_DBaseGetField(InfoDB,n,2)
        Med     = RT_DBaseGetField(InfoDB,n,3)
        AveY    = RT_DBaseGetField(InfoDB,n,4)
        StdY    = RT_DBaseGetField(InfoDB,n,5)
    """
    RT_Met1_Fn="""RT_Subtitle(FMT, n,SC,SceneNo,SceneCnt,n-SOS,SOS,EOS,EOS-SOS+1,Ax,B,Cx,PxDif,CorrY,OVR,FLGS,FS)"""
    RT_Met2_Fn="""RT_Subtitle(FMT2,mn,mx,MnMx,Med,AveY,StdY,align=1)"""
    INSERT_Script="""Last = (SC==1) ? STARTCLIP : (SC==2) ? ENDCLIP : (SC==3) ? SINGLECLIP : Last"""
    SUBS_Script="""
        SC      = RT_DBaseGetField(ScanDB,current_frame,2)
        Last = (SC==1) ? STARTCLIP : (SC==2) ? ENDCLIP : (SC==3) ? SINGLECLIP : Last
        Return Last                
    """
    GScript("""
        If(Metrics || Metrics2 || Subs) {
            SIZE = Round(Height/8.0)
            STARTCLIP = SUBS?SubTitle("START OF SCENE",Align=5,size=SIZE,y=(Height+SIZE)/2,text_color=$C080FF) : Last
            ENDCLIP   = SUBS?SubTitle("END OF SCENE"  ,Align=5,size=SIZE,y=(Height-SIZE)/2,text_color=$FF80C0) : Last
            SINGLECLIP=SUBS?SubTitle("START OF SCENE\nEND OF SCENE",Align=5,size=SIZE,y=(Height-SIZE)/2,text_color=$C0FF80,lsp=0):Last
            if(Metrics||Metrics2) {
                FMT="%d ]\nSC=%d#%d/%d:%d{S%d:E%d:L%d}\nPrv=%.2f Cur=%.2f Nxt=%.2f\nPxDif=%.2f%% : Corr=%.2f\nOvrCnt=%d : $%08X %s"
                FMT2="Mn=%d Mx=%d MMDf=%d Med=%d\nAve=%.2f Std=%.2f"
                nAttribs = RT_DBaseGetAttrib(ScanDB,-1)
                OVR      = RT_DBaseGetAttrib(ScanDB,nAttribs-4)                                   
                SceneCnt=RT_DBaseGetField(ScanDB,RT_DBaseRecords(ScanDB)-1,3)+1
                DupTh   = RT_DBaseGetID(ScanDB,8)
                Script = RT_StrReplace(RT_Script,"@@@@@@" ,(Metrics2?RT_Met2_Fn:""))
                Script = RT_StrReplace(Script   ,"@@@@@"  ,(Metrics?RT_Met1_Fn:""))
                Script = RT_StrReplace(Script   ,"@@@@"   ,(SUBS?INSERT_SCRIPT:""))
                Script = RT_StrReplace(Script   ,"@@@"   ,(Metrics2?RT_Met2:""))
                Script = RT_StrReplace(Script   ,"@@"    ,(Metrics||Metrics2?RT_Met1:""))
                Last.ScriptClip(Script,Args="InfoDB,ScanDB,FMT,FMT2,SceneCnt,STARTCLIP,ENDCLIP,SINGLECLIP,OVR,DupTh,ChromaWeight")
            } Else {
                Last.ScriptClip(SUBS_Script,Args="ScanDB,STARTCLIP,ENDCLIP,SINGLECLIP")     
            }                
        }
    """)
    return Last        
}

Function DBSC_StackSceneChanges(clip c,String InfoDB,String ScanDB,Bool "Subs",Bool "Metrics") {
/*
    DBSC_StackSceneChanges(), Return clip, End frame of a scene together with Stacked Start frame of following scene.
    
    InfoDB, INFO DBase file created via DBSC_CreateInfo().
    ScanDB, SCAN DBase as created via DBSC_Scan().
    Metrics, Default True. Write RT_Subtitle Metrics to frame.
    Subs, Default True. Write Subtitles to frame, eg "START OF SCENE" and "END OF SCENE", Single frame scene has both written.    
    Returns NO AUDIO.
*/
    myName="DBSC_StackSceneChanges: "
    Subs=Default(Subs,True)
    Metrics=Default(Metrics,True)
    DBSC_SubsClip(c,InfoDB,ScanDB,Metrics,Subs,name=myName)
    LT=RT_LocalTimeString                   Start_Fn=LT+"_Start.txt"             End_Fn  =LT+"_End.txt"
    DBSC_WriteFiles(ScanDB,Start_Fn,End_Fn) S=FrameSel(Last,cmd=Start_fn)   E=FrameSel(Last,cmd=End_fn)
    RT_FileDelete(Start_Fn)                 RT_FileDelete(End_Fn)
    S=S.Trim(1,0)                           E=E.Trim(0,E.FrameCount-2)
    (Width>=Height) ? StackVertical(E,S) : StackHorizontal(E,S)
    return Last.KillAudio        
}
__________________
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; 4th February 2015 at 07:59. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:31   #9  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #9 of many

SCSelect equivalent
Code:
Function DBSC_Select(clip Motion,String ScanDB,clip "StartClip", clip "EndClip",Clip "SingleClip") {
/*
    DBSC_Select(), Similar-ish to SCSelect()
    
    Motion, frames used where not Start nor End of scene, nor Single Frame scene,
    Start/End/Single clips default to Motion clip if not supplied.
    ScanDB, SCAN DBase as created via DBSC_Scan().
    StartClip, Frames used for Start Of Scene Frames, Default Motion clip.
    EndClip, Frames used for End Of Scene Frames, Default Motion clip.
    SingleClip, Frames used for Single frame Scene, Default Motion clip.
    Clip FrameCount's must be same as the ScanDB detection clip, (no other similarities to detection clip enforced).
    Returns NO AUDIO.
*/
    myName="DBSC_Select: "
    Motion    StartClip=Default(StartClip,Last)    EndClip=Default(EndClip,Last)  SingleClip=Default(SingleClip,Last)
    Assert(RT_VarIsSame(Last,StartClip,Sig=False),RT_String("%sDissimilar StartClip dimensions OR ColorSpace",myName))
    Assert(StartClip.FrameCount==FrameCount,RT_String("%sDissimilar StartClip FrameCount",myName))
    Assert(RT_VarIsSame(Last,EndClip,Sig=False),RT_String("%sDissimilar EndClip dimensions OR ColorSpace",myName))
    Assert(EndClip.FrameCount==FrameCount,RT_String("%sDissimilar EndClip FrameCount",myName))
    Assert(RT_VarIsSame(Last,SingleClip,Sig=False),RT_String("%sDissimilar SingleClip dimensions OR ColorSpace",myName))
    Assert(SingleClip.FrameCount==FrameCount,RT_String("%sDissimilar SingleClip FrameCount",myName))
    Valid=DBSC_ScanValidate(ScanDB,MustExist=True,name=myName)          
    Assert(Valid,RT_String("%sInvalid ScanDB",myName))    
    Assert(RT_DBaseRecords(ScanDB)==FrameCount,RT_String("%sScanDB Records != FrameCount",myName))    
    ClipClopCmd_Fn=RT_LocalTimeString+".Txt"
    DBSC_WriteFiles(ScanDB,ClipClopCmd_Fn=ClipClopCmd_Fn,Comment=False)
    Last.ClipClop(StartClip,EndClip,SingleClip,cmd=ClipClopCmd_Fn)
    RT_FileDelete(ClipClopCmd_Fn)
    return Last.KillAudio        
}
__________________
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; 4th February 2015 at 08:01. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th January 2015, 04:32   #10  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #10 of many

Dynamically changing borders detector (PART 1)
Code:
#######################################################
### DYNAMICALLY CHANGING BORDERS CROPPING FUNCTIONS ***    
#######################################################

Function DBSC_DynaCrop(clip c,String ScanDB,String "SpliceDB",int "W",int "H",String "Resizer",
    \ Int "CropLimit",Int "CropLimit_Left",Int "CropLimit_Top",Int "CropLimit_Right",Int "CropLimit_Bot",
    \ int "RLBT",int "LeftAdd",int "TopAdd",int "RightAdd",int "BotAdd",
    \ int "DissolveSkip",
    \ String "LogFn",String "LogTMPT",
    \ Float "CropThresh",Float "ATM",
    \ bool "Show",bool "Debug") {
/*

 DBSC_DynaCrop(). With Input SCanDB, Creates output SpliceDB and log, to crop dynamically changing borders from PROGRESSIVE clip.
  Requires RoboCrop v0.21+ for RoboCrop output LogFile, to get crop coords.
  As well as output SpliceDB, also outputs a user configurable log file (always outputs the log file).

 ScanDB, DBase as created via DBSC_Scan().
 SpliceDB filename, Optional default "", default "" produces no output DBase, only a LogFn log file.
   Where provided with an output SpliceDB filename, will:-
    If SpliceDB DOES NOT already Exist, Create zero record SpliceDB in STANDARD format.
    If SpliceDB DOES already Exist, Create SpliceDB in SAME format as existing DBase, but first initialled to zero Records.
   STANDARD Format SpliceDB consists of 12 Int fields and 1 string[256] field, ie to create zero record STANDARD format DB,
     use eg, RT_DBaseAlloc(SpliceDB,0,"iiiiiiiiiiiis")
     
     FieldNumber  Type     Contents
     0             Int     Start of Scene frame              
     1             Int     End of Scene frame
     2             Int     Input clip Width  (same for all DB).
     3             Int     Input clip Height (same for all DB).
     4             Int     Output clip resize Width  (same for all DB).
     5             Int     Output clip resize Height (same for all DB).
     6             Int     Scene Crop left (X) offset
     7             Int     Scene Crop left (Y) offset
     8             Int     Scene Abs Crop Width
     9             Int     Scene Abs Crop Heigth
     10            Int     Scene signed crop width (width relative)
     11            Int     Scene signed crop width (height relative)
     12            String  Resizer String (256 chars], Same for all DB
   You could provide an EXISTING SpliceDB with additional (to STANDARD) fields, where DBSC_DynaCrop() would 1st re-allocate with
   zero records (previous contents lost, but will have same number, type and size fields), and then the STANDARD fields are filled
   with the dynacrop data, any additional fields will be zeroed, ie Float==0.0, String=="".   
   You could later fill your addional (to STANDARD) fields in some fashion, with whatever you want via some other function of your
   own making. These additional user added fields could be accessed later via a DBSC_DynaSplice() 'Func' user function.             
     
 W,H, Output resize dimensions, Defaults to same size as input clip.
 Resizer, String, <Default = "Spline64Resize(_W_,_H_)">. Where '_W_' and '_H_' are replaced with output width and height in the function.
 CropLimit, Default 16, Default for all below Crop edges limits if not otherwise set below.
 CropLimit_Left, Default CropLimit. Maximum allowed border size on Left edge of clip.
 CropLimit_Top, Default CropLimit. Maximum allowed border size on Top edge of clip.
 CropLimit_Right, Default CropLimit. Maximum allowed border size on Right edge of clip.
 CropLimit_Bot, Default CropLimit. Maximum allowed border size on Bottom edge of clip.
 RLBT, Default 15($F). bit flags of edges to crop. 1=Top, 2=Bot, 4=Left, 8=Right. (1+2+4+8=15 = all sides) 
 LeftAdd, Default 0. Amount to add to detected Left edge, and before CropLimit enforced.
 TopAdd, Default 0. Amount to add to detected Top edge, and before CropLimit enforced.
 RightAdd, Default 0. Amount to add to detected Right edge, and before CropLimit enforced.
 BotAdd, Default 0. Amount to add to detected Bottom edge, and before CropLimit enforced.
 DissolveSkip, default 5. Number of frames to skip at either end of scene when detecting borders (try to avoid dissolves and wipes
   playing havoc with detections). Current scene must be at least 4 * DissolveSkip otherwise DissolveSkip ignored.    
 LogFn default "DynaCrop.log". User configurable output log file name.
 LogTMPT Log Template, Default="V_NNNN_ = Trim(_S_,_E_).Crop(_CX_,_CY_,_-CW_,_-CH_)._RSZ_"+Chr(9)+Chr(9)+"# Crop_W= _CW_ Crop_H= _CH_"
   Default produces eg "V0000 = Trim(0,215).Crop(2,4,-14,-6).Spline64Resize(640,400)    # Crop_W= 624 Crop_H= 390"
 ###
     Log TEMPLATE Replacements
      "_NNNN_" = trim/scene number, 0 relative
      "_S_" = Start frame Number, "_E_" = End frame number
      "_CX_", "_CY_", "_CW_","_CH_", Crop x,y,w,h,  "_-CW_" and "_-CH_" are -ve crop width  and height relative
      "_IW_", "_IH_" = Input clip width and height.
      "_W_", "_H_" = Resize width and height.
      "_RSZ_" = The resizer, defaulted or otherwise.

     Example:- Usage of DEFAULT output Log to Trim, Crop, Resize, and Splice [instead of DBSC_DynaSplice()].      
        Function SpliceTrimsString(String VideoString,int maxim,int "Wid",String "Func") {
            Func=Default(Func,"")
            HasFunc=(Func!="")
            Wid=Default(Wid,4)
            GSCript("""
                S=""
                for(i =0,maxim) {
                    S=(S!="" && HasFunc) ? RT_StrAddStr(S,".",Func) : S
                    if(S!="") {S=RT_StrAddStr(S,"+")}
                    S=RT_StrAddStr(S,VideoString+RT_NumberString(i,width=wid))  # RT_StrAddStr, Avoid v2.58 bug
                }
            """)
            return S
        }
        AviSource("Test.avi")
        FUNC="DBSC_Levels(Show=True)"             # DEMO user Func for DBSC_DynaSplice
        
        TRIMS=RT_ReadTxtFromFile("DynaCrop.log")
        Lines=RT_TxtQueryLines(TRIMS)                      # Total lines in text file
        Eval(TRIMS)                                        # Trim, Crop, Resize
        Eval(SpliceTrimsString("V",Lines-1,Func=Func))               # Splice trims
        Return last
 ###
 CropThresh is RoboCrop thresh, Default -32 (RoboCrop DEFAULTED AUTOTHRESH). Best leave alone, will auto adapt.
 ATM, RoboCrop ATM, Default 16.0. Best leave alone, will auto adapt.
 
 RETURN:- Returns clip that has been trimmed, cropped, resized and spliced, with optional info if SHOW=true.
    
*/
Oops, Edited in Blue. Managed to insert an old pre-DEMO version of script.
__________________
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 February 2015 at 14:50. Reason: Updated
StainlessS is offline   Reply With Quote
Old 6th January 2015, 16:33   #11  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Dynamically changing borders detector (PART 2)

Code:
    ROBOCROP_DEBUG=False
    DBUG=FALSE
    c
    myName="DBSC_DynaCrop: "
    Valid=DBSC_ScanValidate(ScanDB,MustExist=True,name=myName)          
    Assert(Valid,RT_String("%sInvalid ScanDB\n%s",myName,ScanDB))    
    Records=RT_DBaseRecords(ScanDB)
    Assert(Records==FrameCount,RT_String("%sScanDB Records != FrameCount",myName))
    SpliceDB=Default(SpliceDB,"")    
    c2 = 0
    _W_=Default(W,width) _H_=Default(H,height)
    Resizer=Default(Resizer,"Spline64Resize(_W_,_H_)")  # Resizer to use
    TResizer="t."+Resizer
    CropThresh=Float(Default(CropThresh,-32.0))         # Absolute Thresh
    ATM=Float(Default(ATM,16.0))                        # ATM Switched almost OFF
    RLBT=Default(RLBT,15)
    Assert(RLBT>=1 && RLBT<=15,RT_String("%sRLBT 1->15 Only",myName))
    LeftAdd=Default(LeftAdd,0) TopAdd=Default(TopAdd,0) RightAdd=Default(RightAdd,0) BotAdd=Default(BotAdd,0)
    CSX=RT_ColorSpaceXMod(c)  CSY=RT_ColorSpaceYMod(c,laced=False)
    CropLimit=Default(CropLimit,16) 
    CropLimit_Left = (Default(CropLimit_Left,CropLimit) + CSX/2) / CSX * CSX
    CropLimit_Top  = (Default(CropLimit_Top,CropLimit)  + CSY/2) / CSY * CSY  
    CropLimit_Right= (Default(CropLimit_Right,CropLimit)+ CSX/2) / CSX * CSX
    CropLimit_Bot  = (Default(CropLimit_bot,CropLimit)  + CSY/2) / CSY * CSY
    DissolveSkip=Default(DissolveSkip,5)
    Assert(DissolveSkip>=0 && DissolveSkip<=10,RT_String("%sDissolveSkip 0->10 only",myName))
    LogFn=Default(LogFn,"DBSC_DynaCrop.log")
    LogTMPT=Default(LogTMPT,RT_String("V_NNNN_ = Trim(_S_,_E_).Crop(_CX_,_CY_,_-CW_,_-CH_)._RSZ_\t\t# Crop_W= _CW_ Crop_H= _CH_"))
    Show=Default(Show,False) Debug=Default(Debug,false)
    (Exist(LogFn)) ? RT_FileDelete(LogFn) : NOP         # Delete existing Log
    EOL=Chr(10)
    FND=RT_String("_RSZ_\n_NNNN_\n_S_\n_E_\n_CX_\n_CY_\n_CW_\n_CH_\n_-CW_\n_-CH_\n_W_\n_H_\n_IW_\n_IH_\n")
    TmpLog="~DynaCropTmp_"+RT_LocalTimeString+".log"
    (Exist(TmpLog)) ? RT_FileDelete(TmpLog) : NOP       # Delete existing TmpLog
    GScript("""
        if(SpliceDB!="") {
            if(Exist(SpliceDB)) {
                Fields=RT_DBaseFields(SpliceDB)
                Assert(Fields>=13,RT_String("%sInvalid SpliceDB, at least 12 Int fields and 1 String[256] field\n%s",myName,SpliceDB))
                for(i=0,11) {
                    Assert(RT_DBaseFieldType(SpliceDB,i)==1,RT_String("%sSpliceDB field %d is NOT type Int\n%s",myName,i,SpliceDB))
                }
                Assert(RT_DBaseFieldType(SpliceDB,12)==3,RT_String("%sSpliceDB field 12 is NOT type String\n%s",myName,SpliceDB))
                if(RT_DBaseRecords(SpliceDB) != 0) {
                    TypeString="iiiiiiiiiiiis"
                    if(Fields>13) {
                        for(i=13,Fields-1) {
                            Type=RT_DBaseFieldType(SpliceDB,i)
                            sz=RT_DBaseFieldSize(SpliceDB,i)
                            TypeString=TypeString+Select(Type,"b","i","f",RT_String("s%d",sz),"b","f")
                        }
                    }
                    (DEBUG)?RT_DebugF("Re-Alloc zero record SpliceDB, TypeString=%s",TypeString,name=myName):NOP 
                    RT_DBaseAlloc(SpliceDB,0,TypeString)        
                } else {
                    (DEBUG)?RT_DebugF("Using existing zero record SpliceDB:- %s",SpliceDB,name=myName):NOP 
                }                
            } else {
                (DEBUG)?RT_DebugF("Allocating Default format SpliceDB:- %s",SpliceDB,name=myName):NOP 
                RT_DBaseAlloc(SpliceDB,0,"iiiiiiiiiiiis")        
            }
        }
        RoboCrop(SAMPLES=Max(Round(Records/100.0),32),ignore=0.2,laced=False,rlbt=RLBT,LogFn=TmpLog,LogAppend=false,Debug=ROBOCROP_DEBUG)
        Wid=Width Hit=Height
        ts=RT_ReadTxtFromFile(TmpLog)       Outer_x=RT_NumberValue(ts)
        ts=MidStr(ts,FindStr(ts," ")+1)     Outer_y=RT_NumberValue(ts)
        ts=MidStr(ts,FindStr(ts," ")+1)     Outer_w=RT_NumberValue(ts)
        ts=MidStr(ts,FindStr(ts," ")+1)     Outer_h=RT_NumberValue(ts)
        Outer_XR=c.Width-Outer_x-Outer_w Outer_YB=c.Height-Outer_y-Outer_h
        (DEBUG)?RT_DebugF("Outermost crop Coords = %d,%d,%d,%d (%dx%d)",Outer_x,Outer_y,Outer_XR,Outer_YB,Outer_w,Outer_h,name=myName):NOP
        Start=0 End=-1 SceneNo=0 SceneCount=RT_DBaseGetField(ScanDB,Records-1,3)+1 
        for(n=0,Records-1) {
            Start=n  End=RT_DBaseGetField(ScanDB,n,1)
            if(End-Start+1 >= DissolveSkip*4) {
                DStart=Start+DissolveSkip   DEnd=End-DissolveSkip    
            } Else {
                DStart=Start                DEnd=End
            }
            IGNORE=2.0 # Allow for significant CGI text
            CropC = RoboCrop(thresh=CROPTHRESH,atm=ATM,ignore=IGNORE,laced=False,rlbt=RLBT,start=DStart,end=DEnd,
                \ LogFn=TmpLog,LogAppend=false,Debug=ROBOCROP_DEBUG,LeftAdd=LeftAdd,TopAdd=TopAdd,RightAdd=RightAdd,BotAdd=BotAdd)
            ts=RT_ReadTxtFromFile(TmpLog)       XL=RT_NumberValue(ts)
            ts=MidStr(ts,FindStr(ts," ")+1)     YT=RT_NumberValue(ts)
            ts=MidStr(ts,FindStr(ts," ")+1)     CW=RT_NumberValue(ts)
            ts=MidStr(ts,FindStr(ts," ")+1)     CH=RT_NumberValue(ts)
            XR=(Wid-XL-CW) YB=(Hit-YT-CH)
            (DBUG)?RT_DebugF("XL=%d YT=%d XR=%d YB=%d",XL,YT,XR,YB,name=myName):NOP
            if(XL>CropLimit_Left || YT>CropLimit_Top || XR>CropLimit_Right || YB>CropLimit_Bot) {
                RT_DebugF("*** Trim(%d,%d) Scene #%d, %d,%d,%d,%d",Start,End,SceneNo+1,XL,YT,XR,YB,name=myName)
                    (DEBUG)?RT_DebugF("*** RoboCrop, CROP LIMIT EXCEEDED, Repeating Call with RoboCrop Default AutoThresh & ATM & Ignore=1.0",name=myName):NOP
                    IGNORE=1.0  # Allow for lil bit CGI text
                    CropC = RoboCrop(ignore=IGNORE,laced=False,rlbt=RLBT,start=DStart,end=DEnd,
                        \ LogFn=TmpLog,LogAppend=false,Debug=ROBOCROP_DEBUG,LeftAdd=LeftAdd,TopAdd=TopAdd,RightAdd=RightAdd,BotAdd=BotAdd)
                    ts=RT_ReadTxtFromFile(TmpLog)       TXL=RT_NumberValue(ts)
                    ts=MidStr(ts,FindStr(ts," ")+1)     TYT=RT_NumberValue(ts)
                    ts=MidStr(ts,FindStr(ts," ")+1)     TCW=RT_NumberValue(ts)
                    ts=MidStr(ts,FindStr(ts," ")+1)     TCH=RT_NumberValue(ts)
                    TXR=(Wid-TXL-TCW) TYB=(Hit-TYT-CH)
                    (DBUG)?RT_DebugF("TMP: XL=%d YT=%d XR=%d YB=%d",TXL,TYT,TXR,TYB,name=myName):NOP
                    XL=(XL<=CropLimit_Left) ? XL : (TXL<=CropLimit_Left) ? TXL : Min(XL,TXL)
                    YT=(YT<=CropLimit_Top)  ? YT : (TYT<=CropLimit_Top)  ? TYT : Min(YT,TYT)                
                    XR=(XR<=CropLimit_Right)? XR : (TXR<=CropLimit_Right)? TXR : Min(XR,TXR)
                    YB=(YB<=CropLimit_Bot)  ? YB : (TYB<=CropLimit_Bot)  ? TYB : Min(YB,TYB)
                    (DBUG)?RT_DebugF("XL=%d YT=%d XR=%d YB=%d",XL,YT,XR,YB,name=myName):NOP
                if(XL>CropLimit_Left || YT>CropLimit_Top || XR>CropLimit_Right || YB>CropLimit_Bot) {
                    (DEBUG)?RT_DebugF("**** RoboCrop, LIMIT EXCEEDED, Repeating Call with RoboCrop Default AutoThresh & ATM=1.0 & Ingore=0.2",name=myName):NOP
                    IGNORE=0.2 # No CGI text
                    CropC = RoboCrop(ignore=IGNORE,laced=False,rlbt=RLBT,start=DStart,end=DEnd,ATM=1.0,
                        \ LogFn=TmpLog,LogAppend=false,Debug=ROBOCROP_DEBUG,LeftAdd=LeftAdd,TopAdd=TopAdd,RightAdd=RightAdd,BotAdd=BotAdd)
                    ts=RT_ReadTxtFromFile(TmpLog)       TXL=RT_NumberValue(ts)
                    ts=MidStr(ts,FindStr(ts," ")+1)     TYT=RT_NumberValue(ts)
                    ts=MidStr(ts,FindStr(ts," ")+1)     TCW=RT_NumberValue(ts)
                    ts=MidStr(ts,FindStr(ts," ")+1)     TCH=RT_NumberValue(ts)
                    TXR=(Wid-TXL-TCW) TYB=(Hit-TYT-CH)
                    (DBUG)?RT_DebugF("TMP: XL=%d YT=%d XR=%d YB=%d",TXL,TYT,TXR,TYB,name=myName):NOP
                    XL=(XL<=CropLimit_Left) ? XL : (TXL<=CropLimit_Left) ? TXL : CropLimit_Left 
                    YT=(YT<=CropLimit_Top)  ? YT : (TYT<=CropLimit_Top)  ? TYT : CropLimit_Top                
                    XR=(XR<=CropLimit_Right)? XR : (TXR<=CropLimit_Right)? TXR : CropLimit_Right
                    YB=(YB<=CropLimit_Bot)  ? YB : (TYB<=CropLimit_Bot)  ? TYB : CropLimit_Bot
                    (DBUG)?RT_DebugF("XL=%d YT=%d XR=%d YB=%d",XL,YT,XR,YB,name=myName):NOP
                }
            }
            Curr_w=Wid-XL-XR Curr_h=Hit-YT-YB     
            (DEBUG)?RT_DebugF("Trim(%d,%d) Scene #%d, %d,%d,%d,%d (W=%d,H=%d)",Start,End,SceneNo+1,XL,YT,-XR,-YB,Curr_w,Curr_h,name=myName):NOP
            XX=Outer_x+XL YY=Outer_y+YT WW=Curr_w -(c.Width -Outer_x-XL) HH=Curr_h -(c.Height-Outer_y-YT)
            REP =
                \ Resizer                           + EOL +
                \ RT_NumberString(SceneNo,width=4)  + EOL +
                \ RT_NumberString(Start)            + EOL +
                \ RT_NumberString(End)              + EOL +
                \ RT_NumberString(XX)               + EOL +
                \ RT_NumberString(YY)               + EOL +
                \ RT_NumberString(Curr_w)           + EOL +
                \ RT_NumberString(Curr_h)           + EOL +
                \ RT_NumberString(WW)               + EOL +
                \ RT_NumberString(HH)               + EOL +
                \ RT_NumberString(_W_)              + EOL +
                \ RT_NumberString(_H_)              + EOL +
                \ RT_NumberString(c.Width)          + EOL +
                \ RT_NumberString(c.Height)         + EOL
            LOG=RT_StrReplaceMulti(LogTMPT,FND,REP)
            RT_WriteFile(LogFn,"%s",LOG,append=True)
            if(SpliceDB!="") {
                RT_DBaseExtend(SpliceDB)                       # Add a single record to DBase
                RT_DBaseSetField(SpliceDB,SceneNo,0,Start)     # Scene start frame
                RT_DBaseSetField(SpliceDB,SceneNo,1,End)       # Scene End frame
                RT_DBaseSetField(SpliceDB,SceneNo,2,c.Width)   # Input clip width (same for all DB).
                RT_DBaseSetField(SpliceDB,SceneNo,3,c.Height)  # Input clip Height (same for all DB).                
                RT_DBaseSetField(SpliceDB,SceneNo,4,_W_)       # Output clip resize width (same for all DB).
                RT_DBaseSetField(SpliceDB,SceneNo,5,_H_)       # Output clip resize height (same for all DB).
                RT_DBaseSetField(SpliceDB,SceneNo,6,XX)        # Scene Crop left offset
                RT_DBaseSetField(SpliceDB,SceneNo,7,YY)        # Scene Crop top offset
                RT_DBaseSetField(SpliceDB,SceneNo,8,Curr_w)    # Scene Abs Crop width
                RT_DBaseSetField(SpliceDB,SceneNo,9,Curr_h)    # Scene Abs Crop height
                RT_DBaseSetField(SpliceDB,SceneNo,10,WW)       # Scene signed crop width (width relative)
                RT_DBaseSetField(SpliceDB,SceneNo,11,HH)       # Scene signed crop Height (height relative)
                RT_DBaseSetField(SpliceDB,SceneNo,12,Resizer)  # Resizer String, Same for all DB                                                
            }
            t=c.Trim(Start,End).Crop(XX,YY,WW,HH)
            t=Eval(TResizer)                                            # Resize using optional resizer
            t = (Show) ? t.RT_Subtitle("#%d/%d S=%d E=%d L=%d\nCrop(\aQ%d+\a-%d,\aQ%d+\a-%d,\aQ-%d\a--%d,\aQ-%d\a--%d) : %dx%d",
                    \ SceneNo+1,SceneCount,Start,End,End-Start+1,Outer_x,XL,Outer_y,YT,Outer_XR,XR,Outer_YB,YB,Curr_w,Curr_h,align=5) : t
            c2 = (c2.IsClip()) ? c2++t : t                             # Splice
            SceneNo=SceneNo+1
            n = End                                                        # Next iteration n = End + 1, ie Start of Next Scene        
        }
        RT_DBaseSetID(SpliceDB,0,DBSC_Str2ID("DYNS"))       
        (Exist(TmpLog)) ? RT_FileDelete(TmpLog) : NOP   # Delete temp Log
    """)
    return c2
}
__________________
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; 4th February 2015 at 08:04. Reason: Update
StainlessS is offline   Reply With Quote
Old 7th January 2015, 03:38   #12  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Dynamic Changing Borders Splicer
Code:
Function DBSC_DynaSplice(clip c,String SpliceDB,String "Func",Bool "DEBUG") {
/*
    DBSC_DynaSplice(), Function to trim, crop, resize and splice trims in SpliceDB DBase [as created via DBSC_DynaCrop()].
    Optionally can call user function 'Func' on each cropped and resized trim, prior to splicing.
    The Func arg must (if used) supply all required args (excluding initial clip) and parenthesis to call the required user function.
      Eg, Func="MyFunc(Show=True)", where will be called with explicit OOP style clip as 1st arg (ie DONT INCLUDE clip as first arg in
      Func string), called as in ClipName.MyFunc(Show=True) from within DBSC_DynaSplice().
    See below DBSC_Levels() for example usage.
      After viewing output of this function, might like to create OVERRIDE.TXT file and use DBSC_Override() to insert additional
    scene changes into ScanDB (it is easlier to find problem areas with remaining borders once this has been processed, also easier to
    spot blended scene transitions and force a scene change there).              
*/
    c
    myName="DBSC_DynaSplice: "
    Func=Default(Func,"")
    DEBUG=Default(DEBUG,TRUE)    
    Assert(SpliceDB!="",RT_String("%sNeed SpliceDB name",myName))
    Assert(Exist(SpliceDB),RT_String("%sSpliceDB Does not exist\n%s",myName,SpliceDB))
    Assert(RT_DBaseGetID(SpliceDB,0)==DBSC_Str2ID("DYNS"),RT_String("%sNot a SpliceDB\n%s",myName,SpliceDB))
    Records=RT_DBaseRecords(SpliceDB)  Fields=RT_DBaseFields(SpliceDB)
    Assert(Records>0,RT_String("%sInvalid SpliceDB, Zero records\n%s",myName,SpliceDB))
    Assert(Fields>=13,RT_String("%sInvalid SpliceDB, at least 12 Int fields and 1 String[256] field\n%s",myName,SpliceDB))
    oc=0
    GScript("""
        for(i=0,11) {Assert(RT_DBaseFieldType(SpliceDB,i)==1,RT_String("%sSpliceDB field %d is NOT type Int\n%s",myName,i,SpliceDB))}
        Assert(RT_DBaseFieldType(SpliceDB,12)==3,RT_String("%sSpliceDB field 12 is NOT type String\n%s",myName,SpliceDB))
        Resizer=RT_DBaseGetField(SpliceDB,0,12)       # Resizer String, "_W_" and "_H_" are width and Height
        OutW=RT_DBaseGetField(SpliceDB,0,4)
        OutH=RT_DBaseGetField(SpliceDB,0,5)        
        FND_S=RT_String("_W_\n_H_\n")        
        REP_S=RT_String("%d\n%d\n",OutW,OutH)
        Resizer="c.trim(Start,End).Crop(XX,YY,WW,HH)."+RT_StrReplaceMulti(Resizer,FND_S,REP_S)
        HasFunc=(Func!="")
        Func=(HasFunc)?"tmpc."+Func:Func        
        for(SceneNo=0,Records-1) {
            Start  = RT_DBaseGetField(SpliceDB,SceneNo,0)
            End    = RT_DBaseGetField(SpliceDB,SceneNo,1)
            Length = End-Start+1
            XX     = RT_DBaseGetField(SpliceDB,SceneNo,6)
            YY     = RT_DBaseGetField(SpliceDB,SceneNo,7)
            WW     = RT_DBaseGetField(SpliceDB,SceneNo,8)
            HH     = RT_DBaseGetField(SpliceDB,SceneNo,9)
            (DEBUG)?RT_DebugF("#%d Start=%d End=%d Length=%d Crop(%d,%d,%d,%d)",SceneNo,Start,End,Length,XX,YY,WW,HH,name=myName):NOP            
            tmpc=Eval(Resizer)
            tmpc=(HasFunc)?Eval(Func):tmpc
            oc = (oc.IsClip()) ? oc++tmpc : tmpc                             # Splice            
        }
    """)
    Return oc        
}
__________________
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; 4th February 2015 at 08:05.
StainlessS is offline   Reply With Quote
Old 11th January 2015, 15:13   #13  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
DEMO User function
Code:
Function DBSC_Levels(clip c,Float "Strength",Float "Gamma",Float "MinRngPerc",int "MinLen",Bool "Show",String "SpliceDB",Int "SceneNo") {
/*
    DBSC_Levels(), Function to DEMO calling of user function on each trim of Dynamic border cropped clip.
    This function can be called via DBSC_DynaSplice(func=FUNC) where FUNC argument string is eg 
      Func="DBSC_Levels(Strength=0.5,Show=True,SpliceDB=SpliceDB,SceneNo=SceneNo)".
      Where, SpliceDB is a DBase as created via DBSC_DynaCrop and SceneNo is record number in that DBase.
      Where using SpliceDB and SceneNo args then MUST be supplied exactly as "SpliceDB=SpliceDB,SceneNo=SceneNo" in the Func string.
      NOTE, the user function MUST have an initial clip argument, in this case clip c as above. Any other args would best be optional.
    NOTE, DBSC_DynaSplice() User functions MUST return clip of same attributes as supplied (size colorspace etc).
    See DBSC_DynaCrop() and DBSC_DynaSplice().    
*/
    c
    myName="DBSC_Levels: "
    Strength=Max(Min(Float(Default(Strength,0.5)),1.0),0.0)
    Gamma=Float(Default(Gamma,1.0))
    MinRngPerc=Max(Min(Float(Default(MinRngPerc,33.3)),100.0),0.0)
    MinLen=Default(MinLen,25)       # If less than MinLen frames, then ignore
    Show=Default(Show,False)
    SpliceDB=Default(SpliceDB,"")
    SceneNo=Default(SceneNo,-1)
    DBUG=FALSE                                                              # Set TRUE to Demo DBase and SceneNo Usage
    GScript("""
        Valid = (SpliceDB!="" && SceneNo!= -1)                              # Basic Validity test
        if(DBUG && Show && Valid) {
            Assert(RT_DBaseGetID(SpliceDB,0)==DBSC_Str2ID("DYNS"),RT_String("%sNot a SpliceDB\n%s",myName,SpliceDB))
            Start  = RT_DBaseGetField(SpliceDB,SceneNo,0)                   # SpliceDB Start Of Scene frame (0 relative)
            End    = RT_DBaseGetField(SpliceDB,SceneNo,1)                   # SpliceDB End Of Scene frame (0 relative)
            Length = End-Start+1
            RT_DebugF("#%d Start=%d End=%d Len=%d",SceneNo+1,Start,End,Length,name=myName) # Show SceneNo as 1 relative
        }
        if(MinLen<=Framecount && STRENGTH>0.0) { # Auto Luma Levelling            
            Eval(RT_QueryLumaMinMax(X=8,Y=8,W=-8,H=-8))                     # Ignore possible remaining borders
            if(IsRGB()) { CSMin = 0  CSMax = 255 }
            else        { CSMin = 16 CSMax = 235 }
            QLRng=QLMMMax-QLMMMin+1
            CSRng=CSMax-CSMin+1
            CSRngMin=CSRng*MinRngPerc/100.0
            if(QLRng >= CSRngMin) {   # Ignore if < MinRngPerc of CS range
                ALMin = Int(CSMin - ((CSMin - QLMMMin) * STRENGTH) + 0.5)   # Round Up
                ALMax = Int(CSMax - ((CSMax - QLMMMax) * STRENGTH))         # Round down
                if(ALMin!=CSMin || ALMax != CSMax) {
                    (Show)?RT_DebugF("Levels(%3d,%.2f,%3d,%d,%d,Coring=False)",ALMin,Gamma,ALMax,CSMin,CSMax,name=myName):NOP
                    Levels(ALMin,Gamma,ALMax,CSMin,CSMax,Coring=False)
                    (Show) ?RT_Subtitle("%sLevels(%3d,%.2f,%3d,%d,%d,Coring=False)",myName,ALMin,Gamma,ALMax,CSMin,CSMax) :NOP
                }
            } Else if(Show){
                RT_DebugF("Skip %3d,%3d Range=%d %.2f%%",QLMMMin,QLMMMax,QLRng,QLRng*100.0/CSRng,name=myName)
                RT_Subtitle("%sSkip %3d,%3d Range=%d %.2f%%",myName,QLMMMin,QLMMMax,QLRng,QLRng*100.0/CSRng)            
            }
        }
    """)

    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; 12th February 2015 at 14:58. Reason: Update
StainlessS is offline   Reply With Quote
Old 4th February 2015, 08:07   #14  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Scan Client Script

Code:
# Start DebugView before script to view output

Import("DBSC.avs")

VideoFileName = "AP10_Out.avi"

Start_Fn    = "Start_Frames.Txt"
End_Fn      = "End_Frames.Txt"
Range_Fn    = "Range_Frames.Txt"
Mid_Fn      = "Mid_Frames.Txt"
ClipClop_Fn = "ClipClop_Frames.Txt"

InfoDB = VideoFileName+"_Info.DB"                                              # INFO DBase
ScanDB = VideoFileName+"_Scan.DB"                                              # SCAN DBase

Avisource(VideoFileName)

RECYCLE_INFO_DB= True
RECYCLE_SCAN_DB= True

OVERRIDE       = "Override.txt"              # Override as Filename

DBSC_CreateInfo(InfoDB,RecycleDB=RECYCLE_INFO_DB)                            # Create INFO DB (REQUIRED), for fast scanning
DBSC_Scan(InfoDB,ScanDB,RecycleDB=RECYCLE_SCAN_DB)                           # Detect Scene Changes and store in ScanDB 

#DBSC_Override(ScanDB,OVERRIDE)
#DBSC_WriteFiles(ScanDB,Start_Fn,End_Fn,Range_fn,Mid_Fn,ClipClop_Fn,VideoFilename=VideoFileName,comment=True)

#Return Last

Return DBSC_SubsClip(InfoDB,ScanDB,Subs=True,Metrics=true,Metrics2=true)    # View detections
#Return DBSC_StackSceneChanges(Last,InfoDB,ScanDB)                           # Check detections START/END of scene STACKED.

# Or Drop through to below to demo DBSC_Select() 
#BilinearResize(Width*2,Height*2)    # DBSC_Select clips need only be same number of frames as ScanDB detection clip.  
SIZE = Round(Height/8.0)
MOTIONCLIP = SubTitle("MOTION",Align=5,size=SIZE,text_color=$80FFC0)
STARTCLIP  = SubTitle("START OF SCENE",Align=5,size=SIZE,y=(Height+SIZE)/2,text_color=$C080FF)
ENDCLIP    = SubTitle("END OF SCENE"  ,Align=5,size=SIZE,y=(Height-SIZE)/2,text_color=$FF80C0)
SINGLECLIP = SubTitle("START OF SCENE\nEND OF SCENE",Align=5,size=SIZE,y=(Height-SIZE)/2,text_color=$C0FF80,lsp=0)
Return DBSC_Select(MOTIONCLIP,ScanDB,STARTCLIP,ENDCLIP,SINGLECLIP)
__________________
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; 4th February 2015 at 08:39.
StainlessS is offline   Reply With Quote
Old 4th February 2015, 08:07   #15  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Dynamic Changing Borders Client script
Code:
Import("DBSC.avs")

VideoFileName = "AP10_Out.avi"

InfoDB   = VideoFileName+"_Info.DB"                                              # INFO DBase
ScanDB   = VideoFileName+"_Scan.DB"                                              # SCAN DBase
LogFn    = VideoFileName+"_User.Log"
SpliceDB = VideoFileName+"_Splice.DB"

RECYCLE_INFO_DB= True
RECYCLE_SCAN_DB= True
OVERRIDE = "Override.txt"              # Override as Filename

Avisource(VideoFileName)

DBSC_CreateInfo(InfoDB,RecycleDB=RECYCLE_INFO_DB)                            # Create INFO DB (REQUIRED), for fast scanning
DBSC_Scan(InfoDB,ScanDB,RecycleDB=RECYCLE_SCAN_DB)                           # Detect Scene Changes and store in ScanDB 

#DBSC_Override(ScanDB,OVERRIDE)

RLBT=$C                                                                      # Left and Right only


# Return one of two below funcs, DBSC_DynaCrop MUST have been called (at some time) before DBSC_DynaSplice 
 Return DBSC_DynaCrop(ScanDB,SpliceDB=SpliceDB,rlbt=RLBT,LeftAdd=0,RightAdd=0,TopAdd=1,BotAdd=1,LogFn=LogFn,Show=True,Debug=True)

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

# This one is best done is separate script when DBSC_DynaCrop() has already created Splice DBase, OR call DBSC_DynaCrop first
# and then comment out DBSC_DynaCrop line. 

#FUNC="DBSC_Levels(Show=True,SpliceDB=SpliceDB,SceneNo=SceneNo)"             # DEMO user Func for DBSC_DynaSplice
#FUNC="DBSC_Levels(Show=False)"
FUNC=RT_Undefined                                                            # Dont call user Func

#Return DBSC_DynaSplice(SpliceDB,Func)

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

# Or Even below if comment out both DBSC_DynaCrop and DBSC_DynaSplice, but with no user Func.

TRIMS=RT_ReadTxtFromFile(LogFn)
Lines=RT_TxtQueryLines(TRIMS)                      # Total lines in text file (Or RT_FileQueryLines)
Eval(TRIMS)										   # Eval trims,crop,resize
Eval(SpliceTrimsString("V",Lines-1,Func=Func))  		       # Splice trims
Return last

Function SpliceTrimsString(String VideoString,int maxim,int "Wid",String "Func") {
    Func=Default(Func,"")
    HasFunc=(Func!="")
    Wid=Default(Wid,4)
    GSCript("""
        S=""
        for(i =0,maxim) {
            S=(S!="" && HasFunc) ? RT_StrAddStr(S,".",Func) : S
            if(S!="") {S=RT_StrAddStr(S,"+")}
            S=RT_StrAddStr(S,VideoString+RT_NumberString(i,width=wid))  # RT_StrAddStr, Avoid v2.58 bug
        }
    """)
    return S
}
__________________
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 February 2015 at 14:51.
StainlessS is offline   Reply With Quote
Old 4th February 2015, 08:08   #16  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
DBSC Update to v0.04, zip in 1st post.
__________________
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; 4th February 2015 at 10:49.
StainlessS is offline   Reply With Quote
Old 12th February 2015, 14:44   #17  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Post #10 updated (FIXED): Oops, Managed to insert an old pre-DEMO version of script [EDIT: Added Func related stuff].

Example:- Usage of DEFAULT output Log to Trim, Crop, Resize, and Splice [instead of DBSC_DynaSplice()].
Code:
       Function SpliceTrimsString(String VideoString,int maxim,int "Wid",String "Func") {
            Func=Default(Func,"")
            HasFunc=(Func!="")
            Wid=Default(Wid,4)
            GSCript("""
                S=""
                for(i =0,maxim) {
                    S=(S!="" && HasFunc) ? RT_StrAddStr(S,".",Func) : S
                    if(S!="") {S=RT_StrAddStr(S,"+")}
                    S=RT_StrAddStr(S,VideoString+RT_NumberString(i,width=wid))  # RT_StrAddStr, Avoid v2.58 bug
                }
            """)
            return S
        }
        AviSource("Test.avi")
        FUNC="DBSC_Levels(Show=True)"             # DEMO user Func for DBSC_DynaSplice
        
        TRIMS=RT_ReadTxtFromFile("DynaCrop.log")
        Lines=RT_TxtQueryLines(TRIMS)                      # Total lines in text file
        Eval(TRIMS)                                        # Trim, Crop, Resize
        Eval(SpliceTrimsString("V",Lines-1,Func=Func))               # Splice trims
        Return last
Also changed in post#15

Code:
TRIMS=RT_ReadTxtFromFile(LogFn)
Lines=RT_TxtQueryLines(TRIMS)                      # Total lines in text file (Or RT_FileQueryLines)
Eval(TRIMS)										   # Eval trims,crop,resize
Eval(SpliceTrimsString("V",Lines-1,Func=Func))  		       # Splice trims
Return last

Function SpliceTrimsString(String VideoString,int maxim,int "Wid",String "Func") {
    Func=Default(Func,"")
    HasFunc=(Func!="")
    Wid=Default(Wid,4)
    GSCript("""
        S=""
        for(i =0,maxim) {
            S=(S!="" && HasFunc) ? RT_StrAddStr(S,".",Func) : S
            if(S!="") {S=RT_StrAddStr(S,"+")}
            S=RT_StrAddStr(S,VideoString+RT_NumberString(i,width=wid))  # RT_StrAddStr, Avoid v2.58 bug
        }
    """)
    return S
}
EDIT: Also might want to change to This, Post 13 Updated.
Code:
Function DBSC_Levels(clip c,Float "Strength",Float "Gamma",Float "MinRngPerc",int "MinLen",Bool "Show",String "SpliceDB",Int "SceneNo") {
/*
    DBSC_Levels(), Function to DEMO calling of user function on each trim of Dynamic border cropped clip.
    This function can be called via DBSC_DynaSplice(func=FUNC) where FUNC argument string is eg 
      Func="DBSC_Levels(Strength=0.5,Show=True,SpliceDB=SpliceDB,SceneNo=SceneNo)".
      Where, SpliceDB is a DBase as created via DBSC_DynaCrop and SceneNo is record number in that DBase.
      Where using SpliceDB and SceneNo args then MUST be supplied exactly as "SpliceDB=SpliceDB,SceneNo=SceneNo" in the Func string.
      NOTE, the user function MUST have an initial clip argument, in this case clip c as above. Any other args would best be optional.
    NOTE, DBSC_DynaSplice() User functions MUST return clip of same attributes as supplied (size colorspace etc).
    See DBSC_DynaCrop() and DBSC_DynaSplice().    
*/
    c
    myName="DBSC_Levels: "
    Strength=Max(Min(Float(Default(Strength,0.5)),1.0),0.0)
    Gamma=Float(Default(Gamma,1.0))
    MinRngPerc=Max(Min(Float(Default(MinRngPerc,33.3)),100.0),0.0)
    MinLen=Default(MinLen,25)       # If less than MinLen frames, then ignore
    Show=Default(Show,False)
    SpliceDB=Default(SpliceDB,"")
    SceneNo=Default(SceneNo,-1)
    DBUG=FALSE                                                              # Set TRUE to Demo DBase and SceneNo Usage
    GScript("""
        Valid = (SpliceDB!="" && SceneNo!= -1)                              # Basic Validity test
        if(DBUG && Show && Valid) {
            Assert(RT_DBaseGetID(SpliceDB,0)==DBSC_Str2ID("DYNS"),RT_String("%sNot a SpliceDB\n%s",myName,SpliceDB))
            Start  = RT_DBaseGetField(SpliceDB,SceneNo,0)                   # SpliceDB Start Of Scene frame (0 relative)
            End    = RT_DBaseGetField(SpliceDB,SceneNo,1)                   # SpliceDB End Of Scene frame (0 relative)
            Length = End-Start+1
            RT_DebugF("#%d Start=%d End=%d Len=%d",SceneNo+1,Start,End,Length,name=myName) # Show SceneNo as 1 relative
        }
        if(MinLen<=Framecount && STRENGTH>0.0) { # Auto Luma Levelling            
            Eval(RT_QueryLumaMinMax(X=8,Y=8,W=-8,H=-8))                     # Ignore possible remaining borders
            if(IsRGB()) { CSMin = 0  CSMax = 255 }
            else        { CSMin = 16 CSMax = 235 }
            QLRng=QLMMMax-QLMMMin+1
            CSRng=CSMax-CSMin+1
            CSRngMin=CSRng*MinRngPerc/100.0
            if(QLRng >= CSRngMin) {   # Ignore if < MinRngPerc of CS range
                ALMin = Int(CSMin - ((CSMin - QLMMMin) * STRENGTH) + 0.5)   # Round Up
                ALMax = Int(CSMax - ((CSMax - QLMMMax) * STRENGTH))         # Round down
                if(ALMin!=CSMin || ALMax != CSMax) {
                    (Show)?RT_DebugF("Levels(%3d,%.2f,%3d,%d,%d,Coring=False)",ALMin,Gamma,ALMax,CSMin,CSMax,name=myName):NOP
                    Levels(ALMin,Gamma,ALMax,CSMin,CSMax,Coring=False)
                    (Show) ?RT_Subtitle("%sLevels(%3d,%.2f,%3d,%d,%d,Coring=False)",myName,ALMin,Gamma,ALMax,CSMin,CSMax) :NOP
                }
            } Else if(Show){
                RT_DebugF("Skip %3d,%3d Range=%d %.2f%%",QLMMMin,QLMMMax,QLRng,QLRng*100.0/CSRng,name=myName)
                RT_Subtitle("%sSkip %3d,%3d Range=%d %.2f%%",myName,QLMMMin,QLMMMax,QLRng,QLRng*100.0/CSRng)            
            }
        }
    """)

    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; 12th February 2015 at 18:35.
StainlessS is offline   Reply With Quote
Old 14th February 2015, 09:17   #18  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
v0.051, see first post for zip.

Added a DBSC_DynaSplice User function to the DBSC.avs script, DBSC_ProcessByDAR.

Code:
Function DBSC_ProcessByDAR(clip c,String "SpliceDB",Int "SceneNo",Float "FDAR",
    \ Float "AR1",Float "AR2",Float "AR3",Float "AR4",Float "AR5",Float "AR6",Float "AR7",Float "AR8",
    \ String "FN",Bool "Show") {
/*
    DBSC_DynaSplice() User function (called by DBSC_DynaSplice on each scene).
    Creates ClipClop command text file based on letterbox cropped Display Aspect Ratio of each scene, enables selective
    processing based on a scenes Display Aspect Ratio where DAR changes within a clip.
    
    FDAR = Full Frame Display Aspect Ratio of Source clip (incl letterboxing).
    ARx Display Aspect Ratio of image area only (Excluding letterboxing)
    Always chooses one of the given ARx clip index numbers (ie never uses source clip ie clipclop clip 0
    unless all ARx Aspect ratios supplied as 0.0.)
    You can switch off ARx by setting to zero, however, you need to supply ClipClop Replacement clips up 
    to the maximum ARx number that may be non zero. Suggest always supply Source + 8 replacment clips to clipclop,
    and just use dummy clip where unused (ARx==0.0).
    
    Set Eg
    
    FUNC="DBSC_ProcessByDar(SpliceDB=SpliceDB,SceneNo=SceneNo,FDAR=4.0/3.0,Show=True)"

    And use in Dynacrop client script eg
        Return DBSC_DynaSplice(SpliceDB,func=FUNC)
    
    Use avs script eg (where ARx are processed clips for chosen AR)
      ClipClop(SourceClip,AR1,AR2,AR3,AR4,AR5,AR6,AR7,AR8,cmd="ClipClopCmd.txt",Show=True)
*/
    myName="DBSC_ProcessByDar: "
    c
    Assert(Defined(SpliceDB),RT_String("%sSpliceDB Not Supplied",myName))
    Assert(Defined(SceneNo),RT_String("%sSceneNo Not Supplied",myName))
    FDAR = Float(Default(FDAR,16.0/9.0))
    ###
    AR1  = Float(Default(AR1,2.40))                                         # If nearest to this, then use ClipClop clip 1
    AR2  = Float(Default(AR2,2.35))
    AR3  = Float(Default(AR3,1.85))
    AR4  = Float(Default(AR4,16.0/9.0))
    AR5  = Float(Default(AR5,1.66))
    AR6  = Float(Default(AR6,16.0/10.0))
    AR7  = Float(Default(AR7,1.5))
    AR8  = Float(Default(AR8,4.0/3.0))                                      # If nearest to this, then use ClipClop clip 8
    ###
    FN=Default(FN,"ClipClopCmd.txt")        
    Show=Default(Show,False)
    GScript("""
        Valid = (SpliceDB!="" && SceneNo>= 0)                               # Basic Validity test, DO NOTHING if bad
        if(Valid) {
            (SceneNo==0) ? RT_FileDelete(FN) : NOP             
            Start  = RT_DBaseGetField(SpliceDB,SceneNo,0)                   # SpliceDB Start Of Scene frame (0 relative)
            End    = RT_DBaseGetField(SpliceDB,SceneNo,1)                   # SpliceDB End Of Scene frame (0 relative)
            Length = End-Start+1
            IWID   = RT_DBaseGetField(SpliceDB,SceneNo,2)                   # Source Clip Width
            IHIT   = RT_DBaseGetField(SpliceDB,SceneNo,3)                   # Source Clip Height
            XX     = RT_DBaseGetField(SpliceDB,SceneNo,6)                   # Left Crop
            YY     = RT_DBaseGetField(SpliceDB,SceneNo,7)                   # Top Crop
            WW     = RT_DBaseGetField(SpliceDB,SceneNo,8)                   # Width
            HH     = RT_DBaseGetField(SpliceDB,SceneNo,9)                   # Height
            SAR    = (FDAR * IHIT)/ IWID                                    # Sample (pixel) Aspect ratio from source clip            
            AR     = (SAR * WW) / HH                                        # Display Aspect Ratio of cropped scene 
            AR0    = 99.9   BestAR = AR0 BestARix = 0 BestARdif=AR0         # If ALL ARx 0.0, Cause ClipCLop to choose source clip 0.
            
            TmpDif = Abs(AR-AR1) If(AR1>0.0 && TmpDif<BestARdif) {BestAR = AR1 BestARix = 1 BestARdif=TmpDif}
            TmpDif = Abs(AR-AR2) If(AR2>0.0 && TmpDif<BestARdif) {BestAR = AR2 BestARix = 2 BestARdif=TmpDif}
            TmpDif = Abs(AR-AR3) If(AR3>0.0 && TmpDif<BestARdif) {BestAR = AR3 BestARix = 3 BestARdif=TmpDif}
            TmpDif = Abs(AR-AR4) If(AR4>0.0 && TmpDif<BestARdif) {BestAR = AR4 BestARix = 4 BestARdif=TmpDif}
            TmpDif = Abs(AR-AR5) If(AR5>0.0 && TmpDif<BestARdif) {BestAR = AR5 BestARix = 5 BestARdif=TmpDif}
            TmpDif = Abs(AR-AR6) If(AR6>0.0 && TmpDif<BestARdif) {BestAR = AR6 BestARix = 6 BestARdif=TmpDif}
            TmpDif = Abs(AR-AR7) If(AR7>0.0 && TmpDif<BestARdif) {BestAR = AR7 BestARix = 7 BestARdif=TmpDif}
            TmpDif = Abs(AR-AR8) If(AR8>0.0 && TmpDif<BestARdif) {BestAR = AR8 BestARix = 8 BestARdif=TmpDif}
            
            RT_WriteFile(FN,"%d %d,%d  # SceneNo=%d Crop(%d,%d,%d,%d) CropAR=%.2f BestAR=%.2f",
                \ BestARix,Start,End,SceneNo+1,XX,YY,WW,HH,AR,BestAR,Append=True)
            RT_DebugF("#%d Start=%d End=%d Len=%d CropAR=%.2f BestAR=%.2f Clip=AR%d",
                \ SceneNo+1,Start,End,Length,AR,BestAR,BestARix,
                \ name=myName)
            if(Show) { 
                RT_Subtitle("#%d Start=%d End=%d Len=%d CropAR=%.2f BestAR=%.2f Clip=AR%d",
                    \ SceneNo+1,Start,End,Length,AR,BestAR,BestARix)
            }
        }
    """)
    Return Last # Return Clip Unchanged # EDIT: Unless Show=True
}
I cant update to current script as it uses quite a few updates to RT_Stats that will not be available for a time.
Previous posts not updated.

EDIT: Function above added due to this post: http://forum.doom9.org/showthread.php?t=171777

EDIT: Produces ClipClop command file, eg
Code:
5 0,254  # SceneNo=1 Crop(18,2,692,572) CropAR=1.29 BestAR=1.33
5 255,332  # SceneNo=2 Crop(16,2,694,572) CropAR=1.29 BestAR=1.33
5 333,347  # SceneNo=3 Crop(20,2,688,572) CropAR=1.28 BestAR=1.33
5 348,355  # SceneNo=4 Crop(10,2,698,572) CropAR=1.30 BestAR=1.33
5 356,390  # SceneNo=5 Crop(10,2,698,572) CropAR=1.30 BestAR=1.33
5 391,455  # SceneNo=6 Crop(12,2,690,572) CropAR=1.29 BestAR=1.33
5 456,468  # SceneNo=7 Crop(10,2,700,572) CropAR=1.31 BestAR=1.33
5 469,476  # SceneNo=8 Crop(8,2,702,572) CropAR=1.31 BestAR=1.33
5 477,488  # SceneNo=9 Crop(12,2,698,572) CropAR=1.30 BestAR=1.33
5 489,548  # SceneNo=10 Crop(10,2,700,572) CropAR=1.31 BestAR=1.33
5 549,569  # SceneNo=11 Crop(10,2,700,572) CropAR=1.31 BestAR=1.33
I did not have a suitable clip handy so is above always selecting the same clip (clip 5).
EDIT: In above changed script, would have always returned clip 8.

EDIT: Purpose, to create a ClipClop command file that selects clip based on scene Display Aspect Ratio of the image
only area (ie without letter boxing).
__________________
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; 17th February 2015 at 04:27.
StainlessS is offline   Reply With Quote
Old 14th February 2015, 12:09   #19  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Updated previous post, and zip updated to v0.051 in 1st post.

Changed slightly, and had a name change to DBSC_ProcessByDAR() [So much nicer than DBSC_Lyris() ]
__________________
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 20th April 2015, 22:50   #20  |  Link
johnmeyer
Registered User
 
Join Date: Feb 2002
Location: California
Posts: 2,685
I have a huge analog video transfer project (dozens of hours of home video) and I want to cut it into scenes. So, I finally have a reason to put this wonderful technology through the ringer.

My video is interlaced NTSC DV video, captured via Firewire. Scene detection works well most of the time, but I am having some failures that don't make sense. At the moment, I am using the default, using your "demo" script to drive the process. Here is a two-second clip where the scene detection fails:

Scene Detect Fail.avi

As you can see, the scene change actually happens in the middle of a frame, where one field in the frame is from the previous frame, and the other field is from the next frame.

If I bob the video, the scene is detected correctly.

Before I start playing around with all the detection parameters, I thought I'd ask whether I need to change something when dealing with interlaced video. I searched this thread and also the documentation for "interlaced," but didn't find anything.

Of course I can just simply bob the video and then divide the frame detect numbers by 2, but I thought I'd ask first.
johnmeyer is offline   Reply With Quote
Reply

Tags
scene change detection

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


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