def wipe_row(clip: vs.VideoNode, secondary: vs.VideoNode = None, width: int = 1, height: int = 1, offset_x: int = 0, offset_y: int = 0, width2: Optional[int] = None, height2: Optional[int] = None, offset_x2: int = 0, offset_y2: Optional[int] = None, show_mask: bool = False) -> vs.VideoNode: funcname = "wipe_row" """ Simple function to wipe a row with a blank clip. You can also give it a different clip to replace a row with. if width2, height2, etc. are given, it will merge the two masks. :param secondary: vs.VideoNode: Appoint a different clip to replace wiped rows with """ secondary = secondary or core.std.BlankClip(clip) sqmask = kgf.squaremask(clip, width, height, offset_x, offset_y) if width2 and height2: sqmask2 = kgf.squaremask(clip, width2, height2, offset_x2, offset_y - 1 if offset_y2 is None else offset_y2) sqmask = core.std.Expr([sqmask, sqmask2], "x y +") if show_mask: return sqmask return core.std.MaskedMerge(clip, secondary, sqmask)
def wipe_row(clip: vs.VideoNode, secondary: Optional[vs.VideoNode] = None, width: int = 1, height: int = 1, offset_x: int = 0, offset_y: int = 0, width2: Optional[int] = None, height2: Optional[int] = None, offset_x2: Optional[int] = None, offset_y2: Optional[int] = None, show_mask: bool = False) -> vs.VideoNode: """ Simple function to wipe a row with a blank clip. You can also give it a different clip to replace a row with. if width2, height2, etc. are given, it will merge the two masks. Dependencies: kagefunc :param clip: Input clip :param secondary: Clip to replace wiped rows with (Default: None) :param width: Width of row (Default: 1) :param height: Height of row (Default: 1) :param offset_x: X-offset of row (Default: 0) :param offset_y: Y-offset of row (Default: 0) :param width2: Width of row 2 (Default: None) :param height2: Height of row 2 (Default: None) :param offset_x2: X-offset of row 2 (Default: None) :param offset_y2: Y-offset of row 2 (Default: None) :return: Clip with rows wiped """ try: import kagefunc as kgf except ModuleNotFoundError: raise ModuleNotFoundError("wipe_row: missing dependency 'kagefunc'") secondary = secondary or core.std.BlankClip(clip) sqmask = kgf.squaremask(clip, width, height, offset_x, offset_y) if width2 and height2: if offset_x2 is None: raise TypeError( "wipe_row: 'offset_x2 cannot be None if using two masks'") sqmask2 = kgf.squaremask( clip, width2, height2, offset_x2, offset_y - 1 if offset_y2 is None else offset_y2) sqmask = core.std.Expr([sqmask, sqmask2], "x y +") if show_mask: return sqmask return core.std.MaskedMerge(clip, secondary, sqmask)
def filter_squaremask(clip, filter, left=0, right=0, top=0, bottom=0): """entirely useless. apply filter only to area of specified square""" crop = core.std.Crop(clip, left, right, top, bottom) filtered = filter(crop) with_borders = filtered.std.AddBorders(left, right, top, bottom) mask = kf.squaremask(clip, clip.width - left - right, clip.height - top - bottom, left, top) return core.std.MaskedMerge(clip, with_borders, mask)
def test_squaremask(self): mask = kgf.squaremask(self.BLACK_SAMPLE_CLIP, 30, 30, 20, 0) self.assert_same_length(mask, self.BLACK_SAMPLE_CLIP) self.assert_same_bitdepth(mask, self.BLACK_SAMPLE_CLIP) self.assert_same_dimensions(mask, self.BLACK_SAMPLE_CLIP) mask.get_frame(0)
def do_filter(): """Vapoursynth filtering""" def _nneedi3_clamp(clip: vs.VideoNode, strength: int = 1) -> vs.VideoNode: bits = clip.format.bits_per_sample - 8 thr = strength * (1 >> bits) luma = get_y(clip) def _strong(clip: vs.VideoNode) -> vs.VideoNode: args = dict(alpha=0.25, beta=0.5, gamma=40, nrad=2, mdis=20, vcheck=3) clip = core.eedi3m.EEDI3(clip, 1, True, **args).std.Transpose() clip = core.eedi3m.EEDI3(clip, 1, True, **args).std.Transpose() return core.resize.Spline36(clip, luma.width, luma.height, src_left=-.5, src_top=-.5) def _weak(clip: vs.VideoNode) -> vs.VideoNode: args = dict(nsize=3, nns=2, qual=2) clip = core.znedi3.nnedi3(clip, 1, True, **args).std.Transpose() clip = core.znedi3.nnedi3(clip, 1, True, **args).std.Transpose() return core.resize.Spline36(clip, luma.width, luma.height, src_left=-.5, src_top=-.5) clip_aa = core.std.Expr( [_strong(luma), _weak(luma), luma], 'x z - y z - * 0 < y x y {0} + min y {0} - max ?'.format(thr)) return vdf.merge_chroma(clip_aa, clip) def _perform_endcard(path: str, ref: vs.VideoNode) -> vs.VideoNode: endcard = lvf.src(path).std.AssumeFPS(ref) endcard = core.std.CropRel(endcard, left=0, top=2, right=24, bottom=20) endcard = core.resize.Bicubic(endcard, ref.width, ref.height, vs.RGBS, dither_type='error_diffusion') endcard = iterate( endcard, partial(core.w2xc.Waifu2x, noise=3, scale=1, photo=True), 2) endcard = core.resize.Bicubic(endcard, format=vs.YUV444PS, matrix_s='709', dither_type='error_diffusion') return Tweak(endcard, sat=1.2, bright=-0.05, cont=1.2) src = JPBD.src_cut src = depth(src, 16) edstart = 31768 denoise_a = CoolDegrain(src, tr=2, thsad=48, blksize=8, overlap=4, plane=4) denoise_b = CoolDegrain(src, tr=3, thsad=96, blksize=8, overlap=4, plane=4) denoise = lvf.rfs(denoise_a, denoise_b, [(edstart + 1870, edstart + 1900)]) antialias = _nneedi3_clamp(denoise) predenoise = mClean(antialias, thSAD=200, chroma=False) detail_mask = lvf.denoise.detail_mask(predenoise, rad=2, radc=2, brz_a=3250, brz_b=1250) ret_mask = kgf.retinex_edgemask(predenoise).std.Binarize( 9250).std.Median().std.Inflate() line_mask = core.std.Expr([detail_mask, ret_mask], 'x y max') deband_a = core.neo_f3kdb.Deband(antialias, 17, 42, 42, 42, 12, 0, sample_mode=4, keep_tv_range=True) deband_a = core.std.MaskedMerge(deband_a, antialias, line_mask) deband_b = core.neo_f3kdb.Deband(deband_a, 18, 48, 48, 48, 0, 0, sample_mode=2, keep_tv_range=True) deband = lvf.rfs(deband_a, deband_b, [(edstart + 1870, edstart + 1900)]) deband_c = core.std.MaskedMerge(deband, deband_b, kgf.squaremask(src, 630, 1080, 1290, 0)) deband = lvf.rfs(deband, deband_c, [(7199, 7270)]) grain = kgf.adaptive_grain(deband, 0.25, luma_scaling=10) endcard = _perform_endcard( '[BDMV][200304][Magia Record][Vol.1]/Scans/endcard2_front_descreen.png', src) endcard_length = 120 final = core.std.Splice([grain, endcard * endcard_length], True) final = core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion') final = core.std.Limiter(final, 16, [235 << 2, 240 << 2]) return depth(final, 10), endcard_length