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. |
![]() |
#41 | Link |
Moderator
![]() Join Date: Oct 2001
Location: Hawaii
Posts: 7,405
|
No problems at all. Don't need a separate FillBorders2 and don't even need GImport to open it. Just a simple Import line seems to be enough.
Cool, can stop shaky movies more easily and better than the old Stab I've been using for years. Thanks to you both. |
![]() |
![]() |
![]() |
#43 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
Arx1meD,
I dont really understand what your fiilter is doing [I was just getting it working, not trying to understand it, years since I used Stab/Depan stuff]. As far as the edge scanning by FillBorders2_TestBord() is concerned, On each edge you test increasing CropWidth until it breaks thr, would it perhaps be better to crop and test individual lines instead [EDIT: pixel rows or columns] ? Where eg left edge and i=8, crop, crop(i-1,0,1,0) [crop(7,0,1,0)] AverageLuma, and compare that with Thr. If you think it might be worth a try, I'll make mod, if dont work then just remain as is now. [I'm not going to try it unless you think it may make a +ve difference]. Off to the shops now, and then after that, gonna feed the ducks. [ No, that is not a euphemism ] EDIT: If works, would likely be more precise, thr may need be lowered. EDIT: Also,Instead of AverageLuma, yPlaneMax could be used to catch individual pixel >= thr [although thr may need go back to int again, but maybe it dont matter].
__________________
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 March 2021 at 15:15. |
![]() |
![]() |
![]() |
#44 | Link | |
Registered User
Join Date: Feb 2021
Posts: 103
|
This is a filter for stabilizing video from shaking. The result of his work can be seen in the example in post #1.
Quote:
Fragment from FillBorders_stabi: Code:
# 4px or greater L4=FalPos ? crop(0,0,-w+4,0) : nop() R4=FalPos ? crop(w-4,0,0 ,0) : nop() T4=FalPos ? crop(0,0,0,-h+4) : nop() B4=FalPos ? crop(0,h-4,0 ,0) : nop() # 3px L3=crop(0,0,-w+3,0) R3=crop(w-3,0,0 ,0) T3=crop(0,0,0,-h+3) B3=crop(0,h-3,0 ,0) # 2px L2=crop(L3,0,0,-1, 0) R2=crop(R3,1,0,0 , 0) T2=crop(T3,0,0,0 ,-1) B2=crop(B3,0,1,0 , 0) # 1px L1=crop(L3,0,0,-2,0 ) R1=crop(R3,2,0,0 ,0 ) T1=crop(T3,0,0,0 ,-2) B1=crop(B3,0,2,0 ,0 ) c Fill = gScriptClip(""" yclip pad= blur ? pad+2 : pad L1A = AverageLuma(L1) R1A = AverageLuma(R1) T1A = AverageLuma(T1) B1A = AverageLuma(B1) x1o = L1A < thr ? (AverageLuma(L2) < thr ? (AverageLuma(L3) < thr ? 3 : 2) : 1) : 0 x1 = L1A < thr ? x1o+pad : x1o x2o = R1A < thr ? (AverageLuma(R2) < thr ? (AverageLuma(R3) < thr ? 3 : 2) : 1) : 0 x2 = R1A < thr ? x2o+pad : x2o y1o = T1A < thr ? (AverageLuma(T2) < thr ? (AverageLuma(T3) < thr ? 3 : 2) : 1) : 0 y1 = T1A < thr ? y1o+pad : y1o y2o = B1A < thr ? (AverageLuma(B2) < thr ? (AverageLuma(B3) < thr ? 3 : 2) : 1) : 0 y2 = B1A < thr ? y2o+pad : y2o Fragment from Stab3: Code:
b3fix && defined(FalPosclip) ? FalPosclip : FixFalPos ? eval(""" thick = b3fix ? 3.0 : 2.0 # removing >2px wide borders cropx = dxmax*2 ratiox = "YPlaneMax("+string(ceil(99-thick/cropx*100))+")" crop(0,0,0,cropx).conditionalfilter(last,clp,ratiox,">","0") crop(0,height-cropx,0,0).conditionalfilter(last,clp,ratiox,">","0") crop(0,0,cropx,0).conditionalfilter(last,clp,ratiox,">","0") crop(width-cropx,0,0,0).conditionalfilter(last,clp,ratiox,">","0")""") : last |
|
![]() |
![]() |
![]() |
#45 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
Quote:
what I meant was something like this demo test for pixel row/column coord scan. [need DebugView] Code:
Blankclip Function FillBorders2_Mod_TestBord_Mod(clip c,int edge, Float thr, int MaxB, Int Pad) { # edge: 0=lft, 1=rgt, 2=top, 3=bot # Horizontal edges:- [ie top(2) and bot(3) always have x coord of 0, and are full width (can use 0)], AND height always 1 pixel # Vertical edges:- [ie lft(0) and rgt(1) always have y coord of 0, and are full height(can use 0)], AND width always 1 pixel # Lft(0) and Rgt(1), x coord varies # Top(2) and Bot(3), y coord varies edge=min(max(edge,0),3) result=0 w=c.width h=c.height EdS=MidStr("LFTRGTTOPBOT",(edge*3)+1,3) for(i = 1, MaxB) { # crpd=c.Crop((edge==1)?w-i:0,(edge==3)?h-i:0,(edge==0)?i:0,(edge==2)?i:0) cx = (edge>=2) ? 0 : (edge==0) ? i-1 : w-i cw = (edge>=2) ? 0 : 1 cy = (edge<=1) ? 0 : (edge==2) ? i-1 : h-i ch = (edge<=1) ? 0 : 1 RT_DebugF("%s: i=%d] cx=%3d cy=%3d cw=%3d ch=%3d",EdS,i,cx,cy,cw,ch,name="TEST: ") # crpd=c.Crop(cx,cy,cw,ch) # if(crpd.AverageLuma < thr) { result=i+pad } # Orig # if(crpd.YPlaneMax < thr) { result=i+pad } # ALTERNATIVE # else { i=MaxB } } return result } For(edge=0,3) { FillBorders2_Mod_TestBord_Mod(Last,edge,10.0,8,8) RT_DebugF("",name="") } Messageclip("DONE") Code:
00000019 1.95851886 [5060] TEST: LFT: i=1] cx= 0 cy= 0 cw= 1 ch= 0 00000020 1.95860696 [5060] TEST: LFT: i=2] cx= 1 cy= 0 cw= 1 ch= 0 00000021 1.95868516 [5060] TEST: LFT: i=3] cx= 2 cy= 0 cw= 1 ch= 0 00000022 1.95875907 [5060] TEST: LFT: i=4] cx= 3 cy= 0 cw= 1 ch= 0 00000023 1.95883310 [5060] TEST: LFT: i=5] cx= 4 cy= 0 cw= 1 ch= 0 00000024 1.95903337 [5060] TEST: LFT: i=6] cx= 5 cy= 0 cw= 1 ch= 0 00000025 1.95910084 [5060] TEST: LFT: i=7] cx= 6 cy= 0 cw= 1 ch= 0 00000026 1.95917070 [5060] TEST: LFT: i=8] cx= 7 cy= 0 cw= 1 ch= 0 00000027 1.95928669 [5060] 00000028 1.95945764 [5060] TEST: RGT: i=1] cx=639 cy= 0 cw= 1 ch= 0 00000029 1.95952940 [5060] TEST: RGT: i=2] cx=638 cy= 0 cw= 1 ch= 0 00000030 1.95960116 [5060] TEST: RGT: i=3] cx=637 cy= 0 cw= 1 ch= 0 00000031 1.95966387 [5060] TEST: RGT: i=4] cx=636 cy= 0 cw= 1 ch= 0 00000032 1.95973265 [5060] TEST: RGT: i=5] cx=635 cy= 0 cw= 1 ch= 0 00000033 1.95979965 [5060] TEST: RGT: i=6] cx=634 cy= 0 cw= 1 ch= 0 00000034 1.95986748 [5060] TEST: RGT: i=7] cx=633 cy= 0 cw= 1 ch= 0 00000035 1.95993960 [5060] TEST: RGT: i=8] cx=632 cy= 0 cw= 1 ch= 0 00000036 1.96003377 [5060] 00000037 1.96018815 [5060] TEST: TOP: i=1] cx= 0 cy= 0 cw= 0 ch= 1 00000038 1.96026278 [5060] TEST: TOP: i=2] cx= 0 cy= 1 cw= 0 ch= 1 00000039 1.96033478 [5060] TEST: TOP: i=3] cx= 0 cy= 2 cw= 0 ch= 1 00000040 1.96040797 [5060] TEST: TOP: i=4] cx= 0 cy= 3 cw= 0 ch= 1 00000041 1.96048045 [5060] TEST: TOP: i=5] cx= 0 cy= 4 cw= 0 ch= 1 00000042 1.96055186 [5060] TEST: TOP: i=6] cx= 0 cy= 5 cw= 0 ch= 1 00000043 1.96062434 [5060] TEST: TOP: i=7] cx= 0 cy= 6 cw= 0 ch= 1 00000044 1.96069789 [5060] TEST: TOP: i=8] cx= 0 cy= 7 cw= 0 ch= 1 00000045 1.96079099 [5060] 00000046 1.96094501 [5060] TEST: BOT: i=1] cx= 0 cy=479 cw= 0 ch= 1 00000047 1.96101999 [5060] TEST: BOT: i=2] cx= 0 cy=478 cw= 0 ch= 1 00000048 1.96109211 [5060] TEST: BOT: i=3] cx= 0 cy=477 cw= 0 ch= 1 00000049 1.96116567 [5060] TEST: BOT: i=4] cx= 0 cy=476 cw= 0 ch= 1 00000050 1.96123731 [5060] TEST: BOT: i=5] cx= 0 cy=475 cw= 0 ch= 1 00000051 1.96131086 [5060] TEST: BOT: i=6] cx= 0 cy=474 cw= 0 ch= 1 00000052 1.96138334 [5060] TEST: BOT: i=7] cx= 0 cy=473 cw= 0 ch= 1 00000053 1.96145618 [5060] TEST: BOT: i=8] cx= 0 cy=472 cw= 0 ch= 1 EDIT: Yep, I know theres too many Mod's in FillBorders2_Mod_TestBord_Mod. EDIT: For YPlaneMax it would not matter if single scanline scan as opposed to block scan, but might be marginally faster. However, If AverageLuma, then might be better for scanline scan [row/column]. EDIT: I can now easily provide two alternative versions of your script for test compare if you wanna test [already done, pretty much]. take maybe 5 mins.
__________________
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 March 2021 at 18:49. |
|
![]() |
![]() |
![]() |
#47 | Link | ||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
Quote:
I assume that black = PC_Levels $00 and white = PC_Levels $FF required. I'll see what I can do with Masktools for above. HERE: Mod for testing against the stab_light.avsi that you already have. Stab_light_Mod.avsi Code:
# Stab_Light_Mod.avsi /* This script can be IMPORT()'ed under Avs+, OR, under Avs v2.60 Standard [ONLY IF GScript is installed]. Can also be GIMPORT()'ed when GScript Installed. Can Also be auto Loaded by Avisynth if in Plugins directory. [needs Gscript installed if not AVS+]. Can Also be dumped in AvsInit()'s GIMPORT directory for auto loading by AvsInit(). */ Function Fb2FnNameEx_Mod(String Fn){Try{Eval(Fn+"()")B=True}catch(e){Assert(e.FindStr("syntax")==0,"Fb2FnNameEx_Mod: Error in Function Name '"+Fn+"'")B=(e.FindStr("no function named")==0)}Return B} Fb2IsPlus_Mod = (FindStr(VersionString,"AviSynth+")!=0) Fb2HasGScript_Mod = Fb2FnNameEx_Mod("GScipt") Fb2_GS_S_Mod = """ Function FillBorders2_TestBord_Mod(clip c,int edge, Float thr, int MaxB, Int Pad) { # edge: 0=lft, 1=rgt, 2=top, 3=bot # Horizontal edges:- [ie top(2) and bot(3) always have x coord of 0, and are full width (can use 0)], AND height always 1 pixel # Vertical edges:- [ie lft(0) and rgt(1) always have y coord of 0, and are full height(can use 0)], AND width always 1 pixel # Lft(0) and Rgt(1), x coord varies # Top(2) and Bot(3), y coord varies edge=min(max(edge,0),3) result=0 w=c.width h=c.height for(i = 1, MaxB) { cx = (edge>=2) ? 0 : (edge==0) ? i-1 : w-i cw = (edge>=2) ? 0 : 1 cy = (edge<=1) ? 0 : (edge==2) ? i-1 : h-i ch = (edge<=1) ? 0 : 1 crpd=c.Crop(cx,cy,cw,ch) if(crpd.AverageLuma < thr) { result=i+pad } # Orig # if(crpd.YPlaneMax < thr) { result=i+pad } # ALTERNATIVE else { i=MaxB } } return result } """ /* If this avsi script is not in plugins, then HasGScript [Fb2HasGScript_Mod] can be FALSE, even if using GImport() from Gscript dll. Not sure why this occurs, so even if Fb2HasGScript_Mod==FALSE and is NOT Avs+, then we use Gscript's GEval instead of Eval to install above FillBorders2_TestBord_Mod(). We use Eval() to install the function, ONLY if GScript not installed and is AVS+. */ Try { (Fb2HasGScript_Mod||!Fb2IsPlus_Mod) ? GEval(Fb2_GS_S_Mod) : Eval(Fb2_GS_S_Mod) } catch (msg) { Assert(False,ScriptFile+": Need GScript or Avs+"+Chr(10)+ \ "IsPlus="+String(Fb2IsPlus_Mod)+" : HasGScript="+String(Fb2HasGScript_Mod)+Chr(10)+ \ "SysErr="+Msg) } Function Stab_Light_Mod(clip clp, int "ts", int "range", int "dxmax", int "dymax", float "zoom", float "PAR", \ bool "mirror", int "MaxBorders", bool "FixBorders", bool "FixFalPos", bool "debug") { ts = Default(ts, 7) # frames to temporal average for better motion estimation (max. 7) range = Default(range, 1) # frames before/after to estimate motion dxmax = Default(dxmax, Round(clp.Width()/180.0)) #maximum deviation in pixels dymax = Default(dymax, dxmax) # x, and y should be the same zoom = Default(zoom, 1) # maximum zoom factor (1 disabled) PAR = Default(PAR, 1.0) # PAR of your source mirror = Default(mirror, false) # Edge filling MaxBorders = Default(MaxBorders, Max(Round(clp.Width()/60.0), 20)) FixBorders = Default(FixBorders, true) FixFalPos = Default(FixFalPos, true) # Fixes borders of MaxBorders more pixels wide debug = Default(debug, false) temp = TemporalSoften(clp, ts, 255, 255, 25, 2) # SC thr to 25 otherwise pans will stutter rep = Repair(temp, TemporalSoften(clp, 1, 255, 255, 25, 2)) inter = Interleave(rep, clp) # temporal stable (better subpixel detection) pre_clp = inter.mt_lut(expr="x 20 1 x 127.5 / - 21 ^ pi x * 255 / cos 21 ^ - * 1.05 * -", Y=3, U=2, V=2).RemoveGrain(mode=17) #ColorYUV(levels="PC->TV") mdata = DePanEstimate(pre_clp, range=range, pixaspect=PAR, trust=0, dxmax=dxmax, dymax=dymax, zoommax=zoom) dp = DePan(inter, data=mdata, offset=-1, mirror=mirror?15:0, pixaspect=PAR, matchfields=false, subpixel=2) stab = SelectEvery(dp, 2, 0) w = Width(clp) h = Height(clp) thr = 10.0 pre = stab.ConvertToY8()#.ColorYUV(off_y=-15) stab = (!mirror && FixFalPos) \ ? gScriptClip(stab, " AverageLuma(Crop(pre, 0, 0, -w+MaxBorders+1, 0)) < thr ? clp : \ AverageLuma(Crop(pre, w-MaxBorders-1, 0, 0, 0)) < thr ? clp : \ AverageLuma(Crop(pre, 0, 0, 0, -h+MaxBorders+1)) < thr ? clp : \ AverageLuma(Crop(pre, 0, h-MaxBorders-1, 0, 0)) < thr ? clp : Last Return Last ", args="clp, pre, MaxBorders, w, h, thr",Local=true) \ : stab Return (!mirror && FixBorders) \ ? FillBorders2_Mod(stab, thr=thr, pad=1, MaxBorders=MaxBorders, debug=debug) \ : stab } Function FillBorders2_Mod(clip c, float "thr", int "pad", int "MaxBorders", bool "debug") { Function FillBorders2_Mod_dBugS(int y1,int x1,int x2,int y2) { Return "Black borders:\n "+string(y1)+"\n "+string(x1)+" "+string(x2)+"\n "+ string(y2) } thr = Default(thr, 5.0) pad = Default(pad, 0) MaxB = Default(MaxBorders, Max(Round(c.Width()/60.0), 20)) debug = Default(debug, false) w = width(c) h = height(c) cblank = c.mt_lut( "0", chroma="-128") pre = c.ConvertToY8()#.ColorYUV(off_y=-15) # Moved out of gScriptclip preblank = cblank.ConvertToY8() font="Courier New" gScriptClip(c, " x1 = Pre.FillBorders2_TestBord_Mod(0, thr, MaxB, Pad) x2 = Pre.FillBorders2_TestBord_Mod(1, thr, MaxB, Pad) y1 = Pre.FillBorders2_TestBord_Mod(2, thr, MaxB, Pad) y2 = Pre.FillBorders2_TestBord_Mod(3, thr, MaxB, Pad) PreBlur = 0 # If > 0 then there may be an error PostBlur = 0 # Max(x1, x2, y1, y2, 4) #If > 0 then there may be an error b_fix = (x1 + x2 + y1 + y2) > 0 max_fix = Max(x1, x2, y1, y2) msk = (b_fix && max_fix >= 8) \ ? preblank.LetterBox(y1, y2, x1, x2, color=$ffffff).ConvertToYV12() \ : cblank fixed = (!b_fix) ? Last \ : (max_fix < 8) ? FillBorders(left=x1, top=y1, right=x2, bottom=y2, mode=0, y=3, u=3, v=3) \ : InpaintLogo(mask=msk, Radius=Max(x1,x2,y1,y2,5)*1.5, PreBlur=PreBlur, PostBlur=PostBlur) (debug) \ ? mt_merge(fixed, cblank.ConvertToRGB().LetterBox(y1, y2, x1, x2, color=$ff3333) \ .ConvertToYV12(),preblank.LetterBox(y1, y2, x1, x2, color=$ffffff).ConvertToYV12(), luma=true) \ .Subtitle(FillBorders2_Mod_dBugS(y1,x1,x2,y2), lsp = 10, text_color=$ff3333, font=Font, x=MaxB+5, y=MaxB+5) \ : fixed Return Last ", args="pre, cblank, preblank, thr, pad, MaxB, debug, w, h,Font",Local=true) } Client Code:
#AVSI_FN = ".\Stab_Light.avsi" AVSI_FN = ".\Stab_Light.avsi" AVSI_FN_MOD = ".\Stab_Light_Mod.avsi" Import(AVSI_FN) Import(AVSI_FN_MOD) ORG=AviSource(".\Src.Avi") # OP's sample, After ffmpeg conversion to UT_Video AVI A = ORG.Stab_Light(zoom = 1.00, mirror = false, FixFalPos = true, FixBorders = true , debug = false) B = ORG.Stab_Light_Mod(zoom = 1.00, mirror = true, FixFalPos = false, FixBorders = true, debug = false) D=B.ClipDelta(A,true) T=StackHorizontal(ORG,A) B=StackHorizontal(B,D) StackVertical(T,B) Return Last # Return Clip Difference of input clips (amp==true = Amplified, show==true = show background) Function ClipDelta(clip clip1,clip clip2,bool "amp",bool "show") { amp=Default(amp,false) show=Default(show,false) c2=clip1.levels(128-32,1.0,128+32,128-32,128+32).greyscale() c1=clip1.subtract(clip2) c1=(amp)?c1.levels(127,1.0,129,0,255):c1 return (show)?c1.Merge(c2):c1 } (May need to try varying Thr [probably lower for mod]). EDIT: Quote:
__________________
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 March 2021 at 19:16. |
||
![]() |
![]() |
![]() |
#48 | Link |
Registered User
Join Date: Feb 2021
Posts: 103
|
Did some tests of the modified version. Here's the result:
Stab_Light - 62.76 fps Stab_Light_Mod - 61.72 fps Equal memory usage. Almost the same search for black borders. I think there is no point in changing the FillBorders2_TestBord function. If in one cycle for-loop find all 4 values x1 x2 y1 y2 then it would be cool. We still run FillBorders2_TestBord 4 times. |
![]() |
![]() |
![]() |
#50 | Link | ||
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
Quote:
[was mainly like that for showing Debug output] Quote:
Arh, so you dont want PC_Levels black and white ? [I thought that you did want PC Levels] In that case your Letterbox thing would do OK. However, I've now been looking for something and found this. Posting it anyways. Code:
Function BoxMask(clip c, Int "X", Int "Y", Int "W", Int "H",Int "BW",Int "BH",Bool "Y8") { /* Return a single frame mask for a box # http://forum.doom9.org/showthread.php?p=1817736#post1817736 c, clip, template for frame size. X,Y,W,H Box dimensions all default 0, as for crop eg 0,0,0,0 = full frame. BW, Default=0=Solid box. Frame width for uprights. BH, Default=BW, Frame height for horizontals. Y8, Default False=YV12. Req MaskTools v2.0 */ c myName="BoxMask: " x=Default(x,0) y=Default(y,0) W=Default(W,0) H=Default(H,0) BW=Default(BW,0) BH=Default(BH,BW) Y8=Default(Y8,False) W=(W<=0) ? Width-X+W : W H=(H<=0) ? Height-Y+H : H Assert(0 <= X < Width, myName+String(X,"0 <= X(%.0f) < ")+String(Width, "Width( %.0f)")) Assert(0 <= Y < Height,myName+String(Y,"0 <= Y(%.0f) < ")+String(Height,"Height(%.0f)")) Assert(0 < W <= Width, myName+String(W,"0 < W(%.0f) <= ")+String(Width, "Width( %.0f)")) Assert(0 < H <= Height,myName+String(H,"0 < H(%.0f) <= ")+String(Height,"Height(%.0f)")) Assert(0 <= BW <= W/2,myName+String(BW,"0 <= BW(%.0f) <= ")+String(W/2,"W/2(%.0f)")) Assert(BW==0 || (0 < BH <= H/2),myName+String(BH,"0 <= BH(%.0f) <= ")+String(H/2,"H/2(%.0f)")) Rpn=(BW==0) \ ? String(X,"x %.0f")+String(X+W," >= x %.0f")+String(Y," < & y %.0f")+String(Y+H," >= & y %.0f < & 255 0 ?") \ : String(X,"x %.0f")+String(X+W," >= x %.0f")+String(Y," < & y %.0f")+String(Y+H," >= & y %.0f < &") + \ String(X+BW," x %.0f")+String(X+W-BW," < x %.0f")+String(Y+BH," >= | y %.0f")+String(Y+H-BH," < | y %.0f >= | & 255 0 ?") return Last.Blankclip(Length=1,pixel_type=(Y8)?"Y8":"YV12").mt_lutspa(relative=false,Yexpr=Rpn, chroma = "-128" ) } Code:
ColorBars.Killaudio BlankClip(Width=640,height=480,Pixel_type="YV12").BoxMask(x=32,y=32,w=-32,h=-32,BW=0) return last ![]() Its a bit more complicated than needed [does hollow box if required], and could just change the "255 0 ?" bits at the end of lines to whatever values required. Hollow Box Code:
ColorBars.Killaudio BlankClip(Width=640,height=480,Pixel_type="YV12").BoxMask(x=32,y=32,w=-32,h=-32,BW=64) 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; 17th March 2021 at 14:05. |
||
![]() |
![]() |
![]() |
#51 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
OK, new test Mod
Code:
# Stab_Light_Mod.avsi /* This script can be IMPORT()'ed under Avs+, OR, under Avs v2.60 Standard [ONLY IF GScript is installed]. Can also be GIMPORT()'ed when GScript Installed. Can Also be auto Loaded by Avisynth if in Plugins directory. [needs Gscript installed if not AVS+]. Can Also be dumped in AvsInit()'s GIMPORT directory for auto loading by AvsInit(). */ Function Fb2FnNameEx_Mod(String Fn){Try{Eval(Fn+"()")B=True}catch(e){Assert(e.FindStr("syntax")==0,"Fb2FnNameEx_Mod: Error in Function Name '"+Fn+"'")B=(e.FindStr("no function named")==0)}Return B} Fb2IsPlus_Mod = (FindStr(VersionString,"AviSynth+")!=0) Fb2HasGScript_Mod = Fb2FnNameEx_Mod("GScipt") Fb2_GS_S_Mod = """ Function FillBorders2_Low_Mod(clip c, clip pre,clip cblank,clip preblank,Float thr,int Pad,int MaxB,bool debug,String Font) { c w=width h=height x1=0 for(i=1, MaxB) { if(pre.Crop(i-1,0,1,0).AverageLuma < thr) { x1=i} else { i=MaxB } } x1=x1>0?x1+pad:0 x2=0 for(i=1, MaxB) { if(pre.Crop(w-i,0,1,0).AverageLuma < thr) { x2=i} else { i=MaxB } } x2=x2>0?x2+pad:0 y1=0 for(i=1, MaxB) { if(pre.Crop(0,i-1,0,1).AverageLuma < thr) { y1=i} else { i=MaxB } } y1=y1>0?y1+pad:0 y2=0 for(i=1, MaxB) { if(pre.Crop(0,h-i,0,1).AverageLuma < thr) { y2=i} else { i=MaxB } } y2=y2>0?y2+pad:0 PreBlur = 0 # If > 0 then there may be an error PostBlur = 0 # Max(x1, x2, y1, y2, 4) #If > 0 then there may be an error max_fix = Max(x1, x2, y1, y2) msk = (max_fix >= 8) \ ? preblank.LetterBox(y1, y2, x1, x2, color=$ffffff).ConvertToYV12() \ : cblank fixed = (max_fix==0) ? Last \ : (max_fix < 8) ? FillBorders(left=x1, top=y1, right=x2, bottom=y2, mode=0, y=3, u=3, v=3) \ : InpaintLogo(mask=msk, Radius=Max(max_fix,5)*1.5, PreBlur=PreBlur, PostBlur=PostBlur) (debug) \ ? mt_merge(fixed, cblank.ConvertToRGB().LetterBox(y1, y2, x1, x2, color=$ff3333) \ .ConvertToYV12(),preblank.LetterBox(y1, y2, x1, x2, color=$ffffff).ConvertToYV12(), luma=true) \ .Subtitle(FillBorders2_Mod_dBugS(y1,x1,x2,y2), lsp = 10, text_color=$ff3333, font=Font, x=MaxB+5, y=MaxB+5) \ : fixed Return Last } """ /* If this avsi script is not in plugins, then HasGScript [Fb2HasGScript_Mod] can be FALSE, even if using GImport() from Gscript dll. Not sure why this occurs, so even if Fb2HasGScript_Mod==FALSE and is NOT Avs+, then we use Gscript's GEval instead of Eval to install above FillBorders2_TestBord_Mod(). We use Eval() to install the function, ONLY if GScript not installed and is AVS+. */ Try { (Fb2HasGScript_Mod||!Fb2IsPlus_Mod) ? GEval(Fb2_GS_S_Mod) : Eval(Fb2_GS_S_Mod) } catch (msg) { Assert(False,ScriptFile+": Need GScript or Avs+"+Chr(10)+ \ "IsPlus="+String(Fb2IsPlus_Mod)+" : HasGScript="+String(Fb2HasGScript_Mod)+Chr(10)+ \ "SysErr="+Msg) } Function Stab_Light_Mod(clip clp, int "ts", int "range", int "dxmax", int "dymax", float "zoom", float "PAR", \ bool "mirror", int "MaxBorders", bool "FixBorders", bool "FixFalPos", bool "debug") { ts = Default(ts, 7) # frames to temporal average for better motion estimation (max. 7) range = Default(range, 1) # frames before/after to estimate motion dxmax = Default(dxmax, Round(clp.Width()/180.0)) #maximum deviation in pixels dymax = Default(dymax, dxmax) # x, and y should be the same zoom = Default(zoom, 1) # maximum zoom factor (1 disabled) PAR = Default(PAR, 1.0) # PAR of your source mirror = Default(mirror, false) # Edge filling MaxBorders = Default(MaxBorders, Max(Round(clp.Width()/60.0), 20)) FixBorders = Default(FixBorders, true) FixFalPos = Default(FixFalPos, true) # Fixes borders of MaxBorders more pixels wide debug = Default(debug, false) temp = TemporalSoften(clp, ts, 255, 255, 25, 2) # SC thr to 25 otherwise pans will stutter rep = Repair(temp, TemporalSoften(clp, 1, 255, 255, 25, 2)) inter = Interleave(rep, clp) # temporal stable (better subpixel detection) pre_clp = inter.mt_lut(expr="x 20 1 x 127.5 / - 21 ^ pi x * 255 / cos 21 ^ - * 1.05 * -", Y=3, U=2, V=2).RemoveGrain(mode=17) #ColorYUV(levels="PC->TV") mdata = DePanEstimate(pre_clp, range=range, pixaspect=PAR, trust=0, dxmax=dxmax, dymax=dymax, zoommax=zoom) dp = DePan(inter, data=mdata, offset=-1, mirror=mirror?15:0, pixaspect=PAR, matchfields=false, subpixel=2) stab = SelectEvery(dp, 2, 0) w = Width(clp) h = Height(clp) thr = 10.0 pre = stab.ConvertToY8()#.ColorYUV(off_y=-15) stab = (!mirror && FixFalPos) \ ? gScriptClip(stab, " AverageLuma(Crop(pre, 0, 0, -w+MaxBorders+1, 0)) < thr ? clp : \ AverageLuma(Crop(pre, w-MaxBorders-1, 0, 0, 0)) < thr ? clp : \ AverageLuma(Crop(pre, 0, 0, 0, -h+MaxBorders+1)) < thr ? clp : \ AverageLuma(Crop(pre, 0, h-MaxBorders-1, 0, 0)) < thr ? clp : Last Return Last ", args="clp, pre, MaxBorders, w, h, thr",Local=true) \ : stab Return (!mirror && FixBorders) \ ? FillBorders2_Mod(stab, thr=thr, pad=1, MaxBorders=MaxBorders, debug=debug) \ : stab } Function FillBorders2_Mod(clip c, float "thr", int "pad", int "MaxBorders", bool "debug") { Function FillBorders2_Mod_dBugS(int y1,int x1,int x2,int y2) { Return "Black borders:\n "+string(y1)+"\n "+string(x1)+" "+string(x2)+"\n "+ string(y2) } thr = Default(thr, 5.0) pad = Default(pad, 0) MaxB = Default(MaxBorders, Max(Round(c.Width()/60.0), 20)) debug = Default(debug, false) cblank = c.mt_lut( "0", chroma="-128") pre = c.ConvertToY8()#.ColorYUV(off_y=-15) # Moved out of gScriptclip preblank = cblank.ConvertToY8() font="Courier New" gScriptClip(c, " Return FillBorders2_Low_Mod(Last,pre,cblank,preblank,thr,Pad,MaxB,debug,Font) ",args="pre,cblank,preblank,thr,pad,MaxB,debug,Font",Local=true) } Code:
AVSI_FN = ".\Stab_Light.avsi" AVSI_FN_MOD = ".\Stab_Light_Mod.avsi" Import(AVSI_FN) Import(AVSI_FN_MOD) DEBUG=True ORG=AviSource(".\Src.Avi") # OP's sample, Left Half, After ffmpeg conversion to UT_Video AVI A = ORG.Stab_Light (zoom = 1.00, mirror = false, FixFalPos = true, FixBorders = true, debug = DEBUG) B = ORG.Stab_Light_Mod(zoom = 1.00, mirror = false, FixFalPos = true, FixBorders = true, debug = DEBUG) D=B.ClipDelta(A,AMP=true) T=StackHorizontal(ORG,A) B=StackHorizontal(B,D) StackVertical(T,B) Return Last # Return Clip Difference of input clips (amp==true = Amplified, show==true = show background) Function ClipDelta(clip clip1,clip clip2,bool "amp",bool "show") { amp=Default(amp,false) show=Default(show,false) c2=clip1.levels(128-32,1.0,128+32,128-32,128+32).greyscale() c1=clip1.subtract(clip2) c1=(amp)?c1.levels(127,1.0,129,0,255):c1 return (show)?c1.Merge(c2):c1 } Actually, maybe Thr should be higher for AverageLuma on pixel rows/comumns, not lower.
__________________
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 March 2021 at 22:37. |
![]() |
![]() |
![]() |
#52 | Link |
Registered User
Join Date: Feb 2021
Posts: 103
|
We are back to where we started. I think the best version of the script is in post #38.
Yes. If the border is 1 px, then border may not be found. But with an increase in Thr (from 1 to 25), the speed of the script decreases. I decided that the most optimal option is when Thr=10. |
![]() |
![]() |
![]() |
#53 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
OK, but I may still continue playing with this.
(As currently implemented in Stab_Light/_Mod, it would seem to me to be a bit un-reliable, ie testing blocks rather than scanlines with Averageluma. If I can figure out what I/we are tryin' to do, then I could maybe make faster than post #38, RT_Stats has some tools that could maybe be of great use here, but currently only for 8 bit.) Does Depan thing generate digital 0 [Y=0] for synthetic borders ? And is it the synthetic borders we are tryin' to detect, or includes original src borders too ? [ I'm hoping to learn as little as possible about depan etc ![]() Side topic, This snippit from original stab3.avsi [modded somewhat, not sure if currently working as intended] Code:
Function FindBlackBorders(clip c, int "width", int "thr", string "path", string "filename") { add = Default(width,1) # Width for detection, normally 1 should suffix to most situations thr = Default(thr,1) # Threshold for detection, pixels lower than this value will be considered a border path = Default(path, "C:") # This is the path to store the statistics file filename = Default(filename, "FindBlackBorders - Statistics.log") # Filename of the statistics file fn = path + "\" + filename Y =c.converttoy8() L1=Y.crop(0,0,add,0) R1=Y.crop(Y.width-add,0,0,0) T1=Y.crop(0,0,0,add) B1=Y.crop(0,Y.height-add,0,0) c.ScriptClip(""" WriteFileIf(fn,string(L1.AverageLuma<thr||R1.AverageLuma<thr||T1.AverageLuma<thr||B1.AverageLuma<thr), \ Chr(34)+"CHAPTER00="+FFFormatTime(round(current_frame*1000/framerate))+Chr(34), \ Append=Current_frame!=0) """, args= "thr,L1,R1,T1,B1, fn",Local=true) #converttoyv12() # Bug or limitations of 8-bit masktools with Overlay or... # mt_merge (masking PC Range masks) so use Dither tools #Dither_merge16_8(Dither_convert_8_to_16(),Dither_convert_8_to_16(c),mt_lut("255"),luma=true) #ditherpost(mode=-1) #c.Echo(Last) # Maybe replace above dither stuff ??? # EDIT: Not using Echo(), input clip c to Scriptclip instead. return last } Code:
A=Colorbars(pixel_type="YV12").Trim(0,-10).KillAudio.AssumeFPS(10.0) B=A.Letterbox(32,0,0,0) B++A++B FindBlackBorders(Path = "D:\DVD", thr=20) return last Code:
CHAPTER00=0:00:00.000 CHAPTER00=0:00:00.100 CHAPTER00=0:00:00.200 CHAPTER00=0:00:00.300 CHAPTER00=0:00:00.400 CHAPTER00=0:00:00.500 CHAPTER00=0:00:00.600 CHAPTER00=0:00:00.700 CHAPTER00=0:00:00.800 CHAPTER00=0:00:00.900 CHAPTER00=0:00:02.000 CHAPTER00=0:00:02.100 CHAPTER00=0:00:02.200 CHAPTER00=0:00:02.300 CHAPTER00=0:00:02.400 CHAPTER00=0:00:02.500 CHAPTER00=0:00:02.600 CHAPTER00=0:00:02.700 CHAPTER00=0:00:02.800 CHAPTER00=0:00:02.900 Can it be replaced by v2.60 Echo() filter ? [to return original source clip and still write log file] EDIT: Replaced Echo, see script in GREEN. Original source script Code:
#################################### ### ### FindBlackBorders() ### ### (http://forum.videohelp.com/threads/371336) ### ### Script to find sources with black borders for example as a result of bad deshaking, run on analysis pass ### The output file is formatted to be imported to avspmod as bookmarks ### use ClipClop() afterwards on a scene by scene basis to fix this. ### ### "width" is border thickness for detection ### "thr" is threshold, pixel values below this will be considered borders ### "path" is the path to store the statistics file, with end backslash. Default is "C:" ### "filename" is the statistics file name. In case you don't want to overwrite old ones ### ### Dependencies: ### ### Required: ### ------------ ### ### masktools (v2a48 or higher) (http://forum.doom9.org/showthread.php?t=98985) ### Dither (v1.26.5 or higher) (http://forum.doom9.org/showthread.php?p=1386559#post1386559) ### #################################### function FindBlackBorders(clip c, int "width", int "thr", string "path", string "filename") { add = Default(width,1) # Width for detection, normally 1 should suffix to most situations thr = Default(thr,1) # Threshold for detection, pixels lower than this value will be considered a border path = Default(path, "C:") # This is the path to store the statistics file filename = Default(filename, "FindBlackBorders - Statistics.log") # Filename of the statistics file c converttoy8() w=width() h=height() L1=crop(0,0,-w+add,0) R1=crop(w-add,0,0 ,0) T1=crop(0,0,0,-h+add) B1=crop(0,h-add,0 ,0) ScriptClip(""" x1 = AverageLuma(L1) < thr ? true : false x2 = AverageLuma(R1) < thr ? true : false y1 = AverageLuma(T1) < thr ? true : false y2 = AverageLuma(B1) < thr ? true : false function IsBorder(clip c, bool x1, bool x2, bool y1, bool y2) {return (x1||y1||x2||y2)?true:false} q = chr(34)chr(34)chr(34) WriteFileIf(""+path+"\"+filename+"", " "+string(IsBorder(x1,y1,x2,y2))+" ", q+"CHAPTER00="+q, \ "FFFormatTime_stabi(round((current_frame * 1000) / framerate()))", "", "") """,args="thr,L1,R1,T1,B1,path,filename") converttoyv12() # Bug or limitations of 8-bit masktools with Overlay or... # mt_merge (masking PC Range masks) so use Dither tools Dither_merge16_8(Dither_convert_8_to_16(),Dither_convert_8_to_16(c),mt_lut("255"),luma=true) ditherpost(mode=-1) } Code:
CHAPTER00=0:00:02.900 ![]() EDIT: Quote:
__________________
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 March 2021 at 16:33. |
|
![]() |
![]() |
![]() |
#54 | Link |
Registered User
Join Date: Feb 2021
Posts: 103
|
DePan creates completely black borders. They can be seen if FixBorders=false. My algorithm finds any black borders, including in the original clip. I have created a "debug" option to control how the black border search algorithm works.
By the way, DePan can fix black borders by itself, but only with a mirror image. They can be seen if mirror=true. I didn't understand why the FindBlackBorders (in stab3.avsi) function is needed. Why would I create a timestamped text file? What should I do with it? I don't see any point in it. Last edited by Arx1meD; 17th March 2021 at 16:49. |
![]() |
![]() |
![]() |
#55 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
Thanks for your answers.
Quote:
I was just looking at it and it looked well weird. eg Code:
q=Chr(34)Chr(34)Chr(34) x1 = AverageLuma(L1) < thr ? true : false function IsBorder(clip c, bool x1, bool x2, bool y1, bool y2) {return (x1||y1||x2||y2)?true:false} I just asked as I thought you might be familiar with that original script, as you produced the light version FillBorders thing. EDIT: The ?true:false constant whotsits are storeed in Global variables list, to access them, is slow, and scans Local vars and then Global if not found in locals. Global vars are slow to access, and true/false are stored right near end of list and so very slow to access, Avs+ sped this up somewhat with a hash table but probably still slow, particularly irksome if in scriptclip and not actually needed when logical true/false is already known. [ie, instead of returning Global variable true when the answer is true, and Global variable false when the answer is false, just return the answer instead. return (x1||y1||x2||y2)?true:false this part, (x1||y1||x2||y2) is evaluated by the avs parser, and is quite quick, does not access true or false globals at all, the result is calculated to be true or 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 ??? Last edited by StainlessS; 17th March 2021 at 18:28. |
|
![]() |
![]() |
![]() |
#56 | Link |
Registered User
Join Date: Feb 2021
Posts: 103
|
I also found this FindBlackBorders function strange. I refused to use it. I took only two of the most efficient functions from stab3.avsi: Stab3 and FillBorders_stabi. Then I simplified them.
I am using AviSynth+ and have not even tried to test the script in other versions. |
![]() |
![]() |
![]() |
#58 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
Your light version works in v2.60 and above.
The FindBlackBorders thing, I think that the dither stuff in it was because of a colorshift problem if using Overlay on a clip. The reason for Overlay, was to ensure that WriteFile was processed on the Y8 clip. [must contribute to the output clip, else does nothing]. Must have been written before v2.60 Echo() which when given 2 clips can force read the 2nd one, and so force WriteFile to work proper. I've changed it around to work without my guessed reason for Dither thing. Also made small mod since prev post on it, changed thr to float. Using RT_Stats RT_WriteFile is way easier then Avs standard builtin Writefile which I find infuriating [at times]. Here the slight mod Code:
#################################### ### ### FindBlackBorders() ### ### (http://forum.videohelp.com/threads/371336) ### ### Script to find sources with black borders for example as a result of bad deshaking, run on analysis pass ### The output file is formatted to be imported to avspmod as bookmarks ### use ClipClop() afterwards on a scene by scene basis to fix this. ### ### "width" is border thickness for detection ### "thr" is threshold, pixel values below this will be considered borders. ssS: changed to Float. ### "path" is the path to store the statistics file, without end backslash. Default is "C:" ### "filename" is the statistics file name. In case you don't want to overwrite old ones ### ### Dependencies: ### ### Required: ### ------------ ### GRunT (v1.0.1 or higher) (http://forum.doom9.org/showthread.php?t=139337) #################################### Function FindBlackBorders(clip c, int "width", Float "thr", string "path", string "filename") { add = Default(width,1) # Width for detection, normally 1 should suffix to most situations thr = Default(thr,1.0) # Threshold for detection, pixels lower than this value will be considered a border path = Default(path, "C:") # This is the path to store the statistics file filename = Default(filename, "FindBlackBorders - Statistics.log") # Filename of the statistics file fn = path + "\" + filename Y =c.converttoy8() L1=Y.crop(0,0,add,0) R1=Y.crop(Y.width-add,0,0,0) T1=Y.crop(0,0,0,add) B1=Y.crop(0,Y.height-add,0,0) c.gScriptClip(""" WriteFileIf(fn,string(L1.AverageLuma<thr||R1.AverageLuma<thr||T1.AverageLuma<thr||B1.AverageLuma<thr), \ Chr(34)+"CHAPTER00="+FFFormatTime(round(current_frame*1000/framerate))+Chr(34), \ Append=Current_frame!=0) """, args= "thr,L1,R1,T1,B1, fn",Local=true) return last } [getting rid of old stock, was £39.95 when on sale at full price, 49.00 euros on Amazon, and 59.0 Euros on manufacturer site]. 16MP, Has Fake [interpolated] 4K30FPS, but 2.7K30FPS, 1080P60FPS, 1080P30FPS, 720P90FPS, 720P60FPS, 720P30FPS. Anyway, thought I might need a deshaker type thing for it, so looking at this stuff a bit more closely. I Aint no photographer, I dont know an F Stop from a Bus Stop, but thought I might give it a try. EDIT: My other action cam is crap with fake 1080P30FPS. EDIT: I think it [Rollei] can also do 720P120FPS, according to Android app. it seems to be an AllWinner v3 camera. [Android SOC] Here a site that I'm probably gonna join at some point, for hacking action camera firmware. https://www.goprawn.com/forum Somebody on-site seem to be aware of Vdub2 and Avisynth. although older [circa 2016 posts on 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; 17th March 2021 at 19:41. |
![]() |
![]() |
![]() |
#59 | Link |
Registered User
Join Date: Feb 2021
Posts: 103
|
I work on restoring old cartoons mostly. And they all have the same problems: shaking, flickering and wrong white balance. If the shaking problem is solved, but there is no good solution with the flickering. All existing filters do not work well with cartoons. I use your GamMac to correct the wrong white balance. Thank you so much! He gives the best result compared to others.
|
![]() |
![]() |
![]() |
#60 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,158
|
Sorry, I missed this question posted just before one of my posts.
Quote:
There are some situations where implicit return of Last dont work proper eg, Code:
Function z() { q = BlankClip q Global Fred=True # If final line in function then cause implicit return Last to fail # q # return last } z EDIT: Must have Return Last at end, unless last line in script function is assignment to Last [either explicit or implicit assign]. [think that is about right] I saw recently a Didee post on simple de-flicker, involved (I think) downsize, temporalsoften, upsize, maybe. [EDIT: also maybe apply some masktools thing too at end]. EDIT: Think this was the thread on de-flicker that I was thinkin' bout [Deflicker]:- https://forum.doom9.org/showthread.php?t=166355
__________________
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 2021 at 18:51. |
|
![]() |
![]() |
![]() |
Tags |
deshaker |
Thread Tools | Search this Thread |
Display Modes | |
|
|