Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import vapoursynth as vs
- import math
- core = vs.core
- def mask(clip, radius=0, thr=None, thr2=70, mode=3, smooth=False, dha=False):
- """
- DeHaloHmod mask, original by AmjadSONY - https://forum.doom9.org/showthread.php?t=145898#post1675762
- Basically a very accurate cartoon lineart mask
- radius settings above 0 will build a dehaloing mask (std.Maximum() * radius)
- in mode 3, raising thr/thr2 actually has the opposite effect (though not much of one)
- smooth=True will enable a little extra line protection by smoothing the inner zone a bit, and sets an insanely high default "thr" value
- dha=True enables close-adjacent line protection for dehalo_alpha and other similar dehaloing scripts
- """
- f = clip.format
- bits = f.bits_per_sample
- isINT = f.sample_type==vs.INTEGER
- thr = thr if thr is not None else 2250 if smooth and mode==3 else 140
- mask = EMask(togray(clip), mode, thr, thr2)
- if radius>0:
- radius = math.ceil(radius)
- inside = mask.std.Inflate(threshold=155 << (bits - 8) if isINT else 155/255) if smooth else mask
- outside = inside
- for _ in range(radius):
- outside = outside.std.Maximum()
- if dha:
- inside = outside
- for _ in range(radius):
- inside = inside.std.Minimum()
- return core.std.Expr([outside.std.Inflate(), inside], 'x y -') if radius>0 else mask
- def EMask(clip, mode, thr, thr2=70):
- f = clip.format
- bits = f.bits_per_sample
- isINT = f.sample_type==vs.INTEGER
- max = 1 << bits if isINT else 1
- peak = max-1 if isINT else 1
- half = max//2 if isINT else 0.5
- if mode == 0:
- return Camembert(clip)
- elif mode == 1:
- thr = thr << (bits - 8) if isINT else (thr-128)/255
- return clip.std.Convolution([1]*9).std.Convolution([1]*9).std.MakeDiff(clip).std.Binarize(thr).std.Inflate().std.Inflate()
- elif mode == 2:
- thr1 = 105 << (bits - 8) if isINT else 0.406393
- thr2 = 110 << (bits - 8) if isINT else 0.429224
- 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()
- else:
- a = 140 if isINT else 0.70710678118654752440084436210485
- b = 29 if isINT else 0.14644660940672623779957781894758
- c = 6 if isINT else 0.03033008588991064330063327157864
- lines = FastLineDarkenMOD3(FastLineDarkenMOD3(clip, thr).std.Convolution([c,b,c,b,a,b,c,b,c]), 250,1,250,-2)
- dark = thr2 << (bits - 8) if isINT else thr2/255
- return core.std.Expr([Camembert(clip), lines], 'y {} <= x 0 ?'.format(dark))
- def Camembert(clip):
- f = clip.format
- bits = f.bits_per_sample
- isINT = f.sample_type==vs.INTEGER
- max = 1 << bits if isINT else 1
- peak = max-1 if isINT else 1
- half = max//2 if isINT else 0.5
- 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])
- last = clip.std.MakeDiff(last) if isINT else core.std.Expr([clip, last], 'x y - 0.5 +')#Overlay(clip, last, mode="difference")
- last = last.std.Expr("x {half} - {peak} {half} - / {peak} * x {half} / 0 {peak} - * {peak} + max".format(half=half, peak=peak))
- last = last.std.Expr("x {d} / {peak} *".format(d=155 << (bits - 8) if isINT else 155/255, peak=peak))
- last = last.rgvs.RemoveGrain(11) if isINT else last.std.Convolution([1,2,1,2,4,2,1,2,1])
- last = last.std.Expr("x {d} / 2.5 pow {peak} *".format(d=64 << (bits - 8) if isINT else 64/255, peak=peak))
- 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])
- last = last.std.Expr("x {d} / {peak} *".format(d=30 << (bits - 8) if isINT else 30/255, peak=peak))
- return last.rgvs.RemoveGrain(11) if isINT else last.std.Convolution([1,2,1,2,4,2,1,2,1])
- def FastLineDarkenMOD3(clip, strength=48, prot=5, luma_cap=191, threshold=4):
- core = vs.core
- f = clip.format
- bits = f.bits_per_sample
- isINT = f.sample_type==vs.INTEGER
- size = 1 << bits
- peak = size-1 if isINT else 1
- half = size//2 if isINT else 0.5
- clamp = '' if isINT else ' 1 min 0 max'
- str = strength/128
- lum = luma_cap << (bits-8) if isINT else luma_cap/255
- thr = threshold << (bits-8) if isINT else threshold/255
- mexpr = 'y {lum} < y {lum} ? x {thr} + > x y {lum} < y {lum} ? - 0 ? {str} * x + '.format(lum=lum, thr=thr, str=str)
- exin = clip.std.Maximum(threshold=peak/(prot+1)).std.Minimum()
- thick = core.std.Expr([clip, exin], mexpr+clamp)
- return thick
- def getmatrix(clip):
- if clip.width <= 1024 and clip.height <= 576:
- return 6
- if clip.width <= 2048 and clip.height <= 1536:
- return 1
- return 9
- def togray(clip, bits=None, dmode=3, range=None):
- f = clip.format
- cf = f.color_family
- isGRAY = cf==vs.GRAY
- isYUV = cf==vs.YUV
- in_st = f.sample_type
- in_bits = f.bits_per_sample
- bits = in_bits if bits==None else bits
- st = in_st if in_bits==bits else vs.INTEGER if bits < 32 else vs.FLOAT
- if (in_bits, in_st) == (bits, st) and isGRAY:
- return clip
- elif (in_bits, in_st) == (bits, st) and isYUV:
- return clip.std.ShufflePlanes(0, vs.GRAY)
- else:
- format = core.register_format(vs.GRAY, st, bits, 0, 0)
- matrix = None if isGRAY or isYUV else getmatrix(clip)
- dither_type = dmode if isinstance(dmode, str) else 'ordered' if dmode==0 else 'none' if dmode<3 else 'error_diffusion'
- 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