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. |
4th April 2021, 21:01 | #21 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,352
|
I would test with no mod borders, in my case it crops more than 4 pixels anyway. I also did a second test with more strict settings to proof myself wrong but I get both mentioned issues.
It easily fails on dark scenes, yours is well lit at borders I think. Code:
RC_IGNORE = 0.00 RC_WMOD = 2 # Width multiple of this RC_HMOD = 2 # Height multiple of this RC_LEFTSKIP = 0 # Crop at least these RC_TOPSKIP = 0 RC_RIGHTSKIP = 0 RC_BOTSKIP = 0 |
4th April 2021, 21:56 | #22 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
If your borders are SOLID single color, the yes RC_IGNORE=0.0 sounds good.
I'm gonna go play with FredAverage, and add mask like I said earlier today.
__________________
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 April 2021, 21:31 | #23 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,352
|
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 } Last edited by Dogway; 22nd April 2021 at 22:03. |
23rd April 2021, 16:08 | #24 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,352
|
Unfortunately I still don't know how to manage variable lifetime of runtime functions, but needed to finish the script for some projects so I went down the rabbit hole and found a method, it does the same and it's very fast, false positives are reduced to a minimum. I still need to do some slight fine tuning but this is pretty much the script done. I even added a hybrid method where IMAX scenes would center in -mode 0- (so content is not cropped) but 2.40 scenes are upscaled to fit -mode 2-.
Code:
function MatteCrop(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/8)))) 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 same or below this will be considered borders mode = Default(mode, 2) # 0: center+pad 1: crop to minimum (WIP) 2: resize to maximum 3:hybrid 0-2 (auto) SC_thr = Default(SC_thr, 3.5) kernel = Default(kernel, "spline36") # Kernel to use when resizing (mode=2) addw==0 ? Assert( addh>0, "You need to scan borders for at least one of the dimension") : nop() addh==0 ? Assert( addw>0, "You need to scan borders for at least one of the dimension") : nop() thr = thr*bdpth avg = contoy ? sisphbd ? converttoy() : converttoy8() : last avg = avg.RatioResize(320.0,"adjust2w",kernel="bicubic") blk_b = avg.blankclip(width=16,height=16,pixel_type="Y8",fps=framerate(c),color=$000000).killaudio() blk_w = avg.blankclip(width=16,height=16,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) # need to turn converttoyv12 into other formats as source avg = avg.RatioResize(float(w),"adjust2w",kernel="bicubic").MatchColorFormat(c) avgsc= Overlay(c.greyscale(),avg,mask=BoxMaskf(addw,w-addw,addh,h-addh,show=true),greymask=true, mode="blend", opacity=1.0) SC = SCSelect_HBD(avg,blk_w,blk_b,blk_b,dfactor=SC_thr,mindif=1.0) ScriptClip(""" step = Mot ? 1 : 2 LBF=current_frame x1=0 x2=0 y1=0 y2=0 # 1440 frames -1 min on 24fps- lookback YPlaneMax(SC)<128 ? Eval(" for (LB=0, 1440, 1) { if (YPlaneMax(trim(SC,current_frame-LB,-1))>128) { LBF=current_frame-LB LB=1440 } }") : nop() trim(avgsc,LBF+10,-1) addw > 0 ? Eval(" for (li=step, addw, step) { if (AverageLuma(crop(li-step,0,-w+li,0,align=true))>thr) { x1= CM ? li : li-step li=addw } } for (ri=step, addw, step) { if (AverageLuma(crop(w-ri,0,-ri+step,0,align=true))>thr) { 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,align=true))>thr) { y1= CM ? ti : ti-step ti=addh } } for (bi=step, addh, step) { if (AverageLuma(crop(0,h-bi,0 ,-bi+step,align=true))>thr) { y2= CM ? bi : bi-step bi=addh } }") : nop() 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,align=true) mode == 0 ? padresize(w,h) : \ mode == 1 ? padresize(w,h) : \ mode == 2 ? RatioResize(float(w),"adjust2w", kernel=kernel).padresize(w,h,mirror=false) : \ YPlaneMax(crop( addh > 0 ? width()-16 : 0,0,0, addw > 0 ? -height()+16 : 0)) <= thr ? \ RatioResize(float(w),"adjust2w", kernel=kernel).padresize(w,h,mirror=false) : padresize(w,h) """,args="c,SC,avgsc,addw,addh,w,h,thr,CM,Mot,fullchr,kernel,mode",local=true) 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 } Last edited by Dogway; 23rd April 2021 at 16:37. |
23rd April 2021, 16:46 | #25 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Doggy, can you supply a short testclip and client script, thanks.
[I've found your ResizersPack4.7.4.avsi] EDIT: As a very temporary hack for global survival, you could use RT_Stats DBase or array, and preset fields/elements with eg -1, not set. Then you only need to use a fixed DBase name to read or write, vars can even survive a reboot. EDIT: Code:
DB = "My.DB".RT_GetFullPathName X1_FLD = 0 Y1_FLD = 1 X2_FLD = 2 Y2_FLD = 3 RECORD_0 = 0 TypeString="iiii" # 4 fields of type int RT_DBaseAlloc(DB,1,TypeString) # Single pre-existing record [int field defaults are set to 0] RT_DBaseSet(DB,RECORD_0,-1,-1,-1,-1) # PreSet all vars -1 X1 = RT_DBaseGetField(DB, RECORD_0, X1_FLD) Y1 = RT_DBaseGetField(DB, RECORD_0, Y1_FLD) X2 = RT_DBaseGetField(DB, RECORD_0, X2_FLD) Y2 = RT_DBaseGetField(DB, RECORD_0, Y2_FLD) # ... RT_DBaseSetField(DB, RECORD_0, X1_FLD, X1) RT_DBaseSetField(DB, RECORD_0, Y1_FLD, Y1) RT_DBaseSetField(DB, RECORD_0, X2_FLD, X2) RT_DBaseSetField(DB, RECORD_0, Y2_FLD, Y2) # OR RT_DBaseSet(DB, RECORD_0, X1,Y1,X2,Y2) Avs+ implemented hash table for Globals access. EDIT: DBase is also a way to return multiple results from a function, supply the function with DBase name, and function returns results in DB, with perhaps success status as actual function return.
__________________
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 April 2021 at 17:19. |
23rd April 2021, 17:22 | #26 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,352
|
I sent you a PM. I still need to refine code for sliding mattes, repurpose width and height arguments depending on mode (pad or resize)
Code:
ffvideosource("title_t00_trans1.mkv") MatteCrop(1920,1080,thr=17.0,cropmore=true,scanH=0,scanW=50,mode=3,kernel="spline36",moving=false) As for variable lifetime, I'm precisely trying to avoid creating intermediary files or analysis passes, but I will have a look deeper in case it helps. |
23rd April 2021, 17:41 | #27 | Link |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Thanks Dog, I got the clip.
I wanted the resize pack for the other functions, RatioResize, PadResize and PadMirror. EDIT: The DBase thing could be used in realtime, not multiple pass thingy, and you can even delete the Dbase on clip closure using CallCmd(). EDIT: This part would be done before entering scriptclip, ie create and preset DBase, And supply DB name as arg to scriptclip, Code:
DB = "My.DB".RT_GetFullPathName X1_FLD = 0 Y1_FLD = 1 X2_FLD = 2 Y2_FLD = 3 RECORD_0 = 0 TypeString="iiii" # 4 fields of type int RT_DBaseAlloc(DB,1,TypeString) # Single pre-existing record [int field defaults are set to 0] RT_DBaseSet(DB,RECORD_0,-1,-1,-1,-1) # PreSet all vars -1 The RECORD_0 and X1_FLD stuff is just for self documentation, you would likely use constants instead of variables. During script developement, it is sometimes useful to use vars like X1_FLD etc so things eg field order can be changed around without changing entire script. When completed, then can simply do a mass text Replace of eg X1_FLD with the final chosen constant.
__________________
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 April 2021 at 17:59. |
23rd April 2021, 17:57 | #28 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,352
|
I will try to play with RT_DBaseSet() soon when I recover from yesterday lol, at first sight it looks promising although currently the biggest help would be from finding a method to average ranges of frames based on SCSelect_HBD. Currently I'm doing a convoluted method of stacking TemporalSoften() (with its own SC) and shifting the parsing frame 10 frames into the future from SC for better consistency.
EDIT: just updated ResizersPack. Last edited by Dogway; 23rd April 2021 at 18:02. |
23rd April 2021, 18:06 | #29 | Link | |
HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Quote:
If you can find range then below might be useful. ClipBlend() :- https://forum.doom9.org/showthread.p...ight=clipblend
__________________
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 ??? |
|
15th October 2021, 19:05 | #30 | Link |
Registered User
Join Date: Nov 2009
Posts: 2,352
|
I tested your workflow a few months ago without realizing it also involved writing to disk.
I updated the function today. I used a mix of frame properties for scene change (modded your SCSelect_HBD function) and also your ClipBoard plugin for variable life. The script is now like 50% faster. I wanted to also use properties for the x1,x2,y1,y2 coords, but frame properties didn't cut it, I would need clip properties, and update them every time there's a SC. I read you can use frame 0 as a placeholder for clip properties, might be useful, need to try.
__________________
i7-4790K@Stock::GTX 1070] AviSynth+ filters and mods on GitHub + Discussion thread |
Tags |
align, automatic, crop, reframe |
Thread Tools | Search this Thread |
Display Modes | |
|
|