Registered User
Join Date: Nov 2009
Posts: 2,361
|
I have been trying to come up with solutions for longer variable lifetime set at runtime functions, like inside scriptclip, the next is a proof of concept:
Code:
function MatteCrop2(clip c, int "width", int "height", float "thr", bool "CropMore", bool "Moving", int "ScanW", int "ScanH", int "mode", string "kernel", float "SC_thr") {
c
w = width(c)
h = height(c)
sisphbd = AvsPlusVersionNumber > 2294
bdpth = sisphbd ? pow(256.,c.BitsPerComponent()/8.)/256. : 1.
contoy = sisphbd ? !isy() : !isy8()
fullchr = contoy ? sisphbd ? ExtractU().width() == w : UToY8().width() == w : true
nw = Default(width,w)
nh = Default(height,h)
addw = Default(ScanW,int(round((w/5))))
addh = Default(ScanH,int(round((h/4))))
Mot = Default(Moving, False) # If the matte is moving (sliding) this enables pixel level accuracy.
CM = Default(CropMore, Mot || fullchr ? True : False) # In case of odd cropping, either crop 1 pixel out or leave 1 pixel of the border
thr = Default(thr, Mot ? 16.3 : 16.0) # Threshold, pixel values above this will be considered borders
mode = Default(mode, 2) # 0: center+pad 1: crop to minimum (WIP) 2: resize to maximum
SC_thr = Default(SC_thr, 3.5)
kernel = Default(kernel, "spline36") # Kernel to use when resizing (mode=2)
thr = thr*bdpth
avg = contoy ? sisphbd ? converttoy() : converttoy8() : last
avg = avg.RatioResize(640.0,"adjust2w",kernel="bicubic")
blk_b = avg.blankclip(pixel_type="Y8",fps=framerate(c),color=$000000).killaudio()
blk_w = avg.blankclip(pixel_type="Y8",fps=framerate(c),color=$FFFFFF).killaudio()
avg = avg.TemporalSoften(10,255,255,10,2)
avg = avg.TemporalSoften(10,255,255,10,2)
avgsc= RatioResize(float(w),"adjust2w",kernel="bicubic").converttoyv12()
SC = SCSelect_HBD(avg,blk_w,blk_b,blk_b,dfactor=SC_thr,mindif=1.0)
ScriptClip("""
isSC=YPlaneMax(SC)>128
# Obviously Defined() doesn't work here
Defined(x1) || Defined(y1) ? Eval("
for (LB=0, 1440, 1) {
if (YPlaneMax(trim(SC,current_frame-LB,current_frame-LB))>128) {
LBF=current_frame-LB
LB=1440
}
}
") : nop()
trim(avgsc,LBF,LBF)
x1=0 x2=0
y1=0 y2=0
step = Mot ? 1 : 2
addw != 0 ? Eval("
for (li=step, addw, step) {
if (AverageLuma(crop(li-step,0,-w+li,0))>thr) {
global x1= CM ? li : li-step
li=addw
}
}
for (ri=step, addw, step) {
if (AverageLuma(crop(w-ri,0,-ri+step,0))>thr) {
global x2= CM ? ri : ri-step
ri=addw
}
}") : nop()
addh != 0 ? Eval("
for (ti=step, addh, step) {
if (AverageLuma(crop(0,ti-step,0,-h+ti))>thr) {
global y1= CM ? ti : ti-step
ti=addh
}
}
for (bi=step, addh, step) {
if (AverageLuma(crop(0,h-bi,0 ,-bi+step))>thr) {
global y2= CM ? bi : bi-step
bi=addh
}
}") : nop()
#subtitle(string(y2),x=30,y=10,align=5)
MotW = Mot ? round(w-x1-x2) : nop()
MotH = Mot ? round(h-y1-y2) : nop()
Mot ? spline36resizeMT(c,fullchr?MotW:MotW+MotW%2,fullchr?MotH:MotH+MotH%2,src_left=x1,src_width=-x2,src_top=y1,src_height=-y2) : \
crop(c,x1,y1,-x2,-y2)
mode == 0 ? padresize(w,h) : \
mode == 1 ? padresize(w,h) : \
RatioResize(float(w),"adjust2w", kernel=kernel).padresize(w,h,mirror=false)
""",args="c,SC,avgsc,addw,addh,w,h,thr,CM,Mot,w,h,fullchr,kernel,mode",local=true, after_frame=false)
padresize(nw,nh)
(!CM || Mot) && mode==2 ? ContinuityFixer(left=addw>0?2:0, top=addh>0?2:0, right=addw>0?2:0, bottom=addh>0?2:0, radius=CM && w>720?0:1) : last
}
I'm having a hard time setting and holding x1,x2,y1 and y2 variables available as long as there's no a new scene change. Indeed Global doesn't cut it, so for the time being I'm shifting frames in a for loop until a scene change is detected but this is very slow. I tried Gavino's solution here without success though.
Last edited by Dogway; 22nd April 2021 at 22:03.
|