Advertisement
Zastin

dhh.py

Jul 29th, 2017
1,242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.77 KB | None | 0 0
  1. import vapoursynth as vs
  2. import math
  3. core = vs.core
  4.  
  5.  
  6. def mask(clip, radius=0, thr=None, thr2=70, mode=3, smooth=False, dha=False):
  7. """
  8. DeHaloHmod mask, original by AmjadSONY - https://forum.doom9.org/showthread.php?t=145898#post1675762
  9. Basically a very accurate cartoon lineart mask
  10.  
  11. radius settings above 0 will build a dehaloing mask (std.Maximum() * radius)
  12. in mode 3, raising thr/thr2 actually has the opposite effect (though not much of one)
  13.  
  14. smooth=True will enable a little extra line protection by smoothing the inner zone a bit, and sets an insanely high default "thr" value
  15. dha=True enables close-adjacent line protection for dehalo_alpha and other similar dehaloing scripts
  16. """
  17.  
  18. f = clip.format
  19. bits = f.bits_per_sample
  20. isINT = f.sample_type==vs.INTEGER
  21.  
  22. thr = thr if thr is not None else 2250 if smooth and mode==3 else 140
  23.  
  24. mask = EMask(togray(clip), mode, thr, thr2)
  25.  
  26. if radius>0:
  27. radius = math.ceil(radius)
  28. inside = mask.std.Inflate(threshold=155 << (bits - 8) if isINT else 155/255) if smooth else mask
  29. outside = inside
  30. for _ in range(radius):
  31. outside = outside.std.Maximum()
  32. if dha:
  33. inside = outside
  34. for _ in range(radius):
  35. inside = inside.std.Minimum()
  36.  
  37. return core.std.Expr([outside.std.Inflate(), inside], 'x y -') if radius>0 else mask
  38.  
  39.  
  40. def EMask(clip, mode, thr, thr2=70):
  41.  
  42. f = clip.format
  43. bits = f.bits_per_sample
  44. isINT = f.sample_type==vs.INTEGER
  45. max = 1 << bits if isINT else 1
  46. peak = max-1 if isINT else 1
  47. half = max//2 if isINT else 0.5
  48.  
  49. if mode == 0:
  50. return Camembert(clip)
  51. elif mode == 1:
  52. thr = thr << (bits - 8) if isINT else (thr-128)/255
  53. return clip.std.Convolution([1]*9).std.Convolution([1]*9).std.MakeDiff(clip).std.Binarize(thr).std.Inflate().std.Inflate()
  54. elif mode == 2:
  55. thr1 = 105 << (bits - 8) if isINT else 0.406393
  56. thr2 = 110 << (bits - 8) if isINT else 0.429224
  57. return core.std.Expr([clip.std.Binarize(thr1, v0=peak, v1=0).std.Maximum(), clip.std.Binarize(thr2, v0=0, v1=peak).std.Maximum()],"x y min").std.Deflate()
  58. else:
  59. a = 140 if isINT else 0.70710678118654752440084436210485
  60. b = 29 if isINT else 0.14644660940672623779957781894758
  61. c = 6 if isINT else 0.03033008588991064330063327157864
  62. lines = FastLineDarkenMOD3(FastLineDarkenMOD3(clip, thr).std.Convolution([c,b,c,b,a,b,c,b,c]), 250,1,250,-2)
  63. dark = thr2 << (bits - 8) if isINT else thr2/255
  64. return core.std.Expr([Camembert(clip), lines], 'y {} <= x 0 ?'.format(dark))
  65.  
  66. def Camembert(clip):
  67.  
  68. f = clip.format
  69. bits = f.bits_per_sample
  70. isINT = f.sample_type==vs.INTEGER
  71. max = 1 << bits if isINT else 1
  72. peak = max-1 if isINT else 1
  73. half = max//2 if isINT else 0.5
  74.  
  75. last = clip.rgvs.RemoveGrain(11).rgvs.RemoveGrain(11) if isINT else clip.std.Convolution([1,2,1,2,4,2,1,2,1]).std.Convolution([1,2,1,2,4,2,1,2,1])
  76. last = clip.std.MakeDiff(last) if isINT else core.std.Expr([clip, last], 'x y - 0.5 +')#Overlay(clip, last, mode="difference")
  77. last = last.std.Expr("x {half} - {peak} {half} - / {peak} * x {half} / 0 {peak} - * {peak} + max".format(half=half, peak=peak))
  78. last = last.std.Expr("x {d} / {peak} *".format(d=155 << (bits - 8) if isINT else 155/255, peak=peak))
  79. last = last.rgvs.RemoveGrain(11) if isINT else last.std.Convolution([1,2,1,2,4,2,1,2,1])
  80. last = last.std.Expr("x {d} / 2.5 pow {peak} *".format(d=64 << (bits - 8) if isINT else 64/255, peak=peak))
  81. last = last.rgvs.RemoveGrain(11).rgvs.RemoveGrain(11) if isINT else last.std.Convolution([1,2,1,2,4,2,1,2,1]).std.Convolution([1,2,1,2,4,2,1,2,1])
  82. last = last.std.Expr("x {d} / {peak} *".format(d=30 << (bits - 8) if isINT else 30/255, peak=peak))
  83. return last.rgvs.RemoveGrain(11) if isINT else last.std.Convolution([1,2,1,2,4,2,1,2,1])
  84.  
  85. def FastLineDarkenMOD3(clip, strength=48, prot=5, luma_cap=191, threshold=4):
  86. core = vs.core
  87.  
  88. f = clip.format
  89. bits = f.bits_per_sample
  90. isINT = f.sample_type==vs.INTEGER
  91. size = 1 << bits
  92. peak = size-1 if isINT else 1
  93. half = size//2 if isINT else 0.5
  94. clamp = '' if isINT else ' 1 min 0 max'
  95.  
  96. str = strength/128
  97. lum = luma_cap << (bits-8) if isINT else luma_cap/255
  98. thr = threshold << (bits-8) if isINT else threshold/255
  99. mexpr = 'y {lum} < y {lum} ? x {thr} + > x y {lum} < y {lum} ? - 0 ? {str} * x + '.format(lum=lum, thr=thr, str=str)
  100.  
  101. exin = clip.std.Maximum(threshold=peak/(prot+1)).std.Minimum()
  102. thick = core.std.Expr([clip, exin], mexpr+clamp)
  103.  
  104. return thick
  105.  
  106. def getmatrix(clip):
  107. if clip.width <= 1024 and clip.height <= 576:
  108. return 6
  109. if clip.width <= 2048 and clip.height <= 1536:
  110. return 1
  111. return 9
  112.  
  113. def togray(clip, bits=None, dmode=3, range=None):
  114.  
  115. f = clip.format
  116. cf = f.color_family
  117. isGRAY = cf==vs.GRAY
  118. isYUV = cf==vs.YUV
  119. in_st = f.sample_type
  120. in_bits = f.bits_per_sample
  121.  
  122. bits = in_bits if bits==None else bits
  123. st = in_st if in_bits==bits else vs.INTEGER if bits < 32 else vs.FLOAT
  124.  
  125. if (in_bits, in_st) == (bits, st) and isGRAY:
  126. return clip
  127. elif (in_bits, in_st) == (bits, st) and isYUV:
  128. return clip.std.ShufflePlanes(0, vs.GRAY)
  129. else:
  130. format = core.register_format(vs.GRAY, st, bits, 0, 0)
  131. matrix = None if isGRAY or isYUV else getmatrix(clip)
  132. dither_type = dmode if isinstance(dmode, str) else 'ordered' if dmode==0 else 'none' if dmode<3 else 'error_diffusion'
  133. return clip.resize.Spline36(format=format.id, matrix=matrix, dither_type=dither_type, range_in=range, range=range)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement