Skip to content

Instantly share code, notes, and snippets.

@blaze077
Last active September 6, 2021 07:15
Show Gist options
  • Save blaze077/ac896645913938591b45e7d65932b136 to your computer and use it in GitHub Desktop.
Save blaze077/ac896645913938591b45e7d65932b136 to your computer and use it in GitHub Desktop.
Collection of Meine Funktionen
import vapoursynth as vs
import functools
import numpy as np
core = vs.core
def extended_dimension(src, dimensions=[0, 0, 0, 0]):
"""
Extends the edges of the clip using the given extension parameters (like negative cropping in Avisynth)
src is the source clip. dimensions is an array of integer values in the following format: [left, right, top, bottom]"""
if len(dimensions) > 4:
raise ValueError("dimensions can only contain 4 values.")
while len(dimensions) < 4:
dimensions.append(0)
if not all(isinstance(d, int) for d in dimensions):
raise ValueError("dimensions must be a list of integers.")
if 0 > min(dimensions):
raise ValueError("dimensions cannot be negative")
w_subsampling=max(src.format.subsampling_w*2, 1)
h_subsampling=max(src.format.subsampling_w*2, 1)
if True in [x % w_subsampling != 0 for x in dimensions[:2]] \
or True in [y % h_subsampling != 0 for y in dimensions[2:4]]:
raise ValueError("The video format is "+src.format.name+".\n You need to enter valid dimension values according to the" \
+ " chroma subsampling.")
left = dimensions[0]//w_subsampling
right = dimensions[1]//w_subsampling
top = dimensions[2]//h_subsampling
bottom = dimensions[3]//h_subsampling
for _ in range(left): src = core.std.StackHorizontal([core.std.CropRel(src, right = src.width - w_subsampling), src])
for _ in range(right): src = core.std.StackHorizontal([src, core.std.CropRel(src, left = src.width - w_subsampling)])
for _ in range(top): src = core.std.StackVertical([core.std.CropRel(src, bottom = src.height - h_subsampling), src])
for _ in range(bottom): src = core.std.StackVertical([src, core.std.CropRel(src, top = src.height - h_subsampling)])
return src
def MCLS(clip: vs.VideoNode, strength=1.0, sharp: vs.VideoNode=None, thsad=400, chroma=False, \
ss=None, repair=None, dmode=1, masked=True, blur_gaussian=False):
"""
Motion Compensated Limited Sharpen
Ported from its Avisynth counterpart: https://forum.doom9.org/showthread.php?p=1767949
Only supports Integer YUV and GRAY input.
"""
if clip.format.color_family not in [vs.YUV, vs.GRAY] or clip.format.sample_type != 0:
raise ValueError("MCLS: Only supports Integer YUV or GRAY input")
if ss is None:
ss = 1.25 if sharp is None else 1.0
if repair is None:
repair = True if sharp is None else False
HD = 0
if clip.width > 1280:
HD = 2
elif clip.width > 720:
HD = 1
pel = [2, 1, 1][HD]
truemotion = [True, False, False][HD]
blksize = [8, 16, 32][HD]
overlap = [4, 8, 8][HD]
isGray = False
if clip.format.num_planes == 1:
if chroma:
raise ValueError("MCLS: chroma=True cannot be used with GRAY input")
isGray=True
ss_width = round(clip.width*ss)
ss_height = round(clip.height*ss)
w_pad = 16 - (ss_width%16)
h_pad = 16 - (ss_height%16)
b_radius = round([3, 3, 4][HD] / 1.25 * ss)
if not chroma and not isGray:
u = core.std.ShufflePlanes(clip, 1, vs.GRAY)
v = core.std.ShufflePlanes(clip, 2, vs.GRAY)
clip = core.std.ShufflePlanes(clip, 0, vs.GRAY)
resized_source = clip if ss == 1.0 else core.resize.Spline36(clip, ss_width+w_pad, ss_height+h_pad)
if sharp is not None:
resized_sharp = sharp if ss == 1.0 else core.resize.Spline36(sharp, ss_width+w_pad, ss_height+h_pad)
sharp = core.std.MakeDiff(resized_sharp, resized_source)
else:
if blur_gaussian:
blurred = core.std.BoxBlur(resized_source, hradius=max(b_radius-2, 1), vradius=max(b_radius-2, 1))
for _ in range(2):
blurred = core.std.BoxBlur(blurred, hradius=max(b_radius-1,1), vradius=max(b_radius-1,1))
else:
blurred = core.std.BoxBlur(resized_source, hradius=b_radius, vradius=b_radius)
sharp = core.std.MakeDiff(resized_source, blurred)
pre = core.rgvs.RemoveGrain(resized_source, 3)
bitdepth = clip.format.bits_per_sample
if masked:
mask = core.std.ShufflePlanes(pre, 0, vs.GRAY)
mask = core.std.Expr([core.std.Maximum(mask), core.std.Minimum(mask)], ["x y - abs"])
mask = core.std.Binarize(mask, 10 << bitdepth - 8, planes=0)
mask = core.std.Deflate(mask, planes=0).rgvs.RemoveGrain(12)
sup0 = core.mv.Super(pre, pel=pel, sharp=2, chroma=chroma)
sup1 = core.mv.Super(sharp, pel=pel, sharp=2, chroma=chroma)
bv1 = core.mv.Analyse(sup0, isb=True, delta=1, chroma=chroma, blksize=blksize, truemotion=truemotion, overlap=overlap)
fv1 = core.mv.Analyse(sup0, isb=False, delta=1, chroma=chroma, blksize=blksize, truemotion=truemotion, overlap=overlap)
plane = 4 if chroma else 0
diff = core.mv.Degrain1(sharp, sup1, bv1, fv1, plane=plane, thsad=thsad)
sharpened_back = core.std.MergeDiff(resized_source, diff)
if repair:
repaired = core.rgvs.Repair(sharpened_back, resized_source, [1, 1] if chroma else 1)
repaired = core.std.MaskedMerge(repaired, sharpened_back, core.std.BlankClip(sharpened_back, format=vs.GRAY8, \
color = 76 << bitdepth - 8).fmtc.bitdepth(bits=bitdepth))
else:
repaired = sharpened_back
def scale(n, bits):
return n << bits - 8
lut = np.arange(scale(256, bitdepth))
lut = np.sqrt(np.sin(np.clip((lut - scale(16, bitdepth)) / scale(219, bitdepth), 0, 1) * np.pi)) * scale(256, bitdepth) * strength
lut = np.clip(lut, 0, scale(256, bitdepth) - 1)
lut = lut.astype(int).tolist()
if masked:
if dmode==1:
bias = core.std.ShufflePlanes(resized_source, 0, vs.GRAY)
bias = core.std.Lut(bias, lut=lut)
bias = core.std.Expr([bias, mask], "x y min")
else:
bias = mask
repaired = core.std.MaskedMerge(resized_source, repaired, bias, planes=[0, 1, 2] if chroma else 0) if dmode == 1 or masked else repaired
resized_back = core.resize.Spline36(repaired, clip.width, clip.height) if ss != 1.0 else repaired
if not chroma:
if not isGray:
return core.std.ShufflePlanes([resized_back, u, v], [0]*3, vs.YUV)
return resized_back
def credits_mask(clip: vs.VideoNode, binarize_thresh_1=46080, binarize_thresh_2=23040, expand=4, temporal=False, temporal_low=0.001,
temporal_high=0.008, temporal_radius=4, temporal_step=1) -> vs.VideoNode:
"""
Useful to detect credits on a >720p clip. This is a basic function that attempts to detect credits by growing a binarized clip
into a resampled difference clip. The temporal mode is experimental right now so it is suggested that you do not use it.
"""
clip = core.std.ShufflePlanes(clip, 0, vs.GRAY)
binarized = core.std.Binarize(clip, binarize_thresh_1)
binarized = core.std.Maximum(clip)
rescaled = core.resize.Spline36(clip, 1280, 720)
rescaled = core.resize.Spline36(rescaled, clip.width, clip.height)
rescaled_diff = core.std.MakeDiff(clip, rescaled)
rescaled_diff = core.fmtc.bitdepth(bits=8)
rescaled_diff = core.hist.Luma(rescaled_diff)
rescaled_diff = core.fmtc.bitdepth(bits=16)
for i in range(expand):
rescaled_diff = core.std.Maximum(rescaled_diff)
rescaled_diff = core.std.Binarize(rescaled_diff, binarize_thresh_2)
def temporal_check(n, f, clip):
high = clip
current_frame_average = f.props.PlaneStatsAverage
for i in range(1,temporal_radius+1, temporal_step):
if n+i < clip.num_frames:
forward_frame_average = clip.get_frame(n+i).props.PlaneStatsAverage
plane_diff_forward = forward_frame_average - current_frame_average
if temporal_high > plane_diff_forward > temporal_low and forward_frame_average > current_frame_average:
high = clip[i:clip.num_frames-1]
temporal_tresh = plane_diff_forward
if n-i > 0:
backward_frame_average = clip.get_frame(n-i).props.PlaneStatsAverage
plane_diff_backward = backward_frame_average - current_frame_average
if temporal_high > plane_diff_backward > temporal_low and backward_frame_average > current_frame_average:
high = clip[0:i]+clip
temporal_tresh = plane_diff_backward
return high
hysteresis = core.misc.Hysteresis(binarized, rescaled_diff)
if not temporal:
return hysteresis
hysteresis = core.std.PlaneStats(hysteresis)
return core.std.FrameEval(hysteresis, functools.partial(temporal_check, clip=hysteresis), prop_src=hysteresis)
def bilatinpaint(diff: vs.VideoNode, mask: vs.VideoNode, ref: vs.VideoNode, subspl=None, limit=12288, chroma=True) -> vs.VideoNode:
"""
TODO: Optimize pretty much the entire function (Will do it soon)
Ported from _08's Avisynth script: https://github.com/Zeght/Morefun/blob/master/Morefun.avsi#L987
This work a little differently but should have virtually little difference.
From _08's MoreFun repository: Function tries to interpolate data in msk area of diff by blurring it using ref clip as reference.
Most of processing is done on clips subsampled with subspl factor.
"""
if subspl is None:
if mask.width > 1280:
subspl = 3.0
else:
subspl = 2.0
w = mask.width
h = mask.height
ws = int(w/subspl/2)*2
hs = int(h/subspl/2)*2
mask_y = core.std.ShufflePlanes(mask, 0, vs.GRAY)
mask_y = core.resize.Bilinear(mask_y, ws, hs)
mask = mask_y
if chroma == True:
mask_uv = core.resize.Bilinear(mask_y, ws//2, hs//2, src_left=-0.25)
mask = core.std.ShufflePlanes([mask_y, mask_uv, mask_uv], [0,0,0], vs.YUV)
planes = [0,1,2]
else:
diff = core.std.ShufflePlanes(diff, 0, vs.GRAY)
ref = core.std.ShufflePlanes(ref, 0, vs.GRAY)
planes = [0]
diff_copy = diff
diff = core.resize.Bilinear(diff, ws, hs)
ref_copy = ref
ref = core.resize.Bilinear(ref, ws, hs)
binarized = core.std.Binarize(mask, 49152, v0=65535, v1=0, planes=planes)
blank = core.std.Expr([diff, binarized], "x 0 > y 0 > and x y min 0 ?")
def average(n, f, clip):
avg_blank_luma = f[0].props.PlaneStatsAverage * (1 << 16) - 1
avg_binarized_luma = f[1].props.PlaneStatsAverage * (1 << 11) - 182
if chroma:
avg_blank_u = f[2].props.PlaneStatsAverage * (1 << 16) - 1
avg_binarized_u = f[3].props.PlaneStatsAverage * (1 << 11) - 102
avg_blank_v = f[4].props.PlaneStatsAverage * (1 << 16) - 1
avg_binarized_v = f[5].props.PlaneStatsAverage * (1 << 11) - 102
return core.std.BlankClip(clip, color=[avg_blank_luma+avg_binarized_luma, avg_blank_u+avg_binarized_u, \
avg_blank_v+avg_binarized_v])
return core.std.BlankClip(clip, color=[avg_blank_luma+avg_binarized_luma])
plane_clips = []
for i in planes:
plane_clips.append(core.std.PlaneStats(core.std.ShufflePlanes(blank, i, vs.GRAY)))
plane_clips.append(core.std.PlaneStats(core.std.ShufflePlanes(binarized, i, vs.GRAY)))
blank = core.std.FrameEval(blank, functools.partial(average, clip=blank), plane_clips)
diff = core.std.MaskedMerge(diff, blank, mask, planes=planes)
diff = core.std.Expr(diff, "x 32768 "+ str(limit) +" + > 32768 "+ str(limit) +" + x ?") if (0 < limit < 32768) else diff
bilat = core.bilateral.Bilateral(diff, ref, sigmaS=min(hs, ws/5), sigmaR=0.10, planes=planes)
diff = core.std.MaskedMerge(diff, bilat, mask, planes=planes)
bilat = core.bilateral.Bilateral(diff, ref, sigmaS=min(hs, ws*2/13), sigmaR=0.02, planes=planes)
diff = core.std.MaskedMerge(diff, bilat, mask, planes=planes)
bilat = core.bilateral.Bilateral(diff, ref, sigmaS=ws/40, sigmaR=0.02, planes=planes)
diff = core.std.MaskedMerge(diff, bilat, mask, planes=planes)
diff = core.bilateral.Bilateral(diff, ref, sigmaS=max(2, ws/80), sigmaR=0.02, planes=planes)
diff = core.resize.Bilinear(diff, w, h)
diff = core.bilateral.Bilateral(diff, ref=ref_copy, sigmaS=2.0, sigmaR=0.02)
return core.std.AddDiff(diff_copy, diff) if not chroma else diff
def kaze_mask(clip):
"""
Ported from an Avisynth script made by ???. It generates a hardsub mask.
"""
clip = core.std.ShufflePlanes(clip, 0, vs.GRAY)
clip = core.rgvs.RemoveGrain(clip, 3)
low = core.std.Binarize(clip, 56320)
high = core.std.Binarize(clip, 12999, v0=65535, v1=0)
for i in range(3):
low = core.std.Maximum(low)
high = core.std.Maximum(high)
sub_mask = core.std.Expr([low, high], "x y min")
matrix = [1] * 25
sub_mask = core.std.Convolution(sub_mask, matrix, divisor=25)
sub_mask = core.std.Convolution(sub_mask, matrix, divisor=25)
sub_mask = core.std.Expr(sub_mask, "x 1000 - 8 *")
sub_mask = core.std.Convolution(sub_mask, matrix, divisor=25)
sub_mask = core.std.Convolution(sub_mask, matrix, divisor=25)
sub_mask = core.std.Expr(sub_mask, "x 3 *")
return sub_mask
def dehardsub(hardsubbed, ref, expand=0):
"""
This is plainly a wrapper around bilatinpaint and kazeMask and aims to "dehardsub" a video by merging the subbed parts of
the hardsubbed clip with the reference clip.
"""
blurred_ref = core.dfttest.DFTTest(ref, ftype=1, sigma=20)
mask = kaze_mask(hardsubbed)
for i in range(expand):
mask = core.std.Maximum(mask)
diff = core.std.MakeDiff(hardsubbed, blurred_ref)
diff = bilatinpaint(diff, mask, blurred_ref)
ref_shifted = core.std.MergeDiff(blurred_ref, diff)
return core.std.MaskedMerge(hardsubbed, ref_shifted, mask, first_plane=True)
@blaze077
Copy link
Author

blaze077 commented Apr 2, 2017

stux mein bruder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment