Advertisement
Guest User

Stabilization Tools Pack

a guest
Dec 5th, 2016
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ###                                                      #
  2. ###                                                      #
  3. ### Stabilization Tools Pack 2.1 by Dogway (16-09-2015)  #
  4. ###                       mod by A.SONY in (06-12-2016)  #
  5. ###                                                      #
  6. ##########################################################
  7. ###
  8. ### FilmGateFix()
  9. ###
  10. ###  (http://forum.videohelp.com/threads/371336)
  11. ###
  12. ### Function to fix frames ( by means of FreezeFrame() ) with film gate issues after a scene change.
  13. ### This is aimed at animation, for live footage frame interpolation should be desired.
  14. ###
  15. ### Rationale:
  16. ### Film Gate is about non-linear vertical stretching, thus we compare
  17. ### current and next frames in two blocks, a 1/5 block of top and bottom.
  18. ### The difference in both should be very high for film gate artifacts
  19. ### between the 2nd and 3rd frame after a Scene Change (also 1st and 2nd are compared).
  20. ### We mask this through a Scene Detection filter, motion masks, etc.
  21. ###
  22. ###  EXPERIMENTAL:
  23. ###  It still grabs too many false-positives, and leaves many positives-positives undone
  24. ###  a better approach would be to automatically bookmark every scene change and manually freezeframe them
  25. ###
  26. ###
  27. ### Dependencies:
  28. ###
  29. ### Required:
  30. ### ------------
  31. ###
  32. ###   MVTools       (v2.5.11.3 or higher)               (http://avisynth.org.ru/mvtools/mvtools2.html)
  33. ###   masktools     (v2a48 or higher)                   (http://forum.doom9.org/showthread.php?t=98985)
  34. ###   Average       (v0.92 or higher)                   (http://forum.doom9.org/showthread.php?t=169832)
  35. ###   GRunT         (v1.0.1 or higher)                  (http://forum.doom9.org/showthread.php?t=139337)
  36. ###
  37. ####################################
  38.  
  39. function FilmGateFix(clip c,  float "thr", int "window", int "thSCD1", int "thSCD2", bool "debug") {
  40.  
  41. thr     = Default(thr,1.2)      # Main tweak setting, use debug and tweak according 2nd frame after Scene Change
  42. window  = Default(window,5)     # Enlarges/reduces detection area, "height()/window"
  43. thSCD1  = Default(thSCD1,500)   # Increase to reduce number of scenes detected
  44. thSCD2  = Default(thSCD2,145)   # Increase to reduce number of scenes detected
  45. Debug   = Default(Debug,false)  # Check what frames will be fixed and the difference value of frames for tweaking "thr"
  46. thr2    = 5.0                   # central part of frame must change less than this to consider static scene to fix.
  47.  
  48. c
  49. w=width()
  50. h=height()
  51.  
  52. # Block for Scene Change detection and Motion Mask
  53. kind   = 0
  54. gam    = 1.2 # Could probably be exposed
  55. mvthr  = 30  # Threshold, heavily dependent on gamma value above
  56. super  = MSuper  (pel=1, sharp=0,vpad=0,hpad=0)
  57. b1v    = MAnalyse(super,isb=true, blksize=16,overlap=8,search=0)
  58. f1v    = MAnalyse(super,isb=false, blksize=16,overlap=8,search=0)
  59. SADbv1 = MMask   (b1v,kind=kind,gamma=gam,thSCD1=thSCD1,thSCD2=thSCD2)
  60. SADfv1 = MMask   (f1v,kind=kind,gamma=gam,thSCD1=thSCD1,thSCD2=thSCD2)
  61.  
  62. SceneChange = MSCDetection (f1v,thSCD1=thSCD1,thSCD2=thSCD2)
  63. mvmask      = Average(SADbv1,1./2,SADfv1,1./2)
  64.  
  65.  
  66. # Film Gate happens commonly between 2nd and 3rd frame after SC
  67. # 1st frame is commonly garbage
  68. add  = round(w/(window*1.0))
  69. T    = crop(0,0,0,((-h+add)/8)*8)
  70. B    = crop(0,((h-add)/8)*8,0,0)
  71.  
  72. L    = crop(0,0,((-w+add)/8)*8,0)
  73. R    = crop(((w-add)/8)*8,0,0,0)
  74.  
  75. CTB  = crop(0,((add)/8)*8,0,-((add)/8)*8)
  76. CLR  = crop(round(((add*1.5)/8)*8),0,round(-((add*1.5)/8)*8),0)
  77.  
  78. SC2  = mt_logic(SceneChange,selectevery(SceneChange,1,-1),"max",U=3,V=3)
  79.  
  80. # Here, if after SC top area changes more than "thr" compared to bottom area
  81. # then apply one FreezeFrame() for first SC frame, and another FreezeFrame() for the 2nd one,
  82. # they (1st and 2nd) compute individually. There is a motionmask on top to rule out false positives.
  83. scriptclip("""(abs(YDifferenceToNext(T)-YDifferenceToNext(B))>"""+string(thr)+""" && abs(YDifferenceToNext(CTB))<"""+
  84.             \ string(thr2)+""") || (abs(YDifferenceToNext(L)-YDifferenceToNext(R))>"""+string(thr)+
  85.             \ """ && abs(YDifferenceToNext(CLR))<"""+string(thr2)+""") ?"""+
  86.             \ """(YplaneMax(SC2)>254?(YDifferenceFromPrevious(SC2)>250?(AverageLuma(mvmask)<"""+string(mvthr)+
  87.             \ """?(LumaDifference(c,d)<3.7?freezeframe(current_frame,current_frame,current_frame+2):(YDifferenceToNext()<8.0?freezeframe(current_frame,current_frame,current_frame+1):c)):c):"""+
  88.             \ """(AverageLuma(mvmask)<"""+string(mvthr)+"""?freezeframe(current_frame,current_frame,current_frame+1):c)):c):c""",
  89.             \ args="T,B,L,R,c,SC2,CTB,CLR,mvmask,d=Trim(2,0)")
  90.  
  91. # Debug block
  92. debug ? +\
  93. eval("""stackhorizontal(scriptclip("Subtitle(c,"+Chr(34)+" Top & Bottom:"+Chr(34)+"+String(YDifferenceToNext(T)-YDifferenceToNext(B))+
  94.        \ "+Chr(34)+"\n Left & Right:  "+Chr(34)+"+String(YDifferenceToNext(L)-YDifferenceToNext(R))+
  95.        \ "+Chr(34)+"\n Center Horiz:  "+Chr(34)+"+String(YDifferenceToNext(CTB))+
  96.        \ "+Chr(34)+"\n Center Vert:    "+Chr(34)+"+String(YDifferenceToNext(CLR))+
  97.        \ "+Chr(34)+"\n AvgLuma:    "+Chr(34)+"+String(LumaDifference(c,d)),
  98.        \ align=7,size=30,lsp=10)",args="T,B,L,R,c,CTB,CLR,d=Trim(2,0)"),
  99.       \ scriptclip("AverageLuma(mvmask)<"""+string(mvthr)+"""?((abs(YDifferenceToNext(T)-YDifferenceToNext(B))>"+string(thr)+
  100.           \ " && abs(YDifferenceToNext(CTB))<"+string(thr2)+") || (abs(YDifferenceToNext(L)-YDifferenceToNext(R))>"+
  101.           \ string(thr)+" && abs(YDifferenceToNext(CLR))<"+string(thr2)+") ? "+
  102.           \ "(YplaneMax(SC2)>254?(LumaDifference(c,d)<3.7?mt_lut(c,"+Chr(34)+"255"+Chr(34)+",U=128,V=128):(YDifferenceToNext()<8.0?mt_lut(c,"+Chr(34)+"255"+Chr(34)+",U=128,V=128):mt_lut(c,"+Chr(34)+"0"+Chr(34)+
  103.           \ ",U=128,V=128))):mt_lut(c,"+Chr(34)+"0"+Chr(34)+",U=128,V=128)):mt_lut(c,"+Chr(34)+"0"+Chr(34)+",U=128,V=128)):mt_lut(c,"+Chr(34)+"0"+
  104.           \ Chr(34)+",U=128,V=128)",args="T,B,L,R,c,CTB,CLR,SC2,mvmask,d=Trim(2,0)"))
  105.           \ crop(0,0,-(round(w/1.1)/2)*2,0).Subtitle("Frame to Freeze",align=9,size=40)""") : last }
  106.  
  107.  
  108.  
  109.  
  110.  
  111. ####################################
  112. ###
  113. ### FillBorders()
  114. ###
  115. ###  (http://forum.videohelp.com/threads/371336)
  116. ###
  117. ### Function to fill dark (use threshold) borders, in the vein of old FillMargins() function.
  118. ### But instead of mirroring or other approaches like resizing, this function fills/interpolates
  119. ### missing data from surrounding pixels.
  120. ### Useful to use as a clean pass after stab() and crop(x1,y1,x2,y2)
  121. ### for the remaining thin black borders (up to 3px)
  122. ###
  123. ### For borders of 4px and more you can enable FixFalPos, there you supply a clip
  124. ### without black borders (ie. before stab() ). It automatically replaces the offended frames.
  125. ### Some thick black borders aren't "0" black at all, they show garbage and the 3+1 pixel border
  126. ### may not average to 0, so a "thr2" setting is added as threshold, default 7 should be enough.
  127. ###
  128. ### Below you can still use the the FindBlackBorders() function for manual handling of thick black borders.
  129. ### Use ClipClop() for the stab() results according to the statistics file of FindBlackBorders()
  130. ###
  131. ### Mind you, for FillBorders() you need to manually load the AVSInpaint plugin:
  132. ### LoadCPlugin("AVSInpaint.dll")
  133. ###
  134. ###  EXPERIMENTAL:
  135. ###  Some thick black borders aren't value 0 at all, sometimes they average to 16, so one would
  136. ###  need to set thr2 to >16 which will basically bypass the Stab'ed clip in a lot of dark scenes.
  137. ###  So probably you might still want to use this for only <4px borders and FindBlackBorders() to
  138. ###  manually find the most offending borders and problematic areas.
  139. ###
  140. ###
  141. ### Dependencies:
  142. ###
  143. ###   masktools     (v2a48 or higher)                   (http://forum.doom9.org/showthread.php?t=98985)
  144. ###   GRunT         (v1.0.1 or higher)                  (http://forum.doom9.org/showthread.php?t=139337)
  145. ###   AVSInpaint    (v2008.02.23 or higher)             (http://forum.doom9.org/showthread.php?t=133682)
  146. ###
  147. ####################################
  148.  
  149. function FillBorders(clip c, int "thr", int "pad", bool "blur", bool "debug", clip "FixFalPos", int "thr2") {
  150.  
  151. thr      = Default(thr, 1)      # Threshold, pixel values below this will be considered borders
  152. pad      = Default(pad, 0)      # Pixels, you can expand the replacement area adding more pixels
  153.                                 # (to deal with dirty borders) (use "1" to deal with 1px b/w chroma, due to the chroma subsampling nature of video)
  154. blur     = Default(blur ,false) # Blurs the masking for the replacement area. Currently not supported for InpaintLogo()
  155. debug    = Default(debug,false) # Show the borders that are going to be filled
  156. FalPos   = Defined(FixFalPos) ? true : false # If you supply a reference clip borders with 4 or more
  157.                                 # average thr2 pixels will be replaced with the clip's frame
  158. thr2     = Default(thr2, 7)     # Threshold for FalPos, FalPos frames sometimes have garbage borders so you need to increase threshold
  159.  
  160. ssispmt = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0
  161.  
  162. c
  163. ssispmt ? !isy() ? converttoy() : last : !isy8() ? converttoy8() : last
  164. yclip=last
  165. w=width()
  166. h=height()
  167.  
  168. # 4px or greater
  169. L4=FalPos ? crop(0,0,-w+4,0) : nop()
  170. R4=FalPos ? crop(w-4,0,0 ,0) : nop()
  171. T4=FalPos ? crop(0,0,0,-h+4) : nop()
  172. B4=FalPos ? crop(0,h-4,0 ,0) : nop()
  173. # 3px
  174. L3=crop(0,0,-w+3,0)
  175. R3=crop(w-3,0,0 ,0)
  176. T3=crop(0,0,0,-h+3)
  177. B3=crop(0,h-3,0 ,0)
  178. # 2px
  179. L2=crop(L3,0,0,-1, 0)
  180. R2=crop(R3,1,0,0 , 0)
  181. T2=crop(T3,0,0,0 ,-1)
  182. B2=crop(B3,0,1,0 , 0)
  183. # 1px
  184. L1=crop(L3,0,0,-2,0 )
  185. R1=crop(R3,2,0,0 ,0 )
  186. T1=crop(T3,0,0,0 ,-2)
  187. B1=crop(B3,0,2,0 ,0 )
  188.  
  189. c
  190. Fill = gScriptClip("""
  191. yclip
  192. pad= blur ? pad+2 : pad
  193.  
  194. x1 = AverageLuma(L1) < thr ? (AverageLuma(L2) < thr ? (AverageLuma(L3) < thr ? 3+pad : 2+pad) : 1+pad) : 0
  195. x2 = AverageLuma(R1) < thr ? (AverageLuma(R2) < thr ? (AverageLuma(R3) < thr ? 3+pad : 2+pad) : 1+pad) : 0
  196. y1 = AverageLuma(T1) < thr ? (AverageLuma(T2) < thr ? (AverageLuma(T3) < thr ? 3+pad : 2+pad) : 1+pad) : 0
  197. y2 = AverageLuma(B1) < thr ? (AverageLuma(B2) < thr ? (AverageLuma(B3) < thr ? 3+pad : 2+pad) : 1+pad) : 0
  198.  
  199. FalPos = FalPos ? ((x1-pad > 2 || x2-pad > 2 || y1-pad > 2 || y2-pad > 2 )
  200.              \ ? ((AverageLuma(L4) < thr2) || (AverageLuma(R4) < thr2) || (AverageLuma(T4) < thr2) || (AverageLuma(B4) < thr2)
  201.              \ ? true : false) : false) : false
  202.  
  203.  
  204. ter = !FalPos && (x1+y1+x2+y2>0)
  205.  
  206. msk  = LetterBox(mt_lut("0"),y1,y2,x1,x2,$ffffff).trim(0,-1).FreezeFrame(0, FrameCount(last)-1, 0).mt_lut("x 128 > 255 x ?")
  207. msk  = blur ? msk.mt_convolution("1 1 1 1 1", "1 1 1 1 1") : msk
  208. msk  = ssispmt ? !isy(c) ? CombinePlanes(msk,c,planes="YUV",sample_clip=c) : msk : !isy8(c) ? YToUV(c.UToY8(),c.VToY8(),msk) : msk
  209.  
  210. fill = FalPos ? trim(c,0,current_frame-1)++trim(FixFalPos,current_frame,-1)++trim(c,current_frame+1,0) : \
  211.         (ter ? InpaintLogo(c, radius=max(x1,y1,x2,y2)+max(2,pad), mask=msk) : c)
  212. sub  = debug  ? subtitle(msk,"Bordered",align=3,size=round(h/20.0)) : nop()
  213.  
  214. debug ? (ter?sub:msk) : fill
  215. """,args="yclip,c,ssispmt,thr,thr2,L4,R4,T4,B4,L3,R3,T3,B3,L2,R2,T2,B2,L1,R1,T1,B1,pad,blur,debug,FalPos,FixFalPos")
  216.  
  217. !debug ? Fill : \
  218. eval("""
  219. box    = h/4.0
  220. m      = 2
  221.  
  222. corner = crop(mt_lut("255"),round((w-box)/m)*m,round((h-box)/m)*m,0,0,align=true)
  223. corner = corner.addborders(0,0,round((w/2.0-box)/m)*m,round(box/m)*m).mt_lut("x 255 < 0 255 ?")
  224.  
  225. horiz  = stackhorizontal(corner,corner.fliphorizontal())
  226. verti  = stackvertical(horiz,horiz.flipvertical())
  227.  
  228. mt_merge(c,Fill.pointresize(w,h),verti,luma=true)""") }
  229.  
  230.  
  231. ####################################
  232. ###
  233. ### FindBlackBorders()
  234. ###
  235. ###  (http://forum.videohelp.com/threads/371336)
  236. ###
  237. ### Script to find sources with black borders for example as a result of bad deshaking, run on analysis pass
  238. ### The output file is formatted to be imported to avspmod as bookmarks
  239. ### use ClipClop() afterwards on a scene by scene basis to fix this.
  240. ###
  241. ### "width" is border thickness for detection
  242. ### "thr" is threshold, pixel values below this will be considered borders
  243. ### "path" is the path to store the statistics file, with end backslash. Default is "C:"
  244. ### "filename" is the statistics file name. In case you don't want to overwrite old ones
  245. ###
  246. ### Dependencies:
  247. ###
  248. ### Required:
  249. ### ------------
  250. ###
  251. ###   masktools     (v2a48 or higher)                   (http://forum.doom9.org/showthread.php?t=98985)
  252. ###   Dither        (v1.26.5 or higher)                 (http://forum.doom9.org/showthread.php?p=1386559#post1386559)
  253. ###
  254. ####################################
  255.  
  256. function FindBlackBorders(clip c, int "width", int "thr", string "path", string "filename") {
  257.  
  258. add      = Default(width,1)     # Width for detection, normally 1 should suffix to most situations
  259. thr      = Default(thr,1)       # Threshold for detection, pixels lower than this value will be considered a border
  260. path     = Default(path, "C:")  # This is the path to store the statistics file
  261. filename = Default(filename, "FindBlackBorders - Statistics.log") # Filename of the statistics file
  262.  
  263. c
  264. converttoy8()
  265. w=width()
  266. h=height()
  267.  
  268. L1=crop(0,0,-w+add,0)
  269. R1=crop(w-add,0,0 ,0)
  270. T1=crop(0,0,0,-h+add)
  271. B1=crop(0,h-add,0 ,0)
  272.  
  273. ScriptClip("""
  274. x1 = AverageLuma(L1) < thr ? true : false
  275. x2 = AverageLuma(R1) < thr ? true : false
  276. y1 = AverageLuma(T1) < thr ? true : false
  277. y2 = AverageLuma(B1) < thr ? true : false
  278. function IsBorder(clip c, bool x1, bool x2, bool y1, bool y2) {return (x1||y1||x2||y2)?true:false}
  279.  
  280. q = chr(34)chr(34)chr(34)
  281. WriteFileIf(""+path+"\"+filename+"", " "+string(IsBorder(x1,y1,x2,y2))+" ", q+"CHAPTER00="+q,
  282.        \ "FFFormatTime_stabi(round((current_frame * 1000) / framerate()))", "", "")
  283. """,args="thr,L1,R1,T1,B1,path,filename")
  284.  
  285. converttoyv12()
  286.  
  287. # Bug or limitations of 8-bit masktools with Overlay or...
  288. # mt_merge (masking PC Range masks) so use Dither tools
  289. Dither_merge16_8(Dither_convert_8_to_16(),Dither_convert_8_to_16(c),mt_lut("255"),luma=true)
  290. ditherpost(mode=-1) }
  291.  
  292.  
  293.  
  294. ####################################
  295. ###
  296. ### Stab2()
  297. ###
  298. ###  (http://forum.videohelp.com/threads/371336)
  299. ###
  300. ### For completeness I'm going to list all the shortcomings of Depan plugin
  301. ### maybe a programmer realises the urge of an avisynth bug-free stabilizer:
  302. ### -Color tint (hue shift to green) when subpixel>0 to stablizated frames --> addressed here
  303. ### -Artifacts occasionally on frame borders (1px skew) --> crop out, check example
  304. ### -No advanced border fill --> addressed above ( FillBorders() )
  305. ### -Some false-positives when people clapping, trembling...
  306. ### -Requires mod 4 inputs?
  307. ### -No medium jitter fix
  308. ### -Some thick borders (false positives) aren't 0 black on the inner side
  309. ###
  310. #######################################
  311. ###
  312. ### What I improved over original Stab() was to work around the first issue by
  313. ###     counter fixing the planes hue deviation on a frame by frame basis with float point precision
  314. ### Implemented a FixPalPos to replace frames that present black borders of 3 or more pixels
  315. ###     with source frames, check output just in case, since some borders don't average to 0 black (rare).
  316. ### Also supplied a more contrasty clip version for more subtle global motion analysis
  317. ### Prefilter is for the prefilter clip, in case the clip is very grainy/noisy
  318. ### Finally a few more things were introduced by testing and checking other script versions.
  319. ###
  320. ###
  321. ### Required (*Optional):
  322. ### ------------
  323. ###   Depan         (v1.10.1 or higher)                 (http://avisynth.org.ru/depan/depan.html)
  324. ###   DePanEstimate (v1.10.1 or higher)                 (http://avisynth.org.ru/depan/depan.html)
  325. ###   Dither        (v1.26.5 or higher)                 (http://forum.doom9.org/showthread.php?p=1386559#post1386559)
  326. ###   SmoothAdjust* (v3.0 or higher)                    (http://forum.doom9.org/showthread.php?t=154971)
  327. ###   AutoAdjust    (v2.50 or higher)                   (http://forum.doom9.org/showthread.php?t=167573)
  328. ###   GRunT         (v1.0.1 or higher)                  (http://forum.doom9.org/showthread.php?t=139337)
  329. ###   Repair        (vanilla or tp7's branch)           (http://avisynth.nl/index.php/Removegrain)
  330. ###
  331. ### Example:
  332. ###
  333. ### stab2(UVfix=true,FixFalPos=true)
  334. ### crop(2,2,-2,-2) # to remove garbage around borders
  335. ###
  336. ####################################
  337.  
  338. function Stab2 (clip clp, int "ts", int "range", int "dxmax", int "dymax", bool "UVfix", bool "FixFalPos", float "zoom", int "mirror", float "PAR", clip "Prefilter") {
  339.  
  340. ts     = default(ts, 7)        #frames to temporal average for better motion estimation (max. 7)
  341. range  = default(range, 3)     #frames before/after to estimate motion
  342. dxmax  = default(dxmax, 15)    #maximum deviation in pixels (use at least 8 for SD)
  343. dymax  = default(dymax, 15)    #x, and y should be the same
  344. zoom   = default(zoom, 1)      #maximum zoom factor (1 disabled)
  345. mirror = default(mirror, 0)    #Edge filling. 0 off, 15 everything on
  346. PAR    = default(PAR, 1.0)     #PAR of your source
  347. UVfix  = default(UVfix, true)  # Fixes the bug of change of HUE in Depan,
  348. FixFalPos  = default(FixFalPos, true) # Fixes borders of 3 or more pixels wide. Use along crop(2,2,-2,-2)...
  349.                                       # ...after stab2() to get rid of border issues entirely
  350.  
  351. Pref   = Defined(Prefilter) ? Prefilter : clp
  352. temp   = Pref.TemporalSoften(ts,255,255,25,2) # SC thr to 25 otherwise pans will stutter
  353. rep    = temp.Repair(Pref.TemporalSoften(1,255,255,25,2))
  354. inter  = Interleave(rep,Pref)
  355.  
  356. # temporal stable auto-contrast (better subpixel detection)
  357. Luma_Expa = AutoAdjust(inter,temporal_radius=10,auto_balance=false,auto_gain=true,use_interp=true,\
  358.            avg_safety=0.25,dark_limit=10,bright_limit=10,gamma_limit=1.0,dark_exclude=0.05,bright_exclude=0.05,\
  359.            chroma_process=0,scd_threshold=16,input_tv=false,output_tv=false,high_bitdepth=false,debug_view=false)
  360.  
  361. mdata = DePanEstimate(Luma_Expa,range=range,pixaspect=PAR,trust=0,dxmax=dxmax,dymax=dymax,zoommax=zoom,improve=true)
  362.  
  363. DePan(Defined(Prefilter)?Interleave(rep,clp):inter,data=mdata,offset=-1,mirror=mirror,pixaspect=PAR,matchfields=false,subpixel=2)
  364. SelectEvery(2,0)
  365.  
  366. # from depansafe() function
  367. FixFalPos ? eval("""
  368. thick = 2.0  # removing >2px wide borders
  369. cropx = ceil(dxmax)*2
  370. ratiox = "YPlaneMax("+string(ceil(99-thick/cropx*100))+")"
  371.  
  372. crop(0,0,0,cropx).conditionalfilter(last,clp,ratiox,">","0")
  373. crop(0,height-cropx,0,0).conditionalfilter(last,clp,ratiox,">","0")
  374. crop(0,0,cropx,0).conditionalfilter(last,clp,ratiox,">","0")
  375. crop(width-cropx,0,0,0).conditionalfilter(last,clp,ratiox,">","0")""") : last
  376.  
  377.  
  378. UVfix ? eval("""
  379. ScriptClip ("
  380. blue=round((AverageChromaU(clp) - AverageChromaU()) * 256.0)
  381. red=round((AverageChromaV(clp) - AverageChromaV()) * 256.0)
  382.  
  383. Dither_convert_8_to_16()
  384. SmoothTweak16(saturation=1.0,hue1=min(384,blue),hue2=min(384,red),HQ=true)
  385. DitherPost(stacked=true,prot=false,mode=6)
  386. ", args="clp" ) """) : last
  387.  
  388. }
  389.  
  390.  
  391. ####################################
  392. ###
  393. ### Stab3()
  394. ###
  395. ### same as Stab2 but with some changes
  396. ###
  397. ####################################
  398.  
  399. function Stab3 (clip clp, int "ts", int "range", int "dxmax", int "dymax", bool "UVfix", bool "FixFalPos", float "zoom", int "mirror", float "PAR", clip "Prefilter", int "Luma_Exp", bool "Fill3pBorders") {
  400.  
  401. ts     = default(ts, 7)        #frames to temporal average for better motion estimation (max. 7)
  402. range  = default(range, 1)     #frames before/after to estimate motion
  403. dxmax  = default(dxmax, Round(clp.width()/180.0)) #maximum deviation in pixels
  404. dymax  = default(dymax, dxmax) #x, and y should be the same
  405. zoom   = default(zoom, 1)      #maximum zoom factor (1 disabled)
  406. mirror = default(mirror, 0)    #Edge filling. 0 off, 15 everything on
  407. PAR    = default(PAR, 1.0)     #PAR of your source
  408. UVfix  = default(UVfix, false)  # Fixes the bug of change of HUE in Depan, not need in depan 1.13.1 and up
  409. b3fix  = default(Fill3pBorders, true) # Fixes borders of 3 or less pixels wide.
  410. FixFalPos  = default(FixFalPos, true) # Fixes borders of 3 or more pixels wide. Use along crop(2,2,-2,-2)...
  411.                                       # ...after stab2() to get rid of border issues entirely
  412. Lumae  = default(Luma_Exp, 1) #Luma Rebuild
  413.  
  414. Pref   = Defined(Prefilter) ? Prefilter : clp
  415. temp   = Pref.TemporalSoften(ts,255,255,25,2) # SC thr to 25 otherwise pans will stutter
  416. rep    = temp.Repair(Pref.TemporalSoften(1,255,255,25,2))
  417. inter  = Interleave(rep,Pref)
  418.  
  419. # temporal stable auto-contrast (better subpixel detection)
  420. Luma_Expa = Lumae==2 ? AutoAdjust(inter,temporal_radius=10,auto_balance=false,auto_gain=true,use_interp=true,\
  421.            avg_safety=0.25,dark_limit=10,bright_limit=10,gamma_limit=1.0,dark_exclude=0.05,bright_exclude=0.05,\
  422.            chroma_process=0,scd_threshold=16,input_tv=false,output_tv=false,high_bitdepth=false,debug_view=false) : \
  423.             Lumae==1 ? inter.ColorYUV(levels="TV->PC") : inter
  424.  
  425. mdata = DePanEstimate(Luma_Expa,range=range,pixaspect=PAR,trust=0,dxmax=dxmax,dymax=dymax,zoommax=zoom)
  426.  
  427. DePan(Defined(Prefilter)?Interleave(rep,clp):inter,data=mdata,offset=-1,mirror=mirror,pixaspect=PAR,matchfields=false,subpixel=2)
  428. SelectEvery(2,0)
  429.  
  430. stabclip=last
  431.  
  432. # from depansafe() function
  433. FixFalPos ? eval("""
  434. thick = b3fix ? 3.0 : 2.0  # removing >2px wide borders
  435. cropx = dxmax*2
  436. ratiox = "YPlaneMax("+string(ceil(99-thick/cropx*100))+")"
  437.  
  438. crop(0,0,0,cropx).conditionalfilter(last,clp,ratiox,">","0")
  439. crop(0,height-cropx,0,0).conditionalfilter(last,clp,ratiox,">","0")
  440. crop(0,0,cropx,0).conditionalfilter(last,clp,ratiox,">","0")
  441. crop(width-cropx,0,0,0).conditionalfilter(last,clp,ratiox,">","0")""") : last
  442.  
  443. bpad = b3fix ? Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0 ? !(clp.is444() || clp.isy()) : VersionNumber() < 2.60 ? clp.isyv12() : !(clp.isyv24() || clp.isy8()) : nop()
  444.  
  445. b3fix ? stabclip.FillBorders(pad=bpad ? 1 : 0,FixFalPos=FixFalPos ? last : Undefined) : last
  446.  
  447. UVfix ? eval("""
  448. lumaf=last
  449. ScriptClip ("
  450. blue=round((AverageChromaU(clp) - AverageChromaU()) * 256.0)
  451. red=round((AverageChromaV(clp) - AverageChromaV()) * 256.0)
  452.  
  453. Dither_convert_8_to_16()
  454. SmoothTweak16(saturation=1.0,hue1=min(384,blue),hue2=min(384,red),HQ=true)
  455. DitherPost(stacked=true,prot=false,mode=6,y=1,slice=false)
  456. ", args="clp" )
  457. Mergeluma(lumaf)
  458. """) : last
  459.  
  460. }
  461.  
  462.  
  463. ######### HELPER FUNCTIONS #########
  464.  
  465. # Helper function for FindBlackBorders() from FFMS2.avsi
  466. function FFFormatTime_stabi(int ms) {
  467.     s = ms / 1000
  468.     ms = ms % 1000
  469.     m = s / 60
  470.     s = s % 60
  471.     h = m / 60
  472.     m = m % 60
  473.     return string(h) + ":" + string(m,"%02.0f") + ":" + string(s,"%02.0f") + "." + string(ms,"%03.0f")}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement