Advertisement
nanogyth

deblink_lib.avs

Apr 12th, 2012
344
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. LoadPlugin("mvtools2.dll")
  2. LoadPlugin("mt_masktools-26.dll")
  3.  
  4. function ng_deblink(clip clp,
  5. \ float "ratio",
  6. \ int "level",
  7. \ clip "blinkmask"
  8. \){
  9. #Version 10 2012.04.22
  10.  
  11.     blink = default(blinkmask, clp.ng_blinkmask())
  12.  
  13.     ratio = default(ratio, 2.0 /3)
  14.     assert(ratio >= 0.0 && 1.0 >= ratio,
  15.     \      "[ng_deblink] 1.0 >= ratio >= 0.0, it was " + string(ratio))
  16.  
  17.     level = default(level, round(ratio * 257))
  18.     assert(level >= 0 && 257 >= level,
  19.     \      "[ng_deblink] 257 >= level >= 0, it was " + string(level))
  20.  
  21.     m01=mt_logic(blink.SelectEvery(4,0),
  22. \                blink.SelectEvery(4,1),
  23. \                mode="or").ConvertToRGB32()
  24.     m23=mt_logic(blink.SelectEvery(4,2),
  25. \                blink.SelectEvery(4,3),
  26. \                mode="or").ConvertToRGB32()
  27.  
  28.     f0=Layer(clp.SelectEvery(4,0),
  29. \            clp.SelectEvery(4,1).Mask(m01),
  30. \            level=level)
  31.     f1=Layer(clp.SelectEvery(4,1),
  32. \            clp.SelectEvery(4,0).Mask(m01),
  33. \            level=level)
  34.     f2=Layer(clp.SelectEvery(4,2),
  35. \            clp.SelectEvery(4,3).Mask(m23),
  36. \            level=(257-level) )
  37.     f3=Layer(clp.SelectEvery(4,3),
  38. \            clp.SelectEvery(4,2).Mask(m23),
  39. \            level=(257-level) )
  40.  
  41.     Interleave(f0,f1,f2,f3)
  42. }
  43.  
  44. function ng_blinkmask(clip clp,
  45. \ bool "TEST",
  46. \ bool "STABILIZE",
  47. \ bool "SHARP",
  48. \ bool "HYSTER",
  49. \ int "inpand",
  50. \ int "expand",
  51. \ int "ml"
  52. \){
  53. #Version 10 2012.04.22
  54.  
  55. #BLINK
  56. # Blinking is a block that alternates on/off each frame
  57. # SelectEven would only see either the on or the off
  58.  
  59. #FLASH
  60. # Flashing is a block that is only on for a single frame
  61. # SelectEven might miss the flash
  62.  
  63. #SHAKE
  64. # Shaking is a block that moves back/forth each frame
  65. # SelectEven would only see one position
  66.  
  67. # The goal of this function is to make a blink mask for use with
  68. # ng_deblink. For overly complicated scenes where a clean blinkmask
  69. # can't be found, just use TASBlend. Uniform softness looks better
  70. # than sharp artifacts.
  71.  
  72. # This function calculates flash and shake info for the test script,
  73. # but those effects should be handled in different ways.
  74. # Flash - choose frames to make sure the flash is in your final clip.
  75. # Shake - SelectEvery(4,0,2,1,3) or SelectEvery(4,1,0,2,3)
  76. # SelectEvery doesn't generally work because it messes with the fluidity
  77. # of motion. But that won't be noticable on a shaking screen.
  78. # Be careful if 2 frame blinking is present, as the selectevery can turn
  79. # it into 1 frame blinking.
  80.  
  81.     TEST      = default(     TEST, false)
  82.     STABILIZE = default(STABILIZE, true)
  83.     SHARP     = default(    SHARP, true)
  84.     HYSTER    = default(   HYSTER, false)
  85.     inpand    = default(   inpand, 1)
  86.     expand    = default(   expand, 1)
  87.     ml        = default(       ml, 128)
  88.  
  89. # The functions used to make the masks work in the YV12 colorspace. Once
  90. # the masks are created they can be used in the RGB32 colorspace direcly
  91.     src=clp.ConvertToYV12()
  92.  
  93. # Blinking is located by looking for blocks that don't exist in
  94. # consecutive frames. The motion vector will match blocks that exist in
  95. # both frames. The blocks that aren't in both will end up with huge
  96. # values that are picked out by the motion mask.
  97.     super = MSuper(src, pel=1)
  98.     fvec  = MAnalyse(super, isb=false, blksize=4)
  99.     bvec  = MAnalyse(super, isb=true , blksize=4)
  100.     fmask = Mmask(src, fvec, kind=1, ml=ml).mt_binarize()
  101.     bmask = Mmask(src, bvec, kind=1, ml=ml).mt_binarize()
  102.     blink = mt_logic(fmask, bmask, mode="and")
  103.  
  104. # Blinking usually occurs against a stable background. This is found
  105. # by looking at blocks 2 frames apart. This distinguishes a blink from
  106. # blocks that are just changing every frame.
  107.     ee_src   = src.SelectEven()
  108.     ee_super = MSuper(ee_src, pel=1)
  109.     ee_fvec  = MAnalyse(ee_super, isb=false, blksize=4)
  110.     ee_bvec  = MAnalyse(ee_super, isb=true , blksize=4)
  111.     ee_fmask = Mmask(ee_src, ee_fvec, kind=1, ml=ml).mt_binarize()
  112.     ee_bmask = Mmask(ee_src, ee_bvec, kind=1, ml=ml).mt_binarize()
  113.  
  114.     oo_src   = src.SelectOdd()
  115.     oo_super = MSuper(oo_src, pel=1)
  116.     oo_fvec  = MAnalyse(oo_super, isb=false, blksize=4)
  117.     oo_bvec  = MAnalyse(oo_super, isb=true , blksize=4)
  118.     oo_fmask = Mmask(oo_src, oo_fvec, kind=1, ml=ml).mt_binarize()
  119.     oo_bmask = Mmask(oo_src, oo_bvec, kind=1, ml=ml).mt_binarize()
  120.  
  121.     fmask_2   = Interleave(ee_fmask, oo_fmask)
  122.     bmask_2   = Interleave(ee_bmask, oo_bmask)
  123.     background = mt_logic(fmask_2.SelectEvery(1,1),
  124. \                         bmask_2.SelectEvery(1,-1),
  125. \                         mode="or")
  126.     stable_blink = mt_hysteresis(background.mt_invert, blink)
  127.     blink2 = (STABILIZE) ? stable_blink : blink
  128.  
  129. # Shrinking the blink mask can get rid of noise,
  130. # too much will lose signal as well.
  131.     blink3 = blink2.mt_inpand(mode=mt_diamond(inpand))
  132.    
  133. # Using just pixels that changed helps sharpen the mask
  134.     diff   = ng_diff(clp.SelectEvery(1,-1), clp)
  135.     diff_2 = mt_logic(diff, diff.SelectEvery(1,1), mode="and")
  136.  
  137. #Hysteresis
  138. # Matches continuous blocks of pixels.
  139. # Use with care, will match the whole screen on fades.
  140.     hyster_blink = mt_hysteresis(blink3, diff_2)
  141.  
  142. # Expand the mask to make up for shrinking it (or just use hysteresis)
  143.     blink4 = blink3.mt_expand(mode=mt_circle(expand))
  144.     sharp_blink = mt_logic(blink4, diff_2, mode="and")
  145.  
  146.     blink5 = (HYSTER) ? hyster_blink :
  147. \            (SHARP)  ? sharp_blink  : blink4
  148.  
  149.    
  150. # A flash won't match blocks 1 or 2 frames away.
  151.     sub_flash = mt_logic(fmask_2, bmask_2, mode="and")
  152.     flash     = mt_logic(blink, sub_flash, mode="and")
  153.    
  154. # A shake changes in one frame and changes back in the next.
  155. # This isn't detected by the motion vectors because the blocks exist in
  156. # both frames, they are just shifting around.
  157.     same   = ng_same(clp.SelectEvery(1,-1), clp.SelectEvery(1,1))
  158.     shake  = mt_logic(same, diff_2, mode="and")
  159.  
  160.     (TEST) ? stackhorizontal(clp, mergeRGB(blink5, flash, shake))
  161. \          : blink5.GreyScale()
  162. }
  163.  
  164. function ng_diff(clip A, clip B, int "thr"){
  165.     thr=default(thr,0)
  166.     TAD=ng_TAD(A,B)
  167.     return mt_binarize(TAD, threshold=thr)
  168. }
  169.  
  170. function ng_same(clip A, clip B, int "thr"){
  171.     thr=default(thr,0)
  172.     TAD=ng_TAD(A,B)
  173.     return mt_binarize(TAD, threshold=thr, upper=true)
  174. }
  175.  
  176. function ng_TAD(clip A, clip B){
  177.     R=ng_AD(A  .showRed("YV12"),B  .showRed("YV12"))
  178.     G=ng_AD(A.showGreen("YV12"),B.showGreen("YV12"))
  179.     B=ng_AD(A .showBlue("YV12"),B .showBlue("YV12"))
  180.     return ng_plus(R, ng_plus(G, B))
  181. }
  182.  
  183. function ng_AD(clip A, clip B){
  184.     return mt_lutxy(A,B,"x y - abs")
  185. }
  186.  
  187. function ng_plus(clip A, clip B){
  188.     return mt_lutxy(A,B,"x y +")
  189. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement