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. |
6th January 2023, 08:25 | #1 | Link |
Registered User
Join Date: Apr 2019
Posts: 217
|
Letterbox detector
Here the suppose final scripts.
LetterBox detector. Code:
video=LSMASHVideoSource("Filename").ConvertBits(8, dither=0).KillAudio() #video=FFmpegSource2("Filename").KillAudio() video src=last LeftA = 220 # For analysing border. TopA = 0 RightA = 220 BottomA = 0 Left = 240 # For fixing letterbox. Top = 0 Right = 240 Bottom = 0 Th1 = 18.0 # Threshold variables. Ensure black frames are the same blackness. Th2 = 17.0 # Ensure letterbox exist and fix letterbox blackness after levels/filter adjustment. Th3 = 16.0 # Ensure ImageMask isn't 100% black. Th4 = 150.0 # Detect white frames and fade in/out. Experimental Th4. LB = $008080 # $008080 Letterbox colour. $FF00FF - see changes for debugging. BorderMaskL = last.BlankClip().LetterBox(TopA, BottomA, LeftA, 0, $FFFFFF) # White where there is border, else black. Leftside. BorderMaskR = last.BlankClip().LetterBox(TopA, BottomA, 0, RightA, $FFFFFF) # White where there is border, else black. Rightside. BorderMask = last.BlankClip().LetterBox(TopA, BottomA, LeftA, RightA, $FFFFFF) # White where there is border, else black. ImageMask = BorderMask.Invert LBox=""" # YPMin = RT_YPlaneMin() FrameB = RT_YPlaneMax() # FrameW = RT_AverageLuma() BorderL = RT_YPlaneMax(Mask=BorderMaskL,MaskMin=128,MaskMax=255) # Measure area that is white in BorderMaskL. BorderR = RT_YPlaneMax(Mask=BorderMaskR,MaskMin=128,MaskMax=255) # Measure area that is white in BorderMaskR. Image = RT_YPlaneMax(Mask=ImageMask ,MaskMin=128,MaskMax=255) # Measure area that is white in ImageMask. if (FrameB <= Th1) { Levels(0, 1.0, 255, 0, 0, coring=false) # Subtitle("Black Frame",Size=64,align=5) # } else if (FrameW > Th4) { # Dissolve()# or use Vdub2 curve editor or whatever filter fixes the problem. Use 'Video Debug.avs' to check if white frames exist. # Subtitle("White Frame",Size=64,align=5) } else if (BorderL <= Th2 && BorderR <= Th2 && Image > Th3) { SmoothLevels(0, 1.0, 255, 8, 255, Lmode=2, brightSTR=100, chroma=100, limiter=0, useMT=10) Letterbox(top, bottom, left, right, color_yuv=LB) # Subtitle("Has Border",Size=64,align=5) } else { SmoothLevels(0, 1.0, 255, 4, 255, Lmode=2, brightSTR=500, chroma=100, limiter=0, useMT=10)#.SmoothTweak(brightness=0, contrast=1.0, saturation=1.0, hue1=0, hue2=0, Lmode=0, limiter=false, useMT=10) # Subtitle("No Border",Size=64,align=5) } Return Last """ GScriptClip(Last,LBox) #StackVertical(src.ColorYUV(analyze=true),last.ColorYUV(analyze=true)) StackHorizontal(src.ColorYUV(analyze=true),last.ColorYUV(analyze=true)) Return Last Code:
video=LSMASHVideoSource("Filename").ConvertBits(8, dither=0).KillAudio() #video=FFmpegSource2("Filename").KillAudio() video src=last Left = 220 Top = 0 Right = 220 Bottom = 0 Th1 = 16.0 # Threshold variables. Ensure black frames are the same blackness. Th2 = 16.0 # Ensure letterbox exist and fix letterbox blackness after levels/filter adjustment. Th3 = 16.0 # Ensure ImageMask isn't 100% black. Th4 = 150.0 # Detect white frames and fade in/out. Fade needs to be fix manually. BorderMaskL = last.BlankClip().LetterBox(Top, Bottom, Left, 0, $FFFFFF) # White where there is border, else black. Leftside. BorderMaskR = last.BlankClip().LetterBox(Top, Bottom, 0, Right, $FFFFFF) # White where there is border, else black. Rightside. BorderMask = last.BlankClip().LetterBox(Top, Bottom, Left, Right, $FFFFFF) # White where there is border, else black. ImageMask = BorderMask.Invert Debug=""" YPMin = RT_YPlaneMin() FrameB = RT_YPlaneMax() FrameW = RT_AverageLuma() BorderL = RT_YPlaneMax(Mask=BorderMaskL,MaskMin=128,MaskMax=255) # Just measure area that is white in BorderMaskL. BorderR = RT_YPlaneMax(Mask=BorderMaskR,MaskMin=128,MaskMax=255) # Just measure area that is white in BorderMaskR. Image = RT_YPlaneMax(Mask=ImageMask,MaskMin=128,MaskMax=255) # Just measure area that is white in ImageMask for black frame. if (FrameB <= Th1) { RT_DebugF("%d Min Luma=%f Max Luma=%f Average Luma=%f Left Border=%f Right Border=%f Image=%f BLACK FRAME",current_frame,YPMin,FrameB,FrameW,BorderL,BorderR,Image) # Subtitle("BLACK FRAME",Size=64,align=5) # Disable Subtitle to increase FPS by x4 } else if (BorderL <= Th2 && BorderR <= Th2 && Image > Th3) { RT_DebugF("%d Min Luma=%f Max Luma=%f Average Luma=%f Left Border=%f Right Border=%f Image=%f HAS BORDER",current_frame,YPMin,FrameB,FrameW,BorderL,BorderR,Image) # Subtitle("HAS BORDER",Size=64,align=5) # Disable Subtitle to increase FPS by x4 } else if (FrameW > Th4) { RT_DebugF("%d Min Luma=%f Max Luma=%f Average Luma=%f Left Border=%f Right Border=%f Image=%f WHITE FRAME",current_frame,YPMin,FrameB,FrameW,BorderL,BorderR,Image) # Subtitle("WHITE FRAME",Size=64,align=5)# Disable Subtitle to increase FPS by x4 } else { RT_DebugF("%d Min Luma=%f Max Luma=%f Average Luma=%f Left Border=%f Right Border=%f Image=%f NO BORDER",current_frame,YPMin,FrameB,FrameW,BorderL,BorderR,Image) # Subtitle("NO BORDER",Size=64,align=5)# Disable Subtitle to increase FPS by x4 } Return Last """ GScriptClip(Last,Debug) #StackHorizontal(src.ColorYUV(analyze=true),last.ColorYUV(analyze=true)) return last Copy and paste into Notepad++. Remove RT_DebugF: to avoid line auto wrap. ctrl+M find 'black frame' and mark all. Do the same for white frame. Find 'has border' and mark all with bookmark line ticked. Check 'find' highlights are grouped continuously. Ie can not have 'has border' then next line 'black frame' then next line 'has border'. Scroll down or pgdn key, scanning at Min Luma - 5,7,4,6,7,3,8,4,6,7,6,7,8 (vertical) and so on until you get - 12,14,15,13,16,15,14,15,16,14 and so on. Vdub2 - Group 1st example as first trim file making sure SmoothLevels output low is 8 to 10. Group 2nd example as second trim file with output low 4. So on. Done 5 video clips and range from 5 to 12 trims. Better than typing in 40 to 60 trim() and having to be super careful not to get the frame numbers wrong. Plus a few trims correcting other 'defect' done separately. Black fade in to out isn't a problem 99% of the time. If the fade looks bad then trim using vdub 2 curve editor. Easy. *************** Below original query. I have many videos with 16/9 and some 4/3 with letterbox mixed in and the levels are off. The long version would be using trim function. However, I want to automate it instead. My idea is - Code:
If frame averageluma < 16 then Levels(0, 1.0, 255, 0, 0, coring=false) else if frame has letterbox and averageluma < 16 then SmoothLevels(0, 1.0, 255, 16, 235).Letterbox(0,0,240,240) else SmoothLevels(0, 1.0, 255, 16, 235) However, for the life of me, i can't find any functions/plugins/whatever that allows me to search an area of a frame. In this case searching for letterbox would be 240x1080 left and right. I suppose i don't need to do 240 and i am sure 100x1080 is sufficient to prove letterbox exist. I know there is location specific part of frame but they all seem to be for logo removal. Last edited by coolgit; 22nd January 2023 at 20:05. Reason: Add final scripts. |
6th January 2023, 09:31 | #2 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Is this what you want, RoboCrop(Blank=True) :- https://forum.doom9.org/showthread.php?t=168053
EDIT: Oops no it ain't (after reading your post again properley), sorry. Doing it frame by frame is destined to failure, must be at least scene based, you gotta detect scene ranges beforehand. EDIT: This is what your script seems to be doing, Code:
#If frame averageluma < 16 If frame Is BLACK #then Levels(0, 1.0, 255, 0, 0, coring=false) then FRAME = BLACK #else if frame has letterbox and averageluma < 16 else if frame has letterbox and is also BLACK #then SmoothLevels(0, 1.0, 255, 16, 235).Letterbox(0,0,240,240) then compress PC levels range 0->255 to to TV.Levels 16 -> 235 and letterbox with black for good measure #else SmoothLevels(0, 1.0, 255, 16, 235) else compress PC levels range 0->255 to to TV.Levels 16 -> 235
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 6th January 2023 at 10:50. |
6th January 2023, 10:41 | #3 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Suggest take look at DBSC:- https://forum.doom9.org/showthread.php?t=171624
In particular (and a few posts following):- https://forum.doom9.org/showthread.p...83#post1733883 and :- https://forum.doom9.org/showthread.p...60#post1709460 Both for the DBSC_ProcessByDAR() thingy. I aint got time to assist, I'm actually tryin' to find time to update DBSC, and it will likely take a couple of weeks if I am not interrupted. EDIT: And this:- [Automatically apply different processing to letterboxed clips] :- https://forum.doom9.org/showthread.php?t=171777
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 6th January 2023 at 11:16. |
7th January 2023, 23:35 | #4 | Link | |
Registered User
Join Date: Apr 2019
Posts: 217
|
This is what i have so far.
Quote:
Avisynth open failure: Average plane: this filter can only be used within run-time filters. ([gscript], line 2) frame area.avs line 42 - which is """) Comment out GScript(""" and """) as not needed in avs+ I think. Get error same as above but line 31 - which is al=AverageLuma() Any ideas anyone |
|
8th January 2023, 00:39 | #5 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Where is the Manolito script ?
[I'll point in right direction, but aint doing anything past that (results may be automated but, I dont believe it will work well)] It has to be done in ScriptClip, or in Gscript setting current_frame at each frame number. (for runtime functions, etc AverageLuma) Also, probably not faster than manolito's trims, only advantage maybe is automated instead of hand edit trim / splice (If thats what Mani's did).
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 8th January 2023 at 00:49. |
8th January 2023, 01:48 | #7 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
This is function equivalent to Mani's script:- https://forum.doom9.org/showthread.p...43#post1603343
Code:
Function AreaOp(clip c,int x1,int y1,int x2, int y2, String Op) { # https://forum.doom9.org/showthread.php?p=1603343#post1603343 /* x1 is left coord. x2 is leftmost pixel of unprocessed Right border (or x2=Width if no Right border) y1=top coord. y2 is topmost pixel of unprocessed Bottom border (or y2=Height if no Bottom border) op is Operation eg "BlackNess()" OR "Levels(16,1.0,235,235,16,coring=False)" */ # Mod 4 coords x1 = x1 - (x1 % 4) y1 = y1 - (y1 % 4) x2 = (x2 + 3) / 4 * 4 y2 = (y2 + 3) / 4 * 4 Area=c.crop(X1,Y1,X2-X1,Y2-Y1) Above = Y1 > 0 ? c.crop(0,0,c.width(),Y1) : NOP Below = Y2 < c.height() ? c.crop(0,Y2,c.width(),c.height()-Y2) : NOP Left = X1 > 0 ? c.crop(0,Y1,X1,Y2-Y1) : NOP Right = X2 < c.width() ? c.crop(X2,Y1,c.width()-X2,Y2-Y1) : NOP Eval("Area." + OP) IsClip(Left) ? StackHorizontal(Left, Last) : NOP IsClip(Right) ? StackHorizontal(Last, Right) : NOP IsClip(Above) ? StackVertical(Above, Last) : NOP IsClip(Below) ? StackVertical(Last, Below) : NOP Return Last } Code:
ColorBars() X1=100 X2=400 Y1=100 Y2=200 AreaOp(x1,y1,x2,y2,"Blackness()") #ConvertToYV12().AreaOp(x1,y1,x2,y2,"Descratch()")
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 8th January 2023 at 05:18. |
8th January 2023, 04:28 | #8 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
I think this works OK (Not much testing),
does similar to above post, but with x,y,w,h coords for inner area (as in crop), It requires YUV444 (eg YV24) or RGB input OR colorspace compatible crop coords. Code:
Function AreaOp_444(clip c,int x,int y,int w, int h, String Op) { /* YUV444 (eg YV24) or RGB only (or coords already crop compatible with colorspace eg all mod 2 for YV12, else error) x,y,w,h, coords of inner area as per crop(x,y,w,h), w and h can be <= 0 where width or height relative. op is Operation eg "BlackNess()" OR "Levels(16,1.0,235,235,16,coring=False)" */ # Make w and h -ve or 0, ie width or height relative. w = (w <= 0) ? w : (x + w) - c.Width() h = (h <= 0) ? h : (y + h) - c.Height() Area=c.crop(x,y,w,h) # Inner Area # Borders, Full width top and bottom, short left and right Above = (y>0) ? c.crop(0,0,c.width(),y) : NOP Below = (h<0) ? c.crop(0,c.Height()+h,c.width(),0) : NOP Left = (x>0) ? c.crop(0,y,x,h) : NOP Right = (w<0) ? c.crop(c.Width+w,y,0,h) : NOP Eval("Area." + OP) IsClip(Left) ? StackHorizontal(Left, Last) : NOP IsClip(Right) ? StackHorizontal(Last, Right) : NOP IsClip(Above) ? StackVertical(Above, Last) : NOP IsClip(Below) ? StackVertical(Last, Below) : NOP Return Last } BlankClip(Color=$FF0000) # RGB32 crop mod 1 # Coords as for crop AreaOp_444(5,7,-2,-54,"BlackNess()") I'll come back again tomorrow.
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 8th January 2023 at 05:18. |
8th January 2023, 15:33 | #9 | Link |
Registered User
Join Date: Apr 2019
Posts: 217
|
Blimey... I had a plan.
To get the basic script working then modify Manolito's script to create my first function, similar to VoodooFX's inpaintloc and use some of VoodooFX code to allow ltrb coords similar to vdub. Just spent a day researching how to create a function, jotting down some ideas and codes to use. Then out of the blue you had already created a basic function... 10 bleeding years ago. You could have posted it in your first reply Done some tests and it worked as intended. I need to get the 2nd part, Gscript to work, at the moment i am getting this annoying runtime error. When that is done, i intend to expand the function itself. One step and a time. Ideas I have for example:- - to use the function for scene change detection - SCSelect_HBD - by zooming in the frame, say 50 off for all sides thus ignoring dodgy borders that may throw up false detection. - to use the function for removing defects persistently in one area - spotless - fixing defect inside the cropped area and ignoring the rest of the frame. Should be useful if the rest of the frame has lots of motion and left untouched. |
8th January 2023, 16:30 | #10 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
My idea was to create two masks, using above func [or via BlankClip and Letterbox],
can use mask mode of some RT_Stats (8 bit only) to measure eg Averageluma of total outer border area, and/or inner area. And also can apply filter to inner area using AreaOp_444(). EDIT: Instead of two masks, can use one mask and altered MaskMin/MaskMax args in the calls to RT_Stats funcs. EDIT: Quote:
or using ScriptClip [Or GScriptClip from Grunt], where splicing is done by ScriptClip. If using For(n=0,FrameCount EDIT: FrameCount-1) loop, then inside you need to set current_frame to the frame number (n) so that AverageLuma (or whatever) knows what frame to sample. current_frame=n, is necessary as it tricks AVS into thinking its in runtime mode (eg ScriptClip), and AverageLuma (and other runtime funcs) then works ok. EDIT: Code:
**************************************** ******* MASKED Luma Y Functions ******** **************************************** Compile time/runtime functions, Planar, YUY2, RGB24 & RGB32. (RGB internally converted to YUV-Y). The compiletime/runtime clip functions share some common characteristics:- The 'n' arg is an optional frame number and defaults to 'current_frame' if not specified. The x,y,w,h, coords specify the source rectangle under scrutiny and are specified as for Crop(), the default 0,0,0,0 is full frame. If 'interlaced' is true, then every other line is ommited from the scan, so if eg y=1, then scanlines 1,3,5,7 etc are scanned, if eg y=4 then scanlines 4,6,8,10 etc are scanned. The 'h' coord specifies the full height scan ie same whether interlaced is true or false, although it will not matter if the 'h' coord is specified as eg odd or even, internally the height 'h' is reduced by 1 when interlaced=true and 'h' is even. 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 The optional mask clip, governs which pixels are processed by the functions. Where a luma pixel in selected area of the the mask clip is in range "MaskMin" to "MaskMax" inclusive, then those pixels will be processed. The Mask must also be Planar but not necessarily the same colorspace as clip c, also must be same dimensions and have at least the same number of frames as clip c. Calling without mask clip OR with MaskMin=0,MaskMax=255 will effectively ignore the mask and scan full x,y,w,h area. RT_YPlaneMin(clip c,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>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Return int -1, if no valid pixels in Mask clip. Returns int value minimum luma (0 -> 255) in frame(n+delta) for area x,y,w,h. Threshold is a percentage, stating how many percent of the pixels are allowed below minimum (ignore extreme pixels ie noise). Threshold is % of valid mask pixels processed if Mask supplied. The threshold is optional and defaults to 0.0. *** *** *** RT_YPlaneMax(clip c,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>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Return int -1, if no valid pixels in Mask clip. Returns int value maximum luma (0 -> 255) in frame(n+delta) for area x,y,w,h. Threshold is a percentage, stating how many percent of the pixels are allowed above maximum (ignore extreme pixels ie noise). Threshold is % of valid mask pixels processed if Mask supplied. The threshold is optional and defaults to 0.0. *** *** *** RT_YPlaneMinMaxDifference(clip c,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>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Return int -1, if no valid pixels in Mask clip. Returns int value luma range (maximum - minimum difference) (0 -> 255) in frame(n+delta) for area x,y,w,h. Threshold is a percentage, stating how many percent of the pixels are allowed below minimum or above maximum (ignore extreme pixels ie noise). Threshold is % of valid mask pixels processed if Mask supplied. The threshold is optional and defaults to 0.0. *** *** *** RT_YPlaneMedian(clip c,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false, int "Matrix"=(Width>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Return int -1, if no valid pixels in Mask clip. Returns int value luma median [equiv RT_YPlaneMin(threshold=50.0)] (0 -> 255) in frame(n+delta) for area x,y,w,h. *** *** *** RT_AverageLuma(clip c,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false, int "Matrix"=(Width>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Return int -1, if no valid pixels in Mask clip. Returns FLOAT value average luma (0.0 -> 255.0) in frame(n+delta) for area x,y,w,h. *** *** *** RT_YPlaneStdev(clip c,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false, int "Matrix"=(Width>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Return int -1, if no valid pixels in Mask clip. Returns FLOAT value luma Standard Deviation (0.0 -> 255.0) in frame(n+delta) for area x,y,w,h. Standard Deviation (Changed, from Sample Standard Deviation with Bessels Correction). http://en.wikipedia.org/wiki/Standard_deviation *** *** *** RT_YInRange(clip c,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false, int "lo"=128,int "hi"=lo,int "Matrix"=(Width>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Return int -1, if no valid pixels in Mask clip. Returns FLOAT value (0.0 -> 1.0) being the amount of pixels in the range "lo" to "hi" (inclusive), 1.0 is equivalent to 100%. Implemented as requested by Martin53 (thankyou), NOTE, differs from other funcs that return range 0.0 to 255.0. NOTE, lo defaults to 128, "hi" defaults to "lo". *** *** *** RT_YPNorm(clip c,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,bool "interlaced"=false, float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1,int "Matrix"=(Width>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Return int -1 if no valid pixels in Mask clip. Returns FLOAT value greater or equal to 0.0, being the "Minkowski P-norm" (range depends upon values of 'd' and 'u') for frame(n+delta) area x,y,w,h. mu, Float, default 0.0 (0.0 -> 255.0) d, int, default 1 (1 -> 255) # downscale p, int, default 1 (1 -> 16) # power u, int, default 1 (1 -> 255) # final upscale before returning result (experimental) Formula is: sum_over_pixels[ ((pixel-mu)/d)^p ]^(1/p) * u or in words: d and u are scaling aids. The differences between the pixel values and mu are scaled, taken to the power of p and added up over the frame. The sum is taken to the p-th root and finally rescaled. mu=0, d=1, p=1, u=1 yields the average. mu=average, d=1, p=2, u=1 yields the standard deviation (uncorrected sample standard deviation). Implemented as requested by Martin53 (thankyou). *** EXPERIMENTAL *** http://en.wikipedia.org/wiki/P-norm#The_p-norm_in_finite_dimensions http://en.wikipedia.org/wiki/Minkowski_distance *** *** *** RT_Ystats(clip c,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 "lo"=128,int "hi"=lo,int "flgs"=255,string "prefix"="YS_", float "mu"=0.0,int "d"=1,int "p"=1,int "u"=1, int "Matrix"=(Width>1100||Height>600?3:2),clip "mask"=NOT_USED,int "MaskMin"=128,"MaskMax"=255) Returns multiple results as for above single frame Luma sampling functions as Local Variables (prefixed with the prefix string arg). The args up to "interlaced", 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. "mu" and "d" and "p" and "u" are used only with the "RT_YPNorm" equivalent routine with same functionality. The new arg "Flgs" selects which results you want returned and the string "Prefix" that is prepended to the returned Local variable names. The actual return result is a copy of the flgs arg with any non valid bits reset, ie the Local variables that were set. Local variables are NOT altered for any function not selected in flgs. Returns 0 if no pixels found in search area of mask within MaskMin and MaskMax. Flgs_Bit_Number Add_To_Flgs Equivalent_Function Local_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) 7 128($80) RT_YPNorm() "yPNorm" (0.0->??? depends upon d and u) 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=255($FF) are all bits set and so sets ALL Local vars at once. RT_Ystats(flgs=1+2+16) would set Local vars "YS_yMin", "YS_yMax" and "YS_yAve" for full frame current_frame. In addition to above Local Variables, RT_YStats() sets an int Local variable (where default prefix) of "YS_PixelCount" being the number of pixels in mask area X,Y,W,H between MaskMin and MaskMax inclusive, or pixels scanned in X,Y,W,H area where mask not used. NOTE, If no valid flg bits set (eg $FF00), then returns 0, YS_PixelCount and all other variables remain as before call. Assuming some valid flg bits, if no valid pixels were found in mask then function returns 0, and only YS_PixelCount would be set to 0, no other variables are touched (remain as before call, undefined if not previously existing). Example usage: ScriptClip(""" got = RT_Ystats(c,mask=Mask,flgs=$10) # AverageLuma (got != 0) ? RT_debug("AverageLuma = " + String(YS_yAve) + "PixelCount = " + String(YS_PixelCount)) : RT_Debug("NO VALID PIXELS FOUND") Return Last # EDIT: Added, else would error as above line does not set a Last clip """) Code:
******************************************** ********* RGB MASKED Channel FUNCTIONS ***** ******************************************** RGB32, RGB24 source clip. The source clip c must be RGB32 or RGB24. The compiletime/runtime clip functions share some common characteristics. The 'n' and (where used) 'n2' args are the optional frame numbers and default to 'current_frame' if not specified. The x,y,w,h, coords specify the source rectangle under scrutiny and are specified as for Crop(), the default 0,0,0,0 is full frame. If 'interlaced' is true, then every other line is ommited from the scan, so if eg x=0,y=1, then scanlines 1,3,5,7 etc are scanned, if eg x=0,y=4 then scanlines 4,6,8,10 etc are scanned. The 'h' coord specifies the full height scan ie same whether interlaced is true or false, although it will not matter if the 'h' coord is specified as eg odd or even, internally the height 'h' is reduced by 1 when interlaced=true and 'h' is even. Optional mask clip Planar ONLY [v2.6 colorpspaces OK] The Planar mask clip, governs which pixels are processed by the functions. Where a luma pixel in selected area of the the mask clip is in range "MaskMin" to "MaskMax" inclusive, then those pixels will be processed. Mask MUST, be same dimensions and have at least the same number of frames as clip c. Calling without mask OR with MaskMin=0,MaskMax=255 will effectively ignore the mask and scan full x,y,w,h area. The Chan arg specifies which R or G or B channel to process [the multi-functional RT_RgbChanStats() function also allows a Chan arg of -1, which processes R and G and B simulaneously for all functions selected by flgs arg, also allowed is chan arg of -2 which additionally processes the ALPHA channel if RGB32 but throws an error if RGB24]. Default Chan is 0 (Red), 1 = Green, 2=Blue channel and 3=ALPHA channel when RGB32 ONLY else error. Do you have [EDIT: frame size and] fixed number and coords of letter boxed sequences ? (what are they)
__________________
I sometimes post sober. StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace "Some infinities are bigger than other infinities", but how many of them are infinitely bigger ??? Last edited by StainlessS; 8th January 2023 at 18:01. |
|
8th January 2023, 18:20 | #11 | Link | ||
Registered User
Join Date: Apr 2019
Posts: 217
|
Quote:
For SD 720x576 letterbox is 90 each vert side. Quote:
If... else... doesn't work in scriptclip does it? I thought the whole point of gscript was to use if... else... Gscriptclip - i was looking at that but according to the website grunt "The alternative (G*) names may be used if you wish, but this is optional in AviSynth version 2.58 or later." So if "g" isn't necessary then i should simply use scriptclip. Or am i missing something. I seen codes with current_frame being used but for the life of me i can't understand why. Now i see you need it to trick avs into runtime mode. Got it. Surely if one has to trick avs into doing something then it must be a bug of sort? Last edited by coolgit; 8th January 2023 at 19:50. |
||
8th January 2023, 19:16 | #12 | Link | ||||||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
You mean crop left and right both by 240 pixels : Crop(240,0,-240,-0) or crop top, bot both by 240 pixels : Crop(0,240,-0,-240) Quote:
or crop top, bot both by 90 pixels : Crop(0,90,-0,-90) Quote:
In standard frameserving stage all frames are processed in order, just like in VDub, VDub dont have option to process and make decision on a single frame, only entire clip processed identically, [EDIT: So far as I remember, VD dont have per frame processed by user script, could be wrong though, if it does then similar to scriptclip] ScriptClip does allow decision making inside runtime script but is slower than frameserving stage (where all processed identically), OR, with trickery can set curent_frame to sample a SINGLE frame only, not applicable to entire clip, so, can do as below Code:
Avisource("...") current_frame = 42 Y = Averageluma # single frame access to frame 42 Subtitle( "AverageLuma of frame 42 = " + String(Y) ) # ALL frames in clip subtitled as for frame 42, was evaluated before frameserving started. return last Code:
Avisource("...") SSS = """ Y = Averageluma # current_frame is set by AVS at each frame, automatically in the background Subtitle( "AverageLuma of frame " + String(current_frame) + " = " + String(Y) ) return last """ Return last frame has already been decided. Where ScriptClip() or other runtime filter is included in script, each frame is processed and evaluated in the real time runtime script given to the runtime filter, and includes script parsing and evaluating at each current_frame frame. Quote:
EDIT: Quote:
Code:
AviSource(".\vid.avi") SSS = """ if(current_frame % 2 == 0) { Subtitle("EVEN") } else { Subtitle("ODD") } Return last """ ScriptClip(SSS) return last Quote:
I did post somewhere a better explanation, but cannot remember now offhand why this is. EDIT: This does actually work, I cant remember the conditions that cause it to fail. Code:
AviSource(".\vid.avi") SSS = """ if(current_frame % 2 == 0) { Subtitle("EVEN") } else { Subtitle("ODD") } Return last """ GScriptClip(SSS) 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; 8th January 2023 at 20:45. |
||||||
8th January 2023, 23:41 | #13 | Link | |
Registered User
Join Date: Apr 2019
Posts: 217
|
Quote:
l=0, t=0, r=100 or -1820, b=1080 or 0 is the area size... crop(0,0,100,1080) or vdub style crop(0,0,-1820,0). This area for HD should be sufficient to determine whether letterbox exist. |
|
9th January 2023, 01:29 | #14 | Link |
Registered User
Join Date: Apr 2019
Posts: 217
|
src=LSMASHVideoSource("filename.mp4", format="YUV420P10", fpsnum=25, fpsden=1).ConvertBits(8, dither=0).KillAudio()
#al=AverageLuma #if(src.AverageLuma < 16){ # Levels(0, 1.0, 255, 0, 0, coring=false) # } screws up fade in/out to/from black #current_frame=n For(n=0,FrameCount-1){ current_frame=n fc=FrameCount() if(current_frame < fc && AreaOp(src,0,100,0,1080).AverageLuma < 16){ SmoothLevels(0, 1.0, 255, 16, 235).Letterbox(0,0,240,240) } else { SmoothLevels(0, 1.0, 255, 16, 235) } current_frame=current_frame+1 Return Last } StackHorizontal(src,last) #Return last After eliminating an error, another one pops up and so and so. The latest "I don't know what framecount means" line 22 } after return last. |
9th January 2023, 23:19 | #15 | Link |
Registered User
Join Date: Apr 2019
Posts: 217
|
Area of frame function.
Code:
# L is left border. T is top border. R is right border. B is bottom border. Op is Operation eg. "BlackNess()". Function FrameArea(clip c,int L,int T,int R, int B) { # https://forum.doom9.org/showthread.p...43#post1603343 # Modulo 4 coords L = L - (L % 4) T = T - (T % 4) R = (R + 3) / 4 * 4 B = (B + 3) / 4 * 4 Area=c.crop(L,T,R-L,B-T) Left = L > 0 ? c.crop(0,T,L,B-T) : NOP Top = T > 0 ? c.crop(0,0,c.width(),T) : NOP Right = R < c.width() ? c.crop(R,T,c.width()-R,B-T) : NOP Bottom = B < c.height() ? c.crop(0,B,c.width(),c.height()-B) : NOP Eval("Area") IsClip(Left) ? StackHorizontal(Left, Last) : NOP IsClip(Top) ? StackVertical(Top, Last) : NOP IsClip(Right) ? StackHorizontal(Last, Right) : NOP IsClip(Bottom) ? StackVertical(Last, Bottom) : NOP Return Last } /* L=0 R=100 T=0 B=1080 FrameArea(src,L,T,R,B) StackHorizontal(src,last) #Return Last */ Latest code Code:
src=LSMASHVideoSource("filename.mp4", format="YUV420P10", fpsnum=25, fpsden=1).ConvertBits(8, dither=0).KillAudio() #al=AverageLuma #if(src.AverageLuma < 16){ # Levels(0, 1.0, 255, 0, 0, coring=false) # } screws up fade in/out to/from black #current_frame=n #fc=FrameCount(src) #AL=AverageLuma SL=""" For (n=0,FrameCount-1){ AL=AverageLuma current_frame=n fc=FrameCount if (current_frame < fc){ if (FrameArea(src,0,100,0,1080) && (AL < 16)){ SmoothLevels(0, 1.0, 255, 16, 235).Letterbox(0,0,240,240) }} else { SmoothLevels(0, 1.0, 255, 16, 235) } # Return Last } """ GScriptClip(SL) # another method #For(n=0,FrameCount-1){ #frame=(FrameArea(src,0,100,0,1080).AverageLuma < 16) ? SmoothLevels(0, 1.0, 255, 16, 235).Letterbox(0,0,240,240) : SmoothLevels(0, 1.0, 255, 16, 235) #} StackHorizontal(src,last) #Return last |
17th January 2023, 03:33 | #16 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Sorry, not been on-site for a while, probably not be around much in near future.
Something like this with scriptclip, Code:
TOP = 0 BOTTOM = 0 LEFT = 240 RIGHT = 240 THRESH = 16.0 NEW_BORDER_COLOR = $FF00FF # So you can see where was changed A = ColorBars(pixel_type="YV24").KillAudio.Spline36Resize(1920,1080).Trim(0,-10) # 10 frames B = A.LetterBox(TOP,BOTTOM,RIGHT,LEFT, $000000) A ++ B ++ A ++ B ++ A # 50 frames Src = Last # Return Last BORDER_MASK = Last.BlankClip().LetterBox(TOP,BOTTOM,LEFT,RIGHT,$FFFFFF) # WHITE where there is BORDER, Else BLACK #Return BORDER_MASK IMAGE_MASK = BORDER_MASK.INVERT #Return IMAGE_MASK OP = "Levels(0, 1.0, 255, 16, 235, coring=false)" # NOT SURE WHAT YOU TRY TO DO HERE, YRange Compress ? # Also, get it working with simple stuff before you get more complicated. SL=""" BorderY = RT_AverageLuma(Mask=BORDER_MASK,MaskMin=128,MaskMax=255) # Just measure area that is WHITE in BORDER_MASK ImageY = RT_AverageLuma(Mask=IMAGE_MASK ,MaskMin=128,MaskMax=255) # Just measure area that is WHITE in IMAGE_MASK { HERE WE ONLY SHOW IT in DebugView, NOT USED FOR ANYTHING ELSE } RT_DebugF("\n%d] BorderY = %f ImageY=%f",current_frame,BorderY,ImageY,name="COOLGIT: ") # To DebugView [google] if (BorderY <= THRESH) { RT_DebugF("%d] HAS BORDER",current_frame,name="COOLGIT: ") AreaOp_444( LEFT, TOP, -RIGHT, -BOTTOM, OP ) # Apply levels, only image area [EDIT: -ve Right, and -ve BOTTOM, as in crop with -ve width/height] # Levels(0, 1.0, 255, 16, 235,coring=false) # Alternative, Apply to whole frame Letterbox(TOP,BOTTOM,RIGHT,LEFT, Color=NEW_BORDER_COLOR) Subtitle("Fixed",Size=64,align=5) } else { RT_DebugF("%d] NO BORDER",current_frame,name="COOLGIT: ") Levels(0, 1.0, 255, 16, 235,coring=false) # Apply Smoothlevels, whole image area } Return Last """ GScriptClip(Last,SL) StackVertical(src,last) Return Last Function AreaOp_444(clip c,int x,int y,int w, int h, String Op) { /* YUV444 (eg YV24) or RGB only (or coords already crop compatible with colorspace eg all mod 2 for YV12, else error) x,y,w,h, coords of inner area as per crop(x,y,w,h), w and h can be <= 0 where width or height relative. op is Operation eg "BlackNess()" OR "Levels(16,1.0,235,235,16,coring=False)" */ # Make w and h -ve or 0, ie width or height relative. w = (w <= 0) ? w : (x + w) - c.Width() h = (h <= 0) ? h : (y + h) - c.Height() Area=c.crop(x,y,w,h) # Inner Area # Borders, Full width top and bottom, short left and right Above = (y>0) ? c.crop(0,0,c.width(),y) : NOP Below = (h<0) ? c.crop(0,c.Height()+h,c.width(),0) : NOP Left = (x>0) ? c.crop(0,y,x,h) : NOP Right = (w<0) ? c.crop(c.Width+w,y,0,h) : NOP Eval("Area." + OP) IsClip(Left) ? StackHorizontal(Left, Last) : NOP IsClip(Right) ? StackHorizontal(Last, Right) : NOP IsClip(Above) ? StackVertical(Above, Last) : NOP IsClip(Below) ? StackVertical(Last, Below) : NOP Return Last } Code:
ImageY = RT_AverageLuma(Mask=IMAGE_MASK ,MaskMin=128,MaskMax=255) Code:
ImageY = RT_AverageLuma(Mask=BORDER_MASK ,MaskMin=0,MaskMax=127) EDIT: Quote:
EDIT: A bit of the DebugView output Code:
00009968 1.55998325 [9336] COOLGIT: 00009969 1.56004477 [9336] COOLGIT: 5] BorderY = 84.625000 ImageY=95.467987 00009970 1.56010675 [9336] COOLGIT: 5] NO BORDER 00009971 1.58738816 [9336] COOLGIT: 00009972 1.58743227 [9336] COOLGIT: 6] BorderY = 84.625000 ImageY=95.467987 00009973 1.58748627 [9336] COOLGIT: 6] NO BORDER 00009974 1.61540735 [9336] COOLGIT: 00009975 1.61546588 [9336] COOLGIT: 7] BorderY = 84.625000 ImageY=95.467987 00009976 1.61552966 [9336] COOLGIT: 7] NO BORDER 00009977 1.64438224 [9336] COOLGIT: 00009978 1.64442945 [9336] COOLGIT: 8] BorderY = 84.625000 ImageY=95.467987 00009979 1.64449239 [9336] COOLGIT: 8] NO BORDER 00009980 1.67529500 [9336] COOLGIT: 00009981 1.67534482 [9336] COOLGIT: 9] BorderY = 84.625000 ImageY=95.467987 00009982 1.67541265 [9336] COOLGIT: 9] NO BORDER 00009983 1.71268141 [9336] COOLGIT: 00009984 1.71272635 [9336] COOLGIT: 10] BorderY = 16.000000 ImageY=95.467987 00009985 1.71278882 [9336] COOLGIT: 10] HAS BORDER 00009986 1.79725134 [9336] COOLGIT: 00009987 1.79730320 [9336] COOLGIT: 11] BorderY = 16.000000 ImageY=95.467987 00009988 1.79736423 [9336] COOLGIT: 11] HAS BORDER 00009989 1.90727317 [9336] COOLGIT: 00009990 1.91610396 [9336] COOLGIT: 12] BorderY = 16.000000 ImageY=95.467987 00009991 1.91829336 [9336] COOLGIT: 12] HAS BORDER 00009992 2.00985384 [9336] COOLGIT: 00009993 2.00990272 [9336] COOLGIT: 13] BorderY = 16.000000 ImageY=95.467987 00009994 2.00996470 [9336] COOLGIT: 13] HAS BORDER 00009995 2.08401132 [9336] COOLGIT: 00009996 2.08404684 [9336] COOLGIT: 14] BorderY = 16.000000 ImageY=95.467987 00009997 2.08408642 [9336] COOLGIT: 14] HAS BORDER 00009998 2.15086484 [9336] COOLGIT: 00009999 2.15089631 [9336] COOLGIT: 15] BorderY = 16.000000 ImageY=95.467987 00010000 2.15093732 [9336] COOLGIT: 15] HAS BORDER 00010001 2.23550248 [9336] COOLGIT: EDIT: And image Y range compressed as per levels. EDIT: I still kinda think that you're wasting your time, unlikely to work well Might work well for most clips, but there will likely be the occasional totally bad mistake on some frames/sequences, borders are unlikely to "play ball" and be exactly what you hope they are. I've seen borders and lowest image black being about 32.xxx [usually result of bad processing somewhere, and looking very 'wishy washy'], but less likely on HD/FHD. They may also not be positioned exactly where you would like them to be, or have edge crud, it's an odd life.
__________________
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 January 2023 at 06:27. |
|
22nd January 2023, 19:01 | #17 | Link |
Registered User
Join Date: Apr 2019
Posts: 217
|
Here the suppose final scripts.
LetterBox detector. Code:
video=LSMASHVideoSource("Filename").ConvertBits(8, dither=0).KillAudio() #video=FFmpegSource2("Filename").KillAudio() video src=last LeftA = 220 # For analysing border. TopA = 0 RightA = 220 BottomA = 0 Left = 240 # For fixing letterbox. Top = 0 Right = 240 Bottom = 0 Th1 = 18.0 # Threshold variables. Ensure black frames are the same blackness. Th2 = 17.0 # Ensure letterbox exist and fix letterbox blackness after levels/filter adjustment. Th3 = 16.0 # Ensure ImageMask isn't 100% black. Th4 = 150.0 # Detect white frames and fade in/out. Experimental Th4. LB = $008080 # $008080 Letterbox colour. $FF00FF - see changes for debugging. BorderMaskL = last.BlankClip().LetterBox(TopA, BottomA, LeftA, 0, $FFFFFF) # White where there is border, else black. Leftside. BorderMaskR = last.BlankClip().LetterBox(TopA, BottomA, 0, RightA, $FFFFFF) # White where there is border, else black. Rightside. BorderMask = last.BlankClip().LetterBox(TopA, BottomA, LeftA, RightA, $FFFFFF) # White where there is border, else black. ImageMask = BorderMask.Invert LBox=""" # YPMin = RT_YPlaneMin() FrameB = RT_YPlaneMax() # FrameW = RT_AverageLuma() BorderL = RT_YPlaneMax(Mask=BorderMaskL,MaskMin=128,MaskMax=255) # Measure area that is white in BorderMaskL. BorderR = RT_YPlaneMax(Mask=BorderMaskR,MaskMin=128,MaskMax=255) # Measure area that is white in BorderMaskR. Image = RT_YPlaneMax(Mask=ImageMask ,MaskMin=128,MaskMax=255) # Measure area that is white in ImageMask. if (FrameB <= Th1) { Levels(0, 1.0, 255, 0, 0, coring=false) # Subtitle("Black Frame",Size=64,align=5) # } else if (FrameW > Th4) { # Dissolve()# or use Vdub2 curve editor or whatever filter fixes the problem. Use 'Video Debug.avs' to check if white frames exist. # Subtitle("White Frame",Size=64,align=5) } else if (BorderL <= Th2 && BorderR <= Th2 && Image > Th3) { SmoothLevels(0, 1.0, 255, 8, 255, Lmode=2, brightSTR=100, chroma=100, limiter=0, useMT=10) Letterbox(top, bottom, left, right, color_yuv=LB) # Subtitle("Has Border",Size=64,align=5) } else { SmoothLevels(0, 1.0, 255, 4, 255, Lmode=2, brightSTR=500, chroma=100, limiter=0, useMT=10)#.SmoothTweak(brightness=0, contrast=1.0, saturation=1.0, hue1=0, hue2=0, Lmode=0, limiter=false, useMT=10) # Subtitle("No Border",Size=64,align=5) } Return Last """ GScriptClip(Last,LBox) #StackVertical(src.ColorYUV(analyze=true),last.ColorYUV(analyze=true)) StackHorizontal(src.ColorYUV(analyze=true),last.ColorYUV(analyze=true)) Return Last Code:
video=LSMASHVideoSource("Filename").ConvertBits(8, dither=0).KillAudio() #video=FFmpegSource2("Filename").KillAudio() video src=last Left = 220 Top = 0 Right = 220 Bottom = 0 Th1 = 16.0 # Threshold variables. Ensure black frames are the same blackness. Th2 = 16.0 # Ensure letterbox exist and fix letterbox blackness after levels/filter adjustment. Th3 = 16.0 # Ensure ImageMask isn't 100% black. Th4 = 150.0 # Detect white frames and fade in/out. Fade needs to be fix manually. BorderMaskL = last.BlankClip().LetterBox(Top, Bottom, Left, 0, $FFFFFF) # White where there is border, else black. Leftside. BorderMaskR = last.BlankClip().LetterBox(Top, Bottom, 0, Right, $FFFFFF) # White where there is border, else black. Rightside. BorderMask = last.BlankClip().LetterBox(Top, Bottom, Left, Right, $FFFFFF) # White where there is border, else black. ImageMask = BorderMask.Invert Debug=""" YPMin = RT_YPlaneMin() FrameB = RT_YPlaneMax() FrameW = RT_AverageLuma() BorderL = RT_YPlaneMax(Mask=BorderMaskL,MaskMin=128,MaskMax=255) # Just measure area that is white in BorderMaskL. BorderR = RT_YPlaneMax(Mask=BorderMaskR,MaskMin=128,MaskMax=255) # Just measure area that is white in BorderMaskR. Image = RT_YPlaneMax(Mask=ImageMask,MaskMin=128,MaskMax=255) # Just measure area that is white in ImageMask for black frame. if (FrameB <= Th1) { RT_DebugF("%d Min Luma=%f Max Luma=%f Average Luma=%f Left Border=%f Right Border=%f Image=%f BLACK FRAME",current_frame,YPMin,FrameB,FrameW,BorderL,BorderR,Image) # Subtitle("BLACK FRAME",Size=64,align=5) # Disable Subtitle to increase FPS by x4 } else if (BorderL <= Th2 && BorderR <= Th2 && Image > Th3) { RT_DebugF("%d Min Luma=%f Max Luma=%f Average Luma=%f Left Border=%f Right Border=%f Image=%f HAS BORDER",current_frame,YPMin,FrameB,FrameW,BorderL,BorderR,Image) # Subtitle("HAS BORDER",Size=64,align=5) # Disable Subtitle to increase FPS by x4 } else if (FrameW > Th4) { RT_DebugF("%d Min Luma=%f Max Luma=%f Average Luma=%f Left Border=%f Right Border=%f Image=%f WHITE FRAME",current_frame,YPMin,FrameB,FrameW,BorderL,BorderR,Image) # Subtitle("WHITE FRAME",Size=64,align=5)# Disable Subtitle to increase FPS by x4 } else { RT_DebugF("%d Min Luma=%f Max Luma=%f Average Luma=%f Left Border=%f Right Border=%f Image=%f NO BORDER",current_frame,YPMin,FrameB,FrameW,BorderL,BorderR,Image) # Subtitle("NO BORDER",Size=64,align=5)# Disable Subtitle to increase FPS by x4 } Return Last """ GScriptClip(Last,Debug) #StackHorizontal(src.ColorYUV(analyze=true),last.ColorYUV(analyze=true)) return last Copy and paste into Notepad++. Remove RT_DebugF: to avoid line auto wrap. ctrl+M find 'black frame' and mark all. Do the same for white frame. Find 'has border' and mark all with bookmark line ticked. Check 'find' highlights are grouped continuously. Ie can not have 'has border' then next line 'black frame' then next line 'has border'. Scroll down or pgdn key, scanning at Min Luma - 5,7,4,6,7,3,8,4,6,7,6,7,8 (vertical) and so on until you get - 12,14,15,13,16,15,14,15,16,14 and so on. Vdub2 - Group 1st example as first trim file making sure SmoothLevels output low is 8 to 10. Group 2nd example as second trim file with output low 4. So on. Done 5 video clips and range from 5 to 12 trims. Better than typing in 40 to 60 trim() and having to be super careful not to get the frame numbers wrong. Plus a few trims correcting other 'defect' done separately. Black fade in to out isn't a problem 99% of the time. If the fade looks bad then trim using vdub 2 curve editor. Easy. Last edited by coolgit; 22nd January 2023 at 20:05. |
22nd January 2023, 19:34 | #18 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
So, it works for you, Yes, and you are a happy bunny ?
__________________
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 ??? |
22nd January 2023, 20:04 | #19 | Link | ||||
Registered User
Join Date: Apr 2019
Posts: 217
|
Quote:
Got to remember that one. I had actually got a working script over a week ago but couldn't understand the error as it kept on pointing at line whatever with } However when I used Code:
video=LSMASHVideoSource("Filename") video=Last Used Code:
video=LSMASHVideoSource("Filename") video src=last Quote:
Quote:
For my purpose it works very very well. The amount of trim is vastly reduce and clicking on 'home' and 'end' key using vdub2 is million times better than typing out frames numbers. Threshold Th1, etc, can be adjusted slightly when necessary according to video debug outputs. Time spent per video is reduced by say 70%, off the head estimate. Is there a way to save/use avisynth script when using Vdub2 job control. Tried it and avisynth was ignored. Last edited by coolgit; 22nd January 2023 at 20:08. |
||||
22nd January 2023, 21:39 | #20 | Link | ||||||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
Quote:
Quote:
Either Code:
LSMASHVideoSource("Filename") # Assign to Implict Last (If not assigned to anything else, then is assigned to Implicit Last), same as Last=LSMASHVideoSource("Filename") src=last # Assign Last to Src Code:
src=LSMASHVideoSource("Filename") # Assign to src src # Assign to implcit Last, ie same as Last=src Quote:
If you wanna save the script, do it before you save it to the Job control whatsit, ie CTRL S # if in VDub main screen, [see Menu hints] or if in VD2 script Editor (via F1 or menu Help, below F5 and F7 as described in VD2 script editor help window) Quote:
F5 saves, reloads, and jumps back to original frameNo. F7 saves, reloads, and jumps to frameNo 0. EDIT: Quote:
THEN "Menu/File/Queue Batch Operation/" sub menu "Save Video", which uses the saved script as source script. OR, "Menu/File/Save Video", And change the "Do Now" option button to "Save to job Queue", then click "Save" button. THEN, "Menu/File/Job Control" and select "START" button {Not OK button which will just exit job control}
__________________
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; 23rd January 2023 at 01:11. |
||||||
Thread Tools | Search this Thread |
Display Modes | |
|
|