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 |
![]() |
#102 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
@Forensic
Ooooo, you really are a sycophant, but dont stop, me likee. ![]()
__________________
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 ??? |
![]() |
![]() |
![]() |
#103 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
RT_Stats new version v1.08, see 1st post.
Also contains new script function in zip: Code:
Function ImageSplicer(String "FileName",int "SzLimit",Float "FAR",Bool "AutoCrop",Float "AutoLevelStrength",bool "ShowAutoLevel",bool "ShowBorder", \ bool "Subs", Float "CropThresh",Float "FPS",int "WMod",int "HMod",int "Baffle",Float "ScanPerc", \ bool "Debug", bool "Debug_QBC",bool "Debug_QLMM",String "Resizer") { ########################################## # ImageSplicer v1.00 - 08 Jan 2013 # # Requires GScript, RT_Stats v1.08 and QueryBorderCrop.avs, QueryLumaMinMax.avs # # ImageSplicer, joins together images of different sizes into a sort of slideshow, auto cropping borders, auto levelling, resizing or original size, # border padding to chosen aspect ratio. # Gets max width/height of all images (after optional auto cropping) and creates a background 'canvas' based on SzLimit & FAR. # SzLimit==0: Images kept at original dimensions (post cropping), canvas made to encompass all cropped images. # SzLimit>0: The shorter canvas dimension (FAR) limited to AT MOST SzLimit, where images will be resized to fit canvas. # SzLimit<0: The shorter canvas dimension (FAR) set at abs(SzLimit) and images resized to fit canvas. # # Args:- # Filename: Default "*.BMP|JPG|JPE|JPEG|PNG|TGA|TIF|GIF|TIFF". Image Path and wildcard with mulitple pipe separated extensions. # SzLimit: Default=0, 0=No resize. Greater than 0 is limit on shorter dimension (see FAR), -ve resize to abs(SzLimit) shorter dimension. # FAR: Default 4.0/3.0. Output Frame Aspect Ratio, if FAR>=1.0 then SzLimit affects height, else affects width. # AutoCrop: Default=True. Crops borders off images. # AutoLevelStrength: Default 0.0, Auto luma leveling, range 0.0 -> 1.0. 0.0 is OFF. # ShowAutoLevel: Default False. If true then shows Auto leveling on right hande side of image ONLY. # ShowBorder: Default False. When padding to maintain Frame Aspect Ratio, borders are shown in red. # Subs: Default False. Shows Subtitled info on frames. # CropThresh: Default -32.0. Leave at default -32.0 to allow auto adjustment (EDIT by QueryBorderCrop). # CropThresh <=0.0 is auto thresh where thresh is set to (YPlaneMin + abs(CropThresh)) # CropThresh >0.0 is explicit threshold @ PC Levels, probably best avoided. # Default -32.0 will for single frames auto adjust cropthresh to -0.58219178 (-0.5 * 255.0/(235-16)), ie -0.5 scaled to PC levels. # CropThresh is then set to (YPlaneMin + abs(CropThresh)). This very sensitive threshold for single # frame clips is to avoid possibility of overcropping. User specified cropthresh of eg -1.0 would scale to YPlaneMin + (1.0*255/219) # RGB clips are sampled as YUV-Y @ PCLevels in QueryBorderCrop. See QueryBorderCrop. # FPS: Default 1.0. Frames Per Second of output clip. # WMod: Default 2. Output clip width is a multiple of WMod. # HMod: Default 2. Output clip height is a multiple of HMod. # Baffle: Default 3. Number of scanlines that must break a CropThresh to be accepted as Image. Avoids noise. Not usually altered. # ScanPerc: Default 49.0. Percentage of image dimensions to scan per side. Not usually altered. See QueryBorderCrop. # Debug: Default False. Show debug info via DebugView. Need DebugView: http://technet.microsoft.com/en-gb/sysinternals/bb545027 # Debug_QBC: Default False. Debug QueryBorderCrop. # Debug_QLMM: Default False. Debug QueryLumaMinMax. # Resizer: Default "Spline36Resize(_W_,_H_)", the resizer to use. "_W_" and "_H_" are replaced by the resize width & height. ##########################################
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 9th January 2013 at 15:47. |
![]() |
![]() |
![]() |
#104 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
v1.09 Bugfix, Fixed RT_RgbChanAve w==1 bug (always blue channel).
__________________
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 ??? |
![]() |
![]() |
![]() |
#105 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
Coming, bit pissed at the moment but thought someone may like the below adds's (what It've got sooooo far)..
RT_GetWorkingDir() Return current Working directory, directory of script, or dir set by SetWorkingDir(). The returned directory ends with a backslash. RT_GetFullPathName(string "name") Creates an absolute or full path name for the specified relative path 'name'. eg 'RT_GetFullPathName("test.avs")' might return "D:\avs\test.avs". Throws and error if cannot return path. (PS, pretty much there). RT_FileDelete(string fn) Delete file fn. Use with care. Returns 0 = OK. -1 = access denied / read only. -2 = Path not found OR is Directory. -3 = Unknown error. RT_FilenameSplit(string filename,int "get"=15) Splits the un-named filename string into component parts selected by 'get' bit flags arg and returns the parts joined together. 'Get' (default 15, 1 -> 15), If set, Bit 0=DRIVE, 1=Dir, 2=Name, 4=Extension. Add 1 for Drive (bit 0), add 2 for Dir (bit 1), add 4 for Name (bit 2), add 8 for Extension (bit 3). Some combinations do not make sense, eg Drive + Extension (1+8=9). Below sensible options. 1 = Drive (includes trailing ':') 2 = Dir (includes trailing '\') 3 = Drive + Dir 4 = Name 6 = Dir + Name 7 = Drive + Dir + Name 8 = Extension (includes leading '.') 12 = Name + Extension 14 = Dir + Name + Extension 15 = Drive + Dir + Name + Extension Assuming a current working directory of eg "D:\avs\avi", 'filename'="test.avi" and 'get'=15, returns "D:\avs\avi\test.avi", so given a relative filename and default 'get'=15, is equivalent to GetFullPathName(filename). Also, gonna add a func to get all Y(luma) stats info from a single call that is little more expensive than a single call. ie, Ave luma, min / max / max-min / Median / Yinrange / stddev, all in a single call, and all costing little more than a single RT call (single RT call about 30% slower than a built in Avisynth call (I thiink). Need some sleep. (wish I had some beer) [EDIT: pretty much there,.]
__________________
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; 28th February 2013 at 04:06. |
![]() |
![]() |
![]() |
#106 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
This script to extract security camera footage with movment only, removing static scenes.
In response to this thread here: http://forum.doom9.org/showthread.php?t=166974 Requires GScript, Grunt, RT_Stats v1.09+, FrameSelect and DegrainMedian Plugins. Code:
AVISource("D:\AVS\AVI\CAP.avi") # DO NOT USE DirectShowSource OR DENOISER THAT NEEDS LINEAR ACCESS eg HQDN3D # MUST SCAN STRAIGHT THROUGH, NO JUMPING ABOUT IN ShowMetrics OR MakeFramesCmd. Function ShowMetrics(clip c,float th,int "x",int "y",int "w",int "h",bool "dim",bool "fast") { # SUBTITLES, 1st number Frame number, 2nd Anchor frame number, Action, Diff between Frame and Anchor. c x=default(x,0) y=default(y,0) w=default(w,0) h=default(h,0) dim=Default(dim,true) Fast=Default(Fast,False) x = (x / 4) * 4 y = (y / 4) * 4 w = (w<=0) ? width() - X + W : w h = (h<=0) ? height() - Y + H : h w = (w / 4) * 4 h = (h / 4) * 4 # Mod 4 both dimensions cropped=Crop(x,y,w,h) (dim && (w!=width || h!=height)) ? levels(0,1.0,255,0,128).Overlay(cropped,x=X,y=Y,opacity=1.0) : Last Global ShowMetrics_Start=0 # Frame to start comparing with (Anchor) Global ShowMetrics_KEPT=0 # Count of kept frames Global ShowMetrics_PREV=0 # The 2nd most recent kept frame ScriptClip(""" d = RT_LumaDifference(Last,Last,n2=ShowMetrics_Start,x=x,y=y,w=w,h=h) keep=(current_frame==0 || current_frame==FrameCount()-1 || d>=th) Global ShowMetrics_KEPT = (keep) ? ShowMetrics_KEPT + 1 : ShowMetrics_KEPT SS=String(current_frame) + " ] (" + String(ShowMetrics_Start) + ") " + ((keep)?" KEEP":" DROP") + " Diff="+String(d,"%03.2f") +\ " KEPT=" + String(ShowMetrics_KEPT) + " " + String(ShowMetrics_KEPT*100.0 / (current_frame+1.0),"%03.2f") + "%" Global ShowMetrics_Start=(keep)?ShowMetrics_Prev:ShowMetrics_Start # Follow but NOT too closely (delayed by 1) Global ShowMetrics_Prev=(keep)?current_frame:ShowMetrics_Prev # 1 kept frame delay Subtitle(SS) """,After_Frame=True,args="th,x,y,w,h") # Needs Grunt for args SubTitle("Thresh = "+String(th,"%02.2f"),Align=1) return ((Fast)?AssumeFPS(250.0):Last) .KillAudio() } Function MakeFramesCmd(clip c,float th,int "x",int "y",int "w",int "h",String "FileName") { c x=default(x,0) y=default(y,0) w=default(w,0) h=default(h,0) FileName=Default(FileName,"FrameSelect_Cmd.Txt") (Exist(FileName)) ? RT_Call("cmd /c DEL /Q "+RT_QuoteStr(FileName),hide=true) : NOP # Delete existing x = (x / 4) * 4 y = (y / 4) * 4 w = (w<=0) ? width() - X + W : w h = (h<=0) ? height() - Y + H : h w = (w / 4) * 4 h = (h / 4) * 4 # Mod 4 both dimensions Global MakeFramesCmd_Start=0 # Frame to start comparing with (Anchor) Global MakeFramesCmd_PREV=0 ScriptClip(""" # We DONT compare with previous frame, we compare with previous KEEP frame to avoid slow (and sneaky) burglars. d = RT_LumaDifference(Last,Last,n2=MakeFramesCmd_Start,x=x,y=y,w=w,h=h) # 2 clip func, use 2 frame nos, not delta keep=(current_frame==0 || current_frame==FrameCount()-1 || d>=th) # Keep BOTH FIRST and LAST frame ALWAYS Global MakeFramesCmd_Start=(keep)?MakeFramesCmd_Prev:MakeFramesCmd_Start # Follow but NOT too closely Global MakeFramesCmd_Prev=(keep)?current_frame:MakeFramesCmd_Prev WriteFileIf(FileName, "(keep)", "current_frame", append=True) """,After_Frame=True,args="th,x,y,w,h,FileName") # Needs Grunt for args return AssumeFPS(250.0).KillAudio() } Function SelectFrames(clip c,String "FileName",bool "Show") { c FileName=Default(FileName,"FrameSelect_Cmd.Txt") Show=Default(Show,False) (Show) ? ShowTime() : NOP FrameSelect(CMD=FileName) # Returns NO audio } Function GetFrames(clip c,float th,int "x",int "y",int "w",int "h",String "FileName",clip "dclip",bool "Show") { Default(dclip,c) # Use denoised clip for scanning MakeFramesCmd(th,x,y,w,h,FileName) # Make the command file for FrameSelect() GSCript(""" For(i=0,framecount-1) { RT_YankChain(n=i) # Force Process, MakeFrames } c.SelectFrames(FileName,Show=Show) # Extract frames and return to client """) } ################### X=128 Y=172 W=-128 H=-0 # Area Of Interest, avoid eg passing traffic or timecode. THRESH =1.3 # Whatever, use ShowMetrics, need adjust, suggest 0.5 -> 1.5, need check against source. DENOISE=7 # DegrainMedian LimitY, 0 = OFF, higher stronger, Suggest 4 -> 8 DN_MODE=0 # DegrainMedian mode, see DegrainMedian docs, suggest 0 -> 2, higher weaker SHOW=True # Show original Time on final output # Optional Denoise, perhaps there are better ones, Produces identical results in below functions. (OK for non-linear access). dclip = (DENOISE>0) ? ConvertToYV12().DeGrainMedian(limitY=DENOISE,limitUV=0,mode=DN_MODE).GreyScale() : Last ################### ShowMetrics(dclip,THRESH,X,Y,W,H) # Show metrics to get best Threshold 'th'. Denoised clip shown in GrayScale. #MakeFramesCmd(dclip,THRESH,X,Y,W,H) # Make Frames Cmd file for SelectFrames() #SelectFrames(show=SHOW) # Return Frames with EXISTING frames Command file (after MakeFramesCmd) #GetFrames(THRESH,X,Y,W,H,dclip=dclip,show=SHOW) # Make Frames command file and then extract frames automatically in 1 pass.
__________________
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; 18th January 2013 at 12:04. |
![]() |
![]() |
![]() |
#107 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
Ref previous post:
I stuck a webcam out my window and captured about 2750 frames at about midnight. Running through previous script with Thresh set to 1.0, it reduced frame count to 145 fames with 1 bike and 3 cars passing, lights behind curtains going off and a fox passing close by. So, it does not seem too bad as it is, but might be happier if more sensitive to small localized movement. Would probably do better with LumaDifference (SAD, Sum Of Absolute Differences) being replaced with Sum Of Squared Differences. I'll add a func to RT_Stats to do that. Ooooh, there's that fox making a weird racket. EDIT: Old Webcam 640x480@15FPS Codec Indeo IV50, murky window glass with street lamp shining upon it.
__________________
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; 18th January 2013 at 02:59. |
![]() |
![]() |
![]() |
#108 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
Updated post #106.
Added dclip denoised detection clip + other mods.
__________________
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; 27th February 2013 at 10:14. |
![]() |
![]() |
![]() |
#109 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
New Version RT_Stats v1.10 17 Mar 2013. See first post.
Updates in brief: Code:
RT_Debug(string s1, ... , string sn,bool "name"=true) v1.10, Added name arg, setting false inhibits title "RT_Debug:" output, set s1 to your own title instead. RT_GetLastError() Return a error number describing previous system error (if available). Perhaps use after eg RT_Call. RT_GetLastErrorString() Return a string describing previous system error (if available). RT_TxtSort(String,int 'mode'=0) Function to sort a Chr(10) separated multiline string. The String arg is the multiline string, and 'mode' can be in range 0 to 11. v1.10, added modes 8 -> 11. 8 = Sort ascending, Integer number Strings 9 = Sort ascending, float number Strings 10= Sort decending, Integer number Strings 11= Sort decending, float number Strings RT_StrPad(String,Int n,string "c"=" ") Pads an unnamed string to at least int n (unnamed) length with first character of string c (Default SPACE). RT_GetWorkingDir() Return current Working directory, directory of script, or dir set by SetWorkingDir(). The returned directory ends with a backslash. RT_GetFullPathName(string "name") Creates an absolute or full path name for the specified relative path 'name'. eg 'RT_GetFullPathName("test.avs")' might return "D:\avs\test.avs". Throws and error if cannot return path. RT_FilenameSplit(string filename,int "get"=15) Splits the un-named filename string into component parts selected by 'get' bit flags arg and returns the parts joined together. 'Get' (default 15, 1 -> 15), If set, Bit 0=DRIVE, 1=Dir, 2=Name, 4=Extension. Add 1 for Drive (bit 0), add 2 for Dir (bit 1), add 4 for Name (bit 2), add 8 for Extension (bit 3). Some combinations do not make sense, eg Drive + Extension (1+8=9). Below sensible options. 1 = Drive (includes trailing ':') 2 = Dir (includes trailing '\') 3 = Drive + Dir 4 = Name 6 = Dir + Name 7 = Drive + Dir + Name 8 = Extension (includes leading '.') 12 = Name + Extension 14 = Dir + Name + Extension 15 = Drive + Dir + Name + Extension Assuming a current working directory of eg "D:\avs\avi\", 'filename'="test.avi" and 'get'=15, returns "D:\avs\avi\test.avi", so given a relative filename and default 'get'=15, is equivalent to RT_GetFullPathName(filename). RT_GetFileExtension(string s) Returns filename extension from the supplied filename, including '.' prefix. RT_FileDelete(string fn) Delete unnamed file fn. Use with care. Returns 0 = OK. -1 = access denied / read only. -2 = Path not found OR is Directory. -3 = Unknown error. RT_Undefined() Returns same as undefined() in v2.6. Defined(RT_Undefined()) would return false. RT_VarExist(string) Given the name (string) of the variable that you want to test for existence, returns true if exists, else false. Eg, #a=32 RT_Debug(string(RT_VarExist("a"))) # would output false to debugview unless '#a=32' uncommented. {Defined(a) would fail with error}. return colorbars() RT_Ord(string) Returns same as 'Ord' in v2.6, the ASCII code for the 1st letter in string (0 if empty string ""). RT_Timer() Returns time in seconds since start of process. RT_Ystats(clip,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false, float "threshold"=0.0,int "Matrix"=(width<=720?2:3),int "lo"=128,int "hi"=lo,int "flgs"=127,string "prefix"="YS_") Returns multiple results as for above single frame Luma sampling functions as Global Variables (prefixed with the prefix string arg). The args up to "interlaced", and "Matrix", are as for all other clip functions, "threshold" used only for "RT_YPlaneMin", "RT_YPlaneMax" and "RT_YPlaneMinMaxDifference" equivalent routines with same functionality. "lo" and "hi" are used only with the "RT_YInRange" equivalent routine with same functionality. The only new args are int "Flgs" which selects which results you want returned and the string "Prefix" that is prepended to the returned global variables. The actual return result is a copy of the flgs args with any non valid bits reset, ie the global variables that were set. Global variables are NOT altered for any function not selected in flgs. Flgs_Bit_Number Add_To_Flgs Equivalent_Funcion Global_Var_Set_Excluding_Prefix 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) 4 16($10) RT_AverageLuma() "yAve" (0.0->255.0) 5 32($20) RT_YPlaneStdev() "yStdev" (0.0->255.0) 6 64($40) RT_YInRange() "yInRng" (0.0->1.0) RT_Ystats() allows you to inquire multiple results simultaneously, with not much more overhead than calling a single individual routine, however, you should not select sub functions that you dont need as there may be an additional unnecessary overhead. The Default flgs=127($7F) are all bits set and so sets ALL global vars at once. RT_Ystats(flgs=1+2+16) would set global vars "YS_yMin", "YS_yMax" and "YS_yAve" for full frame current_frame. ****** SCRIPT CONVERSION TO PLUGIN FUNCTIONS ******** Below fns converted from previously existing script functions which will also be supplied so that you can see the logic, any changes after v1.10 plugin versions may not be reflected in the later script versions. RT_GetSAR(clip,dar float) Gets Sample (pixel) Aspect Ratio from DAR Display Aspect Ratio. RT_GetDAR(clip,sar float) Gets DAR Display Aspect Ratio from SAR, Sample (pixel) Aspect Ratio. RT_SignalDAR(float) # See Megui wiki (name change from SetDAR) Signal DAR to MEGUI. Sets global vars MeGUI_darX and MeGUI_darY which are read during MEGUI loading of AVS file. RT_GetCropDAR(clip,float DAR,float "X"=0,float "Y"=0,Float"W"=0,float "H"=0) Call prior to Crop/Resize with (possibly fractional) cropping to calc resultant DAR, X,Y,W,H are cropping coords DAR = FAR * SAR ::: FAR = DAR / SAR ::: SAR = DAR / FAR Cropping affects FAR & usually DAR, resizing does not affect DAR (unless also cropped). Resizing affects FAR and maybe SAR. We dont allow eg -ve X RT_QueryLumaMinMax(clip c,int "Samples"=24,float "Ignore"=0.2,String "Prefix"="QLMM",bool "DEBUG"=false,int "X"=0,int "Y"=0,int "W"=0,int "H"=0, \ int "Matrix"=(width<=720?2:3)) Prescan function to get Luma Min,Max for clip scanning Samples frames area x,y,w,h. Returns luma min/max as string Default eg "QLMMMin=25 QLMMMax=244", use eg "Eval(RT_QueryLumaMinMax())" to set variables for use in script. Samples:=24 = frames in clip to sample. Ignore:=0.2=Percentage of extreme pixels to ignore (noise) when getting luma min/max. Prefix:="QLMM"=Prefix for return string values. X=Y=W=H=0=Full frame, as crop, area to examine. DEBUG:=false= dont show. True=debug info. Need DebugView: http://technet.microsoft.com/en-gb/sysinternals/bb545027 Matrix:, For conversion of RGB to YUV-Y, 0 = Rec601, 1 = Rec709, 2 = PC601, 3 = PC709 Default for is 2(PC601) if width <= 720 else 3(PC709) : YUV not used Function RT_QueryBorderCrop(clip c,int "Samples"=24,Float "Thresh"=-32,bool "Laced"=true,int "XMod",int "YMod",int "WMod",int "HMod", \ bool "Relative"=false, String "Prefix"="QBCrop",int "RLBT"=15,bool "DEBUG"=false,float "Ignore"=0.2,int "Matrix"=(width<=720?2:3), \ Float "ScanPerc"=49.0,int "Baffle"=4, bool "ScaleAutoThreshRGB"=true,bool "ScaleAutoThreshYUV"=false) Prescan function to get coords for eg cropping black borders by sampling Samples frames. Planar, YUY2, RGB. Borders are detected by sampling at Samples frames, at scanlines (h/v) using AverageLuma (RGB is converted to Luma Y at either TV or PC levels, See Matrix). This sampling is done on all 4 sides of the frame. If a scanline Average luma is below or equal to Thresh, then is considered possible black border, above considered possible image, if Baffle [default=4] adjacent scanlines above Thresh, then it IS image. Simultaneously returns 4 sets of strings holding crop coords, here is one set: "QBCropX=8 QBCropY=8 QBCropW=640 QBCropH=480". String sets are Chr(10) separated, the 'exact found' coords set as above, not rounded at all and possibly throwing an error if you try to crop, although could use in eg resize. Second set using eg "QBCropXL=8", which is CropLess("L" trailer), ie when rounding for Xmod,WMod etc may leave some black border. Third set using eg "QBCropXM=8", which is CropMore, ie when rounding for Xmod,WMod etc may crop some image. Forth set using eg "QBCropXP=8", which is CropPlus, moves border positions an extra 2 pixels inwards on each edge and then as CropMore. The non-exact coords try to center the coords when cropping for larger WMod/HMod's so as to evenly crop from eg both left and right instead of just one side. Also returned in the return string is the used Threshold, perhaps set by AutoThresh, as eg "QBCropThresh=32.0" You can use eg Eval(QueryBorderCrop()) to set values into QBCropX, QBCropY,QBCropW,QBCropH etc variables. Function RT_YInRangeLocate(clip c,int "n"=current_frame,int "Delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,int "Baffle"=8,float "Thresh"=0.0, \ int "Lo"=128,int "Hi"=255,Int "Matrix"=(width<=720?2:3),String "Prefix"="YIRL_",bool "Debug"=false) Clip function to scan frame n+delta for an area where percentage of pixels in luma range Lo to Hi (inclusive) breaks a threshold over at least Baffle consecutive number of scanlines (all four sides). Returns True on Successful location else false. On success set Global var Coords. Args: n: default = current_frame in runtime environment. Delta: Default = 0 X:Y:W:H: All default=0 as in crop. Area to search, default is full frame. Baffle: Default=8, minimum number of scanlines that must have a percentage of pixels in range Lo to Hi, greater than Thresh. Avoids noise. Thresh: Default=0.0 (0.0->100.0). Percentage pixels above which breaks Threshold. Default is any pixel in the range Lo to Hi will break threshold. Lo: Default 128, lower bound of pixel values to search for. Hi: Default 255, upper bound of pixel values to search for. Matrix: Default for RGB is 2(PC601) if width <= 720 else 3(PC709) : YUV not used Prefix: Default "YIRL_", prefix for Global Var coords set on successful location of object, eg YIRL_X, YIRL_Y, YIRL_W, YIRL_H. Debug: Default false. If true outputs info to debugView.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 1st April 2013 at 19:58. |
![]() |
![]() |
![]() |
#110 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
See also previous post:
Here result of script included in RT_Stats v1.10 (EDIT: Required GScript) Code:
00000024 20:06:29 RT_Debug: RT_Stats Timing Test 00000025 20:06:29 RT_Debug: Timing 14x5(70) runs on 2500 Frames (Total Frames=175000) 00000026 20:07:06 RT_Debug: RT_YankChain 7.19Secs : 347.56FPS :: Basic GetFrame() [ADJUSTMENT] 00000027 20:07:58 RT_Debug: YPlaneMin 10.55Secs : 237.03FPS :: ADJUSTED 3.35Secs 745.38FPS 00000028 20:08:47 RT_Debug: RT_YPlaneMin 9.66Secs : 258.75FPS :: ADJUSTED 2.47Secs 1012.69FPS 00000029 20:09:39 RT_Debug: YPlaneMax 10.55Secs : 237.03FPS :: ADJUSTED 3.35Secs 745.38FPS 00000030 20:10:28 RT_Debug: RT_YPlaneMax 9.67Secs : 258.48FPS :: ADJUSTED 2.48Secs 1008.47FPS 00000031 20:11:23 RT_Debug: YPlaneMinMaxDif 11.03Secs : 226.74FPS :: ADJUSTED 3.83Secs 652.23FPS 00000032 20:12:13 RT_Debug: RT_YPlaneMinMaxDif 10.00Secs : 250.00FPS :: ADJUSTED 2.81Secs 890.63FPS 00000033 20:13:06 RT_Debug: YPlaneMedian 10.59Secs : 235.99FPS :: ADJUSTED 3.40Secs 735.15FPS 00000034 20:13:55 RT_Debug: RT_YPlaneMedian 9.73Secs : 256.82FPS :: ADJUSTED 2.54Secs 983.73FPS 00000035 20:14:38 RT_Debug: AverageLuma 8.63Secs : 289.86FPS :: ADJUSTED 1.43Secs 1745.81FPS 00000036 20:15:20 RT_Debug: RT_AverageLuma 8.44Secs : 296.30FPS :: ADJUSTED 1.24Secs 2009.12FPS 00000037 20:17:57 RT_Debug: Avisynth_ALL 31.44Secs : 79.52FPS :: ADJUSTED 24.24Secs 103.12FPS 00000038 20:18:56 RT_Debug: RT_Avisynth_ALL 11.83Secs : 211.35FPS :: ADJUSTED 4.64Secs 539.30FPS 00000039 20:19:56 RT_Debug: RT_ALL 11.87Secs : 210.62FPS :: ADJUSTED 4.68Secs 534.57FPS 00000040 20:19:56 RT_Debug: Total Runtime = 13.45 Mins Does 5 runs on each func, throws away fastest and slowest times and gets average of remaining three. Adjusted times have the timing for reading frames (eg HardDrive, codec, sourcefilter) subtracted from them. Avisynth_ALL samples each frame via all the Avisynth Native Luma Sampling runtime funcs, RT_Avisynth_ALL() [RT_YStats] does same but in 1 function. RT_ALL includes two additional Runtime funcs that are not native to Avisynth, ie 7 sampling funcs altogether at once. EDIT: If your results contradict above, post them here (above surprises the hell out of me, RT_ just standard CPP). Above results on Core 2 Duo duel core. Similar results speed ratios on single core Prescot and another P4 machine. EDIT: Below is the RT_Ystats() doc which is repeated here from previous post (is a bit hidden there): Code:
RT_Ystats(clip,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false, float "threshold"=0.0,int "Matrix"=(width<=720?2:3),int "lo"=128,int "hi"=lo,int "flgs"=127,string "prefix"="YS_") Returns multiple results as for above single frame Luma sampling functions as Global Variables (prefixed with the prefix string arg). The args up to "interlaced", and "Matrix", are as for all other clip functions, "threshold" used only for "RT_YPlaneMin", "RT_YPlaneMax" and "RT_YPlaneMinMaxDifference" equivalent routines with same functionality. "lo" and "hi" are used only with the "RT_YInRange" equivalent routine with same functionality. The only new args are int "Flgs" which selects which results you want returned and the string "Prefix" that is prepended to the returned global variables. The actual return result is a copy of the flgs args with any non valid bits reset, ie the global variables that were set. Global variables are NOT altered for any function not selected in flgs. Flgs_Bit_Number Add_To_Flgs Equivalent_Funcion Global_Var_Set_Excluding_Prefix 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) 4 16($10) RT_AverageLuma() "yAve" (0.0->255.0) 5 32($20) RT_YPlaneStdev() "yStdev" (0.0->255.0) 6 64($40) RT_YInRange() "yInRng" (0.0->1.0) RT_Ystats() allows you to inquire multiple results simultaneously, with not much more overhead than calling a single individual routine, however, you should not select sub functions that you dont need as there may be an additional unnecessary overhead. The Default flgs=127($7F) are all bits set and so sets ALL global vars at once. RT_Ystats(flgs=1+2+16) would set global vars "YS_yMin", "YS_yMax" and "YS_yAve" for full frame current_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; 18th March 2013 at 13:24. |
![]() |
![]() |
![]() |
#111 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
OOPS, mismatch in docs, script YInRangeLocate.avs and RT_YInRangeLocate default Prefix,
docs say "YIRL" avs script "YIRL" and "YIRL_" in RT_YInRangeLocate. Have changed online docs to "YIRL_" and will update doc and avs script in next version to "YIRL_". Code:
Function RT_YInRangeLocate(clip c,int "n"=current_frame,int "Delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,int "Baffle"=8,float "Thresh"=0.0, \ int "Lo"=128,int "Hi"=255,Int "Matrix"=(width<=720?2:3),String "Prefix"="YIRL_",bool "Debug"=false)
__________________
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 ??? |
![]() |
![]() |
![]() |
#112 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
Oh dear!
Another update, v1.11 19 Mar 2013. Last minute change to v1.10, I missed out a '!' in check on clips in RT_LumaCorrelation and RT_LumaDifference, so they will give a "Must Have Two Clips" type error. Fixed here in v1.11. See 1st post or in sig. Also posted a request for a name of new func here (in developers forum):- LINK REMOVED, THINK I MADE A BOOBOO If you have a better name then please submit. As a temp measure, v1.11 includes func as RT_LumaSNSSD() # Scaled Normalized Sum Of Squared Differences. Code:
RT_LumaSNSSD(clip,clip2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0, int "n2"=current_frame,int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(width<=720?2:3)) Returns FLOAT value Scaled Normalized Sum of Squared Differences. (0.0 -> 255.0) between clip frame (n+delta) area x,y,w,h, and clip2 frame (n2+delta2) area x2,y2,w,h. Note, 'x2' and 'y2' default to 'x' and 'y' respectively. Calculates Sum Of Squared Differences, takes the Square root of it and then scales in range 0.0 -> 255.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; 19th March 2013 at 23:46. |
![]() |
![]() |
![]() |
#114 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
Thank you kind sir, making lots of mistakes lately, must be getting senile.
Think I may also have dropped a B@ll@ck with the RT_LumaSNSSD() thing, it seems to be graphing linearly (not much different to SAD LumaDifference). Perhaps an early April fool thing. ![]() I was going to experiment with the RT_LumaSNSSD thing and had just put back the source into RT_Stats source when I found the "!" error in v1.10, as I was reluctant to remove it again for the v1.11 update I just pushed it out, but not sure that it is terribly useful. Have just now implemented the RT_LumaSSSD and that seems to be working as expected.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 19th March 2013 at 21:44. |
![]() |
![]() |
![]() |
#115 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
And again. New Version v1.12.
Code:
# PROBABLY REMOVED IN NEXT VERSION, I THINK I MADE A BOOBOO RT_LumaSNSSD(clip,clip2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0, int "n2"=current_frame,int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(width<=720?2:3)) Returns FLOAT value Scaled Normalized Sum of Squared Differences. (0.0 -> 255.0) between clip frame (n+delta) area x,y,w,h, and clip2 frame (n2+delta2) area x2,y2,w,h. Note, 'x2' and 'y2' default to 'x' and 'y' respectively. Calculates Sum Of Squared Differences, takes the Square root of it and then scales in range 0.0 -> 255.0. Code:
# CONSIDER IT EXPERIMENTAL RT_LumaSSSD(clip,clip2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0, int "n2"=current_frame,int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(width<=720?2:3)) Returns FLOAT value Scaled Sum of Squared Differences. (0.0 -> 255.0) between clip frame (n+delta) area x,y,w,h, and clip2 frame (n2+delta2) area x2,y2,w,h. Note, 'x2' and 'y2' default to 'x' and 'y' respectively. Calculates Sum Of Squared Differences, then scales in range 0.0 -> 255.0. 18.5 seconds in current version, ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 19th March 2013 at 22:43. |
![]() |
![]() |
![]() |
#116 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
New version, RT_Stats v1.13, see first post.
RT_QueryBorderCrop CropLess/CropMore modified (did not quite work as it should have).
__________________
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 ??? |
![]() |
![]() |
![]() |
#117 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
New Version, RT_Stats v1.14, see 1st post.
Added RT_FindStr. Mods:- RT_Debug, StrReplace fns, RT_NumberValue and RT_HexValue. Newly Added: Code:
RT_FindStr(String S,string Substr,bool "Sig"=True,int "Pos"=1) Finds unnamed string Substr in unnamed string S. Optional bool Sig: Default=True, does case significant comparison, insignificant if false. Optional int Pos: Default=1, is start position in string S to find string Substr. If Pos smaller than 1 or greater than length of string s, then will return 0, Not Found. Returns position (1 relative) of found string within the FULL LENGTH string S, or 0 if not found. Differs from Avisynth FindStr in Sig and Pos args and in that if either string S or string Substr is "" then will ALWAYS return 0, 'Not Found', Avisynth FindStr always returns 1 if SubStr="" even if S is also "". v1.14, New. Code:
RT_Debug(string s1, ... , string sn,bool "name"=true) Non-clip function. Takes one or more strings, joins them together and then outputs the combined string to OutputDebugString(), if strings are NOT space separated, it inserts a single space between them. Useful during development Compile-time/Run-time scripts to monitor status in real time. Can also output multiline string obtained via eg RT_ReadTxtFromFile. Name: bool Default=True. If False, then does NOT output "RT_Debug: " at the beginning of each line, you might want to replace with your own title in string s1. Use DebugView utility to view and capture output. http://technet.microsoft.com/en-gb/sysinternals/bb545027 Usage eg:- RT_Debug("["+String(42)+"]","Going pretty good so far @","Line "+String(19)) Would Produce this "RT_Debug: [42] Going pretty good so far @ Line 19" The above "RT_Debug:" title is present in all RT_Debug() output to the debugview window and you can (in DebugView), filter out all lines that do not contain "RT_Debug:" so as to skip stuff that is of no interest (eg AVSPMod generates some output, not sure but I think Avisynth v2.58 also generates lots of debug stuff). NOTE, Any program can send output to DebugView window, if no debug viewer is present, it normally just disappears down the plughole. In DebugView, filter for eg "RT_Debug:" to skip all the extraneous stuff generated by other plugins/programs. (In DebugView "Menu:Edit-Filter/Highlight", and enter "RT_Debug:". v1.14, No longer converts characters 127->255 to SPACE, only chr(2) converted to chr(1). Characters displayed via debugview are same as those via SubTitle, but those above 127 are dissimilar to the ones produced via Avisynth source Info.h, used during eg plugin metrics display. Example to show characterset with both RT_Debug & Subtitle: # ShowCharacterset.avs # Requires GScript & RT_Stats v1.14+ S="" GSCript(""" for(y=0,15) { s=s+"$"+RT_Hex(y*16,2)+ " " for(x=0,15) { n=y*16+x c=(n==0 || n==9 || n==10 || n==13) ? Chr(1) : Chr(n) # Convert Odd Effect chars to NO GRAPHIC {Square} Chr(1) # NOTE, DebugView # Chr(0) {NUL} [Null or End of String], converted here to NO GRAPHIC Chr(1). # Chr(9) {TAB} [Horizontal TAB], produces SPACE, converted here to NO GRAPHIC Chr(1). # Chr(10) {LF} [Line Feed or NewLine], converted here to NO GRAPHIC Chr(1). # Chr(13) {CR} [Carriage Return], converted here to NO GRAPHIC Chr(1). # # Chr(2) {SOH} [Start Of Heading ], Produces ODD effect , converted internally by RT_Debug to a NO GRAPHIC Chr(1). s=s+c } s=s+Chr(10) } """) colorbars(width=320,height=320).Trim(0,-1) RT_Debug(s) s=RT_StrReplace(s,Chr(10),"\n") Subtitle(s,font="Courier New",lsp=0) return Last RT_StrReplace(string source,string find,string replace,bool "sig"=True) # Based on Algorithm by Vampiredom, Gavino & IanB. String args 'source', 'find' and 'replace' unnamed and compulsory. Takes a source string, searches for all occurences of find string and replaces the found strings with the replace string. Can use "" in replace string (only in replace) to delete the found substrings from the source string. Newlines are treated no differently to other characters, and could be replaced/deleted. v1.14, added 'sig' arg,default true is Case Significant (as previous version). Set false for case insignificant find string. RT_StrReplaceDeep(string source,string find,string replace,bool "sig"=True) String args 'source', 'find' and 'replace' unnamed and compulsory. Takes a source string, searches for all occurences of find string and replaces the found strings with the replace string. Can use "" in replace string (only in replace) to delete the found substrings from the source string. Newlines are treated no differently to other characters, and could be replaced/deleted. Differs from RT_StringReplace in that if length of replace < length of find string will rescan after a replacement to see if the replaced string combines with currently existing string to create another find string, If length replace >= find, then calls RT_StringReplace instead. Useful to replace eg " " with " ", (two spaces with 1 space), where more than two consecutive spaces would end up with more than one consecutive resulting space if using plain RT_StrReplace. v1.14, added 'sig' arg,default true is Case Significant (as previous version). Set false for case insignificant find string. RT_StrReplaceMulti(string source,string find,string replace,bool "sig"=True) String args 'source', 'find' and 'replace' unnamed and compulsory. Takes a source string, searches for all occurences of find substrings and replaces the found substrings with the replace substrings. Find string and Replace string are both multiline [Chr(10) separated] strings, both of n lines where find[i] and replace[i] are matched pairs, ie the first line of a multiline find is replaced by the first line of a multiline replace, etc. Can use "" in replace string (only in replace) to delete the found substrings from the source string. Differs from RT_StrReplace, in that both find and replace strings are multiline strings and MUST match in number of lines. Cannot use either carriage return [Chr(13)] or newline [Chr(10)] in find or replace as these are interpreted as end of current line, you would need to use RT_StrReplace() instead. eg S=RT_StrReplaceMulti("THE cat SAT.","SAT"+Chr(10)+"THE","sat"+Chr(10)+"The") produces "The cat sat.". v1.14, added 'sig' arg,default true is Case Significant (as previous version). Set false for case insignificant find string. RT_HexValue(String,"pos"=1) Returns an int conversion of the supplied hexadecimal string. Conversion will cease at the first non legal number base digit, without producing an error Fixes HexValue bug in 2.58 & 2.6a3. eg "FFFFFFFF" returns 2147483647 (0x7FFFFFFF) instead of the correct -1 (As most/all calculators) Bug is fixed in Avisynth v2.6a4. v1.14, Added optional pos arg default=1, start position in string of the HexString, 1 denotes the string beginning. Will return 0 if error in 'pos' ie if pos is less than 1 or greater than string length. RT_NumberValue(String,int "base"=10,int "pos"=1) Returns an int conversion of the supplied number base string. Base, (10, 2 -> 36) is the number base that the string uses. To convert a Decimal string to a Float, use Avisynth native "Value()" func. Conversion will cease at the first non legal number base digit, without producing an error. eg RT_NumberValue("1100",2) returns 12 from the binary string. v1.14, Added optional pos arg default=1, start position in string of the number string, 1 denotes the string beginning. Will return 0 if error in 'pos' ie if pos is less than 1 or greater than string length. Code:
00000004 04:48:40 RT_Debug: $00 00000005 04:48:40 RT_Debug: $10 00000006 04:48:40 RT_Debug: $20 !"#$%&'()*+,-./ 00000007 04:48:40 RT_Debug: $30 0123456789:;<=>? 00000008 04:48:40 RT_Debug: $40 @ABCDEFGHIJKLMNO 00000009 04:48:40 RT_Debug: $50 PQRSTUVWXYZ[\]^_ 00000010 04:48:40 RT_Debug: $60 `abcdefghijklmno 00000011 04:48:40 RT_Debug: $70 pqrstuvwxyz{|}~ 00000012 04:48:40 RT_Debug: $80 €‚ƒ„…†‡ˆ‰Š‹ŒŽ 00000013 04:48:40 RT_Debug: $90 ‘’“”•–—˜™š›œžŸ 00000014 04:48:40 RT_Debug: $A0 ** 00000015 04:48:40 RT_Debug: $B0 00000016 04:48:40 RT_Debug: $C0 00000017 04:48:40 RT_Debug: $D0 00000018 04:48:40 RT_Debug: $E0 00000019 04:48:40 RT_Debug: $F0
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 9th April 2013 at 12:06. |
![]() |
![]() |
![]() |
#118 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
New Version v1.15, see 1st post.
v1.15 pretty much same as v1.14, made small alteration to RT_YInRangeLocate, Internally, Baffle separately limited to dimensions on both axis. Also added below script to v1.15 zip. Code:
AVISource("D:\avs\test.avi") # Pick a test below #Return TestClip($FFFFFF).TweenFrames(LimitLo=200.0,LimitHi=255.0,Show=true) # Fix White frames PROGRESSIVE #Return TestClip($000000).TweenFrames(LimitLo=0.0,LimitHi=32.0,Show=true) # Fix Black frames PROGRESSIVE #Return TestClipI($FFFFFF).TweenFramesI(LimitLo=200.0,LimitHi=255.0,Show=true) # Fix White frames INTERLACED #Return TestClipI($000000).TweenFramesI(LimitLo=0.0,LimitHi=32.0,Show=true) # Fix Black frames INTERLACED Function TweenFrames(clip c,float "LimitLo",float "LimitHi",bool "show") { # TweenFrames() by StainlessS # PROGRESSIVE. Requires RT_Stats & MvTools 2 # Replace isolated bad frames eg Black or White with a frame tweened from those either side using MvTools, and RT_Stats. # LimitLo: is minimum luma value of frame to replace. Allows select, eg black/White. # LimitHi: is maximum luma value of frame to replace. # Show: Puts indicator on fixed frames. c LimitLo=Float(Default(LimitLo,200.0)) # Average Luma greater or equal to this eligible for replacement LimitHi=Float(Default(LimitHi,255.0)) # Average Luma lesser or equal to this eligible for replacement show=Default(show,False) Prev=DeleteFrame(FrameCount-1).DuplicateFrame(0) super = Prev.MSuper() backward_vectors = MAnalyse(super, isb = true,truemotion=true, delta=2) forward_vectors = MAnalyse(super, isb = false,truemotion=true, delta=2) inter = Prev.MFlowInter(super, backward_vectors, forward_vectors, time=50, ml=70) inter = (show) ? inter.Subtitle("FRAME FIXED") : inter CondS=""" ave=RT_AverageLuma() prv=RT_YDifference(delta=-1) nxt=RT_YDifference(delta=1) alt=RT_YDifference(current_frame-1,delta=2) clpn=(ave>=LimitLo && ave<=LimitHi && alt < prv && alt < nxt) ? 1 : 0 # RT_Debug(String(current_frame)+"]","Ave="+String(ave),"Prv="+String(prv),"Nxt="+String(nxt),"Alt="+String(alt),"ClpN="+String(clpn)) clpn """ CondS=RT_StrReplaceMulti(CondS,"LimitLo"+Chr(10)+"LimitHi",String(LimitLo)+Chr(10)+String(LimitHi)) ConditionalSelect(Last,CondS,Last,inter) # Fix bad frames return Last } Function TweenFramesI(clip c,float "LimitLo",float "LimitHi",bool "show") { # TweenFramesI() by StainlessS # INTERLACED. # Replace isolated bad fields eg Black or White with a field tweened from those either side using MvTools, and RT_Stats. # LimitLo: is minimum luma value of field to replace. Allows select, eg black/White. # LimitHi: is maximum luma value of field to replace. # Show: Puts indicator on fixed fields. c LimitLo=Float(Default(LimitLo,200.0)) # Average Luma greater or equal to this eligible for replacement LimitHi=Float(Default(LimitHi,255.0)) # Average Luma lesser or equal to this eligible for replacement show=Default(show,False) SEP=SeparateFields() Even=SEP.SelectEven() Prev=Even.DeleteFrame(FrameCount-1).DuplicateFrame(0) super = Prev.MSuper() backward_vectors = MAnalyse(super, isb = true,truemotion=true, delta=2) forward_vectors = MAnalyse(super, isb = false,truemotion=true, delta=2) inter = Prev.MFlowInter(super, backward_vectors, forward_vectors, time=50, ml=70) inter = (show) ? inter.Subtitle("EVEN FIELD FIXED") : inter CondS=""" ave=RT_AverageLuma() prv=RT_YDifference(delta=-1) nxt=RT_YDifference(delta=1) alt=RT_YDifference(current_frame-1,delta=2) clpn=(ave>=LimitLo && ave<=LimitHi && alt < prv && alt < nxt) ? 1 : 0 # RT_Debug(String(current_frame)+"] EVEN","Ave="+String(ave),"Prv="+String(prv),"Nxt="+String(nxt),"Alt="+String(alt),"ClpN="+String(clpn)) clpn """ CondS=RT_StrReplaceMulti(CondS,"LimitLo"+Chr(10)+"LimitHi",String(LimitLo)+Chr(10)+String(LimitHi)) # Import explicit into script EvenFixed=ConditionalSelect(Even,CondS,Even,inter) # Fix bad even fields Odd=SEP.SelectOdd() Prev=Odd.DeleteFrame(FrameCount-1).DuplicateFrame(0) super = Prev.MSuper() backward_vectors = MAnalyse(super, isb = true,truemotion=true, delta=2) forward_vectors = MAnalyse(super, isb = false,truemotion=true, delta=2) inter = Prev.MFlowInter(super, backward_vectors, forward_vectors, time=50, ml=70) inter = (show) ? inter.Subtitle("ODD FIELD FIXED",align=1) : inter CondS=RT_StrReplace(CondS,"EVEN","ODD") OddFixed=ConditionalSelect(Odd,CondS,Odd,inter) # Fix bad Odd fields Interleave(EvenFixed,OddFixed) Weave() return Last } Function TestClip(clip c,int "Color") { # Replace every 8th frame with blank. c Color=Default(Color,$FFFFFF) KillAudio() BAD=Last.BlankClip(color=Color) A=SelectEvery(8,0) B=SelectEvery(8,1) C=SelectEvery(8,2) D=SelectEvery(8,3) E=SelectEvery(8,4) F=SelectEvery(8,5) G=SelectEvery(8,6) Interleave(A,B,C,D,E,F,G,BAD) # every 8th frame replaced with BAD Return Trim(0,1000) } Function TestClipI(clip c,int "Color") { # Replace every 8th EVEN field and every 12th ODD field with a blank. Color=Default(Color,$FFFFFF) c=c.KillAudio() SEP=c.SeparateFields BAD=SEP.BlankClip(color=Color) EVEN=SEP.SelectEven() A=EVEN.SelectEvery(8,0) B=EVEN.SelectEvery(8,1) C=EVEN.SelectEvery(8,2) D=EVEN.SelectEvery(8,3) E=EVEN.SelectEvery(8,4) F=EVEN.SelectEvery(8,5) G=EVEN.SelectEvery(8,6) EVEN=Interleave(A,B,C,D,E,F,G,BAD) ODD=SEP.SelectODD() A=ODD.SelectEvery(12,0) B=ODD.SelectEvery(12,1) C=ODD.SelectEvery(12,2) D=ODD.SelectEvery(12,3) E=ODD.SelectEvery(12,4) F=ODD.SelectEvery(12,5) G=ODD.SelectEvery(12,6) H=ODD.SelectEvery(12,7) I=ODD.SelectEvery(12,8) J=ODD.SelectEvery(12,9) K=ODD.SelectEvery(12,10) ODD=Interleave(A,B,C,D,E,F,G,H,I,J,K,BAD) Interleave(EVEN,ODD) Weave() Return Trim(0,1000) } http://forum.doom9.org/showthread.php?t=167632 EDIT: Maybe TweenFramesI should be called TweenFields.
__________________
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 April 2013 at 19:15. |
![]() |
![]() |
![]() |
#119 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
New version RT_Stats v1.16. See 1st post.
Function added: Code:
RT_LumaSceneChange(clip,clip2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0, int "n2"=current_frame,int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(width<=720?2:3)) Returns FLOAT value (0.0 -> 255.0) scene change detection between clip frame (n+delta) area x,y,w,h, and clip2 frame (n2+delta2) area x2,y2,w,h. Note, 'x2' and 'y2' default to 'x' and 'y' respectively. Is implemented sort of like:- mt_lutxy(mt_polish("((x-y)/4)^2")).AverageLuma() where x=clip(n+delta) and y=clip2(n2+delta2). Scene change metric between current frame and next frame, whilst ignoring 32 pixels of crud at bottom:- SC = RT_LumaSceneChange(Last,Last,delta2=1,h=-32) and exactly the same thing again: SC = RT_LumaSceneChange(Last,Last,n2=current_frame+1,h=-32) There are two arg clips for flexibility, might usually both be same, but might want to measure against two separate clips and so implemented as above. Scene change detection between current frame top field and bottom field, whilst ignoring 32 pixels of crud at bottom:- SC = RT_LumaSceneChange(Last,Last,y2=1,interlaced=true,h=-32) # EDIT: Expect higher metrics here A threshold of about 80.0 is pretty good for a hi/lo motion clip, above is scene change, below not scene change although metrics before and after scene change would best be used as well. http://forum.doom9.org/showthread.ph...75#post1625975
__________________
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; 30th April 2013 at 20:10. |
![]() |
![]() |
![]() |
#120 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,137
|
New Version RT_Stats v1.17, see 1st post.
v1.17, Added RT_LumaMovement. RT_Ord mod. Code:
RT_LumaMovement(clip,clip2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0, int "n2"=current_frame,int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(width<=720?2:3), int "Mode"=0,int "BlkW"=32,int "BlkH"=32) Returns FLOAT value (0.0 -> 255.0) movement detection between clip frame (n+delta) area x,y,w,h, and clip2 frame (n2+delta2) area x2,y2,w,h. Note, 'x2' and 'y2' default to 'x' and 'y' respectively. There are two modes available, 0 (Default) = RT_LumaDifference() : 1 = RT_LumaSceneChange(). BLKW/BLKH (default 32), Block size. Minimum 8 (silently limited to frame dimensions). RT_LumaMovement() splits the frames into block sized lumps and calls the desired mode RT_LumaDifference or RT_LumaSceneChange function to get a metric for each of those blocks. The metric returned is the metric with the highest value, and so is more sensitive to localized movement. If Interlaced is true, then only every other horizontal scanline in BLKH will be scanned. v1.17, New. RT_Ord(string,int "pos"=1) Returns same as 'Ord' in v2.6, the ASCII code for the 1st letter in string (0 if empty string ""). v1.17, Added pos arg, default 1, ie 1st character in string. Returns 0 if pos < 1 or greater than string length. Could possibly use a string as a sort of BYTE sized int array containing non zero values. Code:
AVISource("D:\AVS\AVI\CAP4.avi") #.Trim(32,0) ############################################ # SecurityCamExtractMotion.AVS, v1.0, By StainlessS. # Requires RT_Stats v1.17, FrameSelect v1.03, GScript, Grunt, Maybe DeGrainMedian if required. # # DO NOT USE DirectShowSource OR DENOISER THAT NEEDS LINEAR ACCESS eg HQDN3D # MUST SCAN STRAIGHT THROUGH, NO JUMPING ABOUT IN ShowMetrics OR MakeFramesCmd. ############################################ X=32 Y=32 W=-32 H=-0 # Area Of Interest, avoid eg passing traffic or timecode. MODE =1 # For RT_LumaMovement. 0=RT_LumaDifference, 1=RT_LumaSceneChange, Metrics will change with Mode. BLKW =32 # Metrics will change with block size. For RT_LumaMovement(). BLKH =32 # THRESH =2.25 # Below KEEP. Use ShowMetrics, need check against source. About 3.0 for Mode 1. DENOISE=0 # DegrainMedian LimitY, 0 = OFF, higher stronger, Suggest 4 -> 8 DN_MODE=0 # DegrainMedian mode, see DegrainMedian docs, suggest 0 -> 2, higher weaker SHOW=True # Frame Info SHOWTIME=True # Show original Time on output ROBOLEVELS=False # AutoLevel, need differnt Thresh PC=False # PC Levels for ROBOLEVELS dclip = (ROBOLEVELS) ? RoboLevels(x=X,y=Y,W=W,h=H,pc=PC) : Last # Optional Denoise, perhaps there are better ones, (OK for non-linear access). dclip = (DENOISE>0) ? dclip.ConvertToYV12().DeGrainMedian(limitY=DENOISE,limitUV=0,mode=DN_MODE).GreyScale() : dclip ########################################## # Choose 1 of below options:- (uncomment) ########################################## # Show metrics to get best Threshold 'th'. Denoised clip shown in GrayScale. ShowMetrics(dclip,THRESH,X,Y,W,H,fast=true,showTime=SHOWTIME,mode=MODE,blkw=BLKW,blkh=BLKH) # Make Frames Cmd file for SelectFrames(), Must Play all way through. #MakeFramesCmd(dclip,THRESH,X,Y,W,H,mode=MODE,blkw=BLKW,blkh=BLKH) # Return Frames with EXISTING frames Command file (after MakeFramesCmd) #SelectFrames(show=SHOW,showTime=SHOWTIME) # Return NON-selected frames, for scrutiny, with EXISTING frames Command file (after MakeFramesCmd) #RejectedFrames(show=SHOW,showTime=SHOWTIME) # Make Frames command file and then extract frames automatically in 1 pass. #AutoGetFrames(THRESH,X,Y,W,H,dclip=dclip,show=SHOW,showTime=SHOWTIME,mode=MODE,blkw=BLKW,blkh=BLKH) AssumeFPS(250.0) return Last ########################################## Function RoboLevels(clip c,float "Strength",int "Samples",float "Ignore",Bool "QBC",Float "QBC_Thresh",int "X",int "Y",int "W",int "H", \ int "Matrix",bool "PC",bool "DEBUG",bool "Interlaced",bool "DoCrop",Bool "AutoGain") { c Frames=FrameCount Strength=Float(Default(Strength,0.95)) Samples=(!Defined(Samples)) ? 24 : (Samples > Frames) ? Frames : (Samples < 1) ? 1 : Samples Ignore=Float(Default(Ignore,0.2)) QBC=Default(QBC,False) QBC_Thresh=Float(Default(QBC_Thresh,-32.0)) QBCropXM = Default(X,0) QBCropYM = Default(Y,0) QBCropWM = Default(W,-0) QBCropHM = Default(H,-0) DoCrop = Default(DoCrop,True) AutoGain = Default(AutoGain,false) QBCropWM = (QBCropWM<=0) ? QBCropWM : Width -(QBCropXM+QBCropWM) QBCropHM = (QBCropHM<=0) ? QBCropHM : Height-(QBCropYM+QBCropHM) QBCropXP = QBCropXM+2 QBCropYP = QBCropYM+2 QBCropWP = QBCropWM-2 QBCropHP = QBCropHM-2 Matrix = Default(Matrix,(width <= 720) ? 2 : 3) PC=Default(PC,False) DEBUG=Default(DEBUG,False) Interlaced=Default(Interlaced,true) Assert(Strength>=0.0 && Strength <=1.0, "RoboLevels: 0.0 <= Strength <= 1.0") GScript(""" if(QBC) { QBCS=RT_QueryBorderCrop(samples=Samples,thresh=QBC_Thresh,debug=DEBUG,ignore=Ignore,laced=Interlaced,matrix=Matrix) Eval(QBCS) } if(Strength>0.0||AutoGain) { if(AutoGain) { (DEBUG)?RT_Debug("AutoGain"):NOP TMPW=QBCropWP/4*4 # Mod 4 for AutoGain TMPH=QBCropHP/4*4 # Mod 4 for AutoGain TMP=Crop(QBCropXP,QBCropYP,TMPW,TMPH) AutoGain(Last,TMP) } else { QLMMS=RT_QueryLumaMinMax(samples=Samples,ignore=Ignore,debug=DEBUG,X=QBCropXP,Y=QBCropYP,W=QBCropWP,H=QBCropHP,matrix=Matrix) (DEBUG)?RT_Debug(QLMMS):NOP Eval(QLMMS) if(IsRGB() || PC) { CSMin = 0 CSMax = 255 } else { CSMin = 16 CSMax = 235 } ALMin = Int(CSMin - ((CSMin - QLMMMin) * Strength) + 0.5) # Round Up ALMax = Int(CSMax - ((CSMax - QLMMMax) * Strength)) # Round down (DEBUG)? RT_Debug("Levels("+String(ALMin)+",1.0,"+String(AlMax)+","+String(CSMin)+","+String(CSMax)+",Coring=False)"):NOP Levels(ALMin,1.0,ALMax,CSMin,CSMax,Coring=False) # DO NOT use Coring } } else { (DEBUG) ? RT_Debug("No Auto Levels") : NOP } if(QBC && DoCrop) { RT_Debug("RoboLevels",String(QBCropXM),String(QBCropYM),String(QBCropWM),String(QBCropHM)) Crop(QBCropXM,QBCropYM,QBCropWM,QBCropHM) } """) return Last } Function ShowMetrics(clip c,float th,int "x",int "y",int "w",int "h",bool "dim",bool "fast",bool "Showtime",int "Mode",int "BlkW",int "BlkH") { # SUBTITLES, # LINE 1, 1st number Frame number, 2nd Anchor frame number (current comparison frame), Remainder, delayed KEPT frames (avoid dups). # LINE 2, Diff between Frame and Anchor, Action, KEPT Frame count, % of frames KEPT. c x=default(x,0) y=default(y,0) w=default(w,0) h=default(h,0) dim=Default(dim,true) Fast=Default(Fast,False) ShowTime=Default(ShowTime,True) Mode=Default(Mode,0) BlkW=Default(BlkW,32) BlkH=Default(BlkH,32) x = (x / 4) * 4 y = (y / 4) * 4 w = (w<=0) ? width() - X + W : w h = (h<=0) ? height() - Y + H : h w = (w / 4) * 4 h = (h / 4) * 4 # Mod 4 both dimensions cropped=Crop(x,y,w,h) (dim && (w!=width || h!=height)) ? levels(0,1.0,255,0,128).Overlay(cropped,x=X,y=Y,opacity=1.0) : Last Global ShowMetrics_KEPT=0 # Count of kept frames Global ShowMetrics_DEL7=0 Global ShowMetrics_DEL6=0 Global ShowMetrics_DEL5=0 Global ShowMetrics_DEL4=0 Global ShowMetrics_DEL3=0 Global ShowMetrics_DEL2=0 Global ShowMetrics_DEL1=0 Global ShowMetrics_DEL0=0 ScriptClip(""" d = RT_LumaMovement(Last,Last,n2=ShowMetrics_DEL7,x=x,y=y,w=w,h=h,mode=Mode,blkw=BlkW,blkh=BlkH) keep=(current_frame==0 || current_frame==FrameCount()-1 || d>=th) Global ShowMetrics_KEPT = (keep) ? ShowMetrics_KEPT + 1 : ShowMetrics_KEPT SS=String(current_frame) + "]{" + \ String(ShowMetrics_DEL7) + "}("+ String(ShowMetrics_DEL6) + "," + \ String(ShowMetrics_DEL5) + "," + String(ShowMetrics_DEL4) + "," + \ String(ShowMetrics_DEL3) + "," + String(ShowMetrics_DEL2) + "," + \ String(ShowMetrics_DEL1) + "," + String(ShowMetrics_DEL0) + ")\n" + \ "Diff="+String(d,"%-6.2f ") + ((keep)?"KEEP":"DROP") + \ " KEPT=" + String(ShowMetrics_KEPT) + " " + String(ShowMetrics_KEPT*100.0 / (current_frame+1.0),"%03.2f") + "%\n" + \ "Thresh="+String(th,"%.2f"+" Mode="+String(Mode)+" BlkW="+String(BlkW)+" BlkH="+String(BlkH)) Global ShowMetrics_DEL7=(keep)?ShowMetrics_DEL6:ShowMetrics_DEL7 # Follow but NOT too closely (delayed by 7) Global ShowMetrics_DEL6=(keep)?ShowMetrics_DEL5:ShowMetrics_DEL6 Global ShowMetrics_DEL5=(keep)?ShowMetrics_DEL4:ShowMetrics_DEL5 Global ShowMetrics_DEL4=(keep)?ShowMetrics_DEL3:ShowMetrics_DEL4 Global ShowMetrics_DEL3=(keep)?ShowMetrics_DEL2:ShowMetrics_DEL3 Global ShowMetrics_DEL2=(keep)?ShowMetrics_DEL1:ShowMetrics_DEL2 Global ShowMetrics_DEL1=(keep)?ShowMetrics_DEL0:ShowMetrics_DEL1 Global ShowMetrics_DEL0=(keep)?current_frame:ShowMetrics_DEL0 Subtitle(SS,lsp=0,font="Courier New",size=18) """,After_Frame=True,args="th,x,y,w,h,Mode,BlkW,BlkH") # Needs Grunt for args (ShowTime) ? ShowTime() : NOP return ((Fast)?AssumeFPS(250.0):Last) .KillAudio() } Function MakeFramesCmd(clip c,float th,int "x",int "y",int "w",int "h",String "FileName",int "Mode",int "BlkW",int "BlkH") { c x=default(x,0) y=default(y,0) w=default(w,0) h=default(h,0) FileName=Default(FileName,"FrameSelect_Cmd.Txt") Mode=Default(Mode,0) BlkW=Default(BlkW,32) BlkH=Default(BlkH,32) (Exist(FileName)) ? RT_FileDelete(FileName) : NOP # Delete existing x = (x / 4) * 4 y = (y / 4) * 4 w = (w<=0) ? width() - X + W : w h = (h<=0) ? height() - Y + H : h w = (w / 4) * 4 h = (h / 4) * 4 # Mod 4 both dimensions Global MakeFramesCmd_DEL7=0 # Frame to start comparing with (Anchor) Global MakeFramesCmd_DEL6=0 Global MakeFramesCmd_DEL5=0 Global MakeFramesCmd_DEL4=0 Global MakeFramesCmd_DEL3=0 Global MakeFramesCmd_DEL2=0 Global MakeFramesCmd_DEL1=0 Global MakeFramesCmd_DEL0=0 ScriptClip(""" # We DONT compare with previous frame, we compare with a previous KEPT frame to avoid slow (and sneaky) burglars. d = RT_LumaMovement(Last,Last,n2=MakeFramesCmd_DEL7,x=x,y=y,w=w,h=h,mode=Mode,blkw=BlkW,blkh=BlkH) keep=(current_frame==0 || current_frame==FrameCount()-1 || d>=th) # Keep BOTH FIRST and LAST frame ALWAYS Global MakeFramesCmd_DEL7=(keep)?MakeFramesCmd_DEL6:MakeFramesCmd_DEL7 Global MakeFramesCmd_DEL6=(keep)?MakeFramesCmd_DEL5:MakeFramesCmd_DEL6 Global MakeFramesCmd_DEL5=(keep)?MakeFramesCmd_DEL4:MakeFramesCmd_DEL5 Global MakeFramesCmd_DEL4=(keep)?MakeFramesCmd_DEL3:MakeFramesCmd_DEL4 Global MakeFramesCmd_DEL3=(keep)?MakeFramesCmd_DEL2:MakeFramesCmd_DEL3 Global MakeFramesCmd_DEL2=(keep)?MakeFramesCmd_DEL1:MakeFramesCmd_DEL2 Global MakeFramesCmd_DEL1=(keep)?MakeFramesCmd_DEL0:MakeFramesCmd_DEL1 Global MakeFramesCmd_DEL0=(keep)?current_frame:MakeFramesCmd_DEL0 WriteFileIf(FileName, "(keep)", "current_frame", append=True) """,After_Frame=True,args="th,x,y,w,h,FileName,Mode,BlkW,BlkH") # Needs Grunt for args return AssumeFPS(250.0).KillAudio() } Function SelectFrames(clip c,String "FileName",bool "Show",bool "Showtime") { c FileName=Default(FileName,"FrameSelect_Cmd.Txt") Show=Default(Show,False) ShowTime=Default(ShowTime,False) (ShowTime) ? ShowTime() : NOP FrameSelect(CMD=FileName,show=Show) # Returns NO audio } Function RejectedFrames(clip c,String "FileName",bool "Show",bool "Showtime") { c FileName=Default(FileName,"FrameSelect_Cmd.Txt") Show=Default(Show,False) ShowTime=Default(ShowTime,False) (Showtime) ? ShowTime() : NOP FrameSelect(CMD=FileName,show=Show,reject=True) # Returns NO audio } Function AutoGetFrames(clip c,float th,int "x",int "y",int "w",int "h",String "FileName",clip "dclip",bool "Show",bool "Showtime", \ int "Mode",int "BlkW",int "BlkH") { Default(dclip,c) # Use denoised clip for scanning Mode=Default(Mode,0) BlkW=Default(BlkW,32) BlkH=Default(BlkH,32) MakeFramesCmd(th,x,y,w,h,FileName,mode=MODE,blkw=BLKW,blkh=BLKH) # Make the command file for FrameSelect() GSCript(""" For(i=0,framecount-1) { RT_YankChain(n=i) # Force Process, MakeFrames } c.SelectFrames(FileName,Show=Show,showtime=Showtime) # Extract source frames and return to client """) } ![]() One clip about 11:00 PM, cut down to about 10% of frames, where about 25 vehicles, 3 cyclists, 2 pedestrians and one fox caused motion detection. Original clip about 18 mins. Dark, rain shimmering under street lamps. 2nd clip, about 02:00 AM cut down to about 3.5% of frames, where about 9 vehicles caused motion detection. Original clip about 18 mins. Dark, little activity.
__________________
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; 16th May 2013 at 15:45. |
![]() |
![]() |
![]() |
Tags |
averageluma, correlation, lumadifference, runtime |
Thread Tools | Search this Thread |
Display Modes | |
|
|