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. |
|
|
Thread Tools | Search this Thread | Display Modes |
4th January 2015, 04:24 | #1 | Link |
HeartlessS Usurer
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) */
__________________
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 |
4th January 2015, 04:25 | #2 | Link |
HeartlessS Usurer
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 |
4th January 2015, 04:26 | #3 | Link |
HeartlessS Usurer
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 |
4th January 2015, 04:27 | #4 | Link |
HeartlessS Usurer
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 |
4th January 2015, 04:28 | #5 | Link |
HeartlessS Usurer
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 |
4th January 2015, 04:29 | #6 | Link |
HeartlessS Usurer
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 |
4th January 2015, 04:29 | #7 | Link |
HeartlessS Usurer
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 |
4th January 2015, 04:31 | #8 | Link |
HeartlessS Usurer
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 |
4th January 2015, 04:31 | #9 | Link |
HeartlessS Usurer
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 |
4th January 2015, 04:32 | #10 | Link |
HeartlessS Usurer
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. */
__________________
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 |
6th January 2015, 16:33 | #11 | Link |
HeartlessS Usurer
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 |
7th January 2015, 03:38 | #12 | Link |
HeartlessS Usurer
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. |
11th January 2015, 15:13 | #13 | Link |
HeartlessS Usurer
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 |
4th February 2015, 08:07 | #14 | Link |
HeartlessS Usurer
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. |
4th February 2015, 08:07 | #15 | Link |
HeartlessS Usurer
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. |
4th February 2015, 08:08 | #16 | Link |
HeartlessS Usurer
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. |
12th February 2015, 14:44 | #17 | Link |
HeartlessS Usurer
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 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 } 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. |
14th February 2015, 09:17 | #18 | Link |
HeartlessS Usurer
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 } 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 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. |
14th February 2015, 12:09 | #19 | Link |
HeartlessS Usurer
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 ??? |
20th April 2015, 22:50 | #20 | Link |
Registered User
Join Date: Feb 2002
Location: California
Posts: 2,695
|
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. |
Tags |
scene change detection |
Thread Tools | Search this Thread |
Display Modes | |
|
|