def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) edstart, edend = 14969, src.num_frames - 1 denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 48, 48) deband_a = dbs.f3kbilateral(out, 22, 96, 96) deband = lvf.rfs(deband, deband_a, [(edstart, edend)]) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain endcard = endcard_source( r'endcards\yande.re 611483 isekai_quartet iwamoto_tatsurou maid ram_(re_zero) rem_(re_zero) sketch tanya_degurechaff tate_no_yuusha_no_nariagari uniform youjo_senki.jpg', src) endcard_ar = endcard.width / endcard.height endcard_ev = bool(endcard.format.name == 'YUV420P8') if endcard_ar > 16 / 9: w, h = get_w(src.height, endcard_ar, only_even=endcard_ev), src.height elif endcard_ar < 16 / 9: w, h = src.width, get_h(src.width, endcard_ar, only_even=endcard_ev) else: w, h = src.width, src.height endcard = core.resize.Bicubic(endcard, w, h, vs.YUV444PS, range_in=1, range=0, dither_type='error_diffusion') endcard = mvf.BM3D(endcard, 0.5) endcard = core.std.CropAbs(endcard, 1920, 1080, top=round((endcard.height - 1080) / 2 / 2) * 2) final = core.std.Splice([out, endcard * (17263 - src.num_frames)], mismatch=True) return core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion')
def inverse_scale(source: vs.VideoNode, width=None, height=720, kernel='bilinear', kerneluv='blackman', taps=4, a1=1/3, a2=1/3, invks=True, mask_detail=False, masking_areas=None, mask_highpass=0.3, denoise=False, bm3d_sigma=1, knl_strength=0.4, use_gpu=True) -> vs.VideoNode: """ source = input clip width, height, kernel, taps, a1, a2 are parameters for resizing mask_detail, masking_areas, mask_highpass are parameters for masking; mask_detail = False to disable masking_areas takes frame tuples to define areas which will be masked (e.g. opening and ending) masking_areas = [[1000, 2500], [30000, 32000]]. Start and end frame are inclusive. mask_highpass is used to remove small artifacts from the mask. Value must be normalized. denoise, bm3d_sigma, knl_strength, and use_gpu are parameters for denoising; denoise = False to disable use_gpu = True -> chroma will be denoised with KNLMeansCL (faster) """ if source.format.bits_per_sample != 32: source = core.fmtc.bitdepth(source, bits=32) if width is None: width = getw(height, ar=source.width/source.height) planes = clip_to_plane_array(source) if denoise and use_gpu: planes[1], planes[2] = [core.knlm.KNLMeansCL(plane, a=2, h=knl_strength, d=3, device_type='gpu', device_id=0) for plane in planes[1:]] planes = inverse_scale_clip_array(planes, width, height, kernel, kerneluv, taps, a1, a2, invks) planes[0] = mvf.BM3D(planes[0], sigma=bm3d_sigma, radius1=1) else: planes = inverse_scale_clip_array(planes, width, height, kernel, kerneluv, taps, a1, a2, invks) scaled = plane_array_to_clip(planes) if denoise and not use_gpu: scaled = mvf.BM3D(scaled, radius1=1, sigma=bm3d_sigma) if mask_detail: mask = generate_mask(source, width, height, kernel, taps, a1, a2, mask_highpass) if masking_areas is None: scaled = apply_mask(source, scaled, mask) else: scaled = apply_mask_to_area(source, scaled, mask, masking_areas) return scaled
def _perform_filtering_ending(clip: vs.VideoNode, adapt_mask: vs.VideoNode) -> vs.VideoNode: luma = get_y(clip) denoise_a = mvf.BM3D(luma, 2.25, 1) denoise_b = mvf.BM3D(luma, 1.25, 1) denoise = core.std.MaskedMerge(denoise_a, denoise_b, adapt_mask) grain = core.grain.Add(denoise, 0.3, constant=True) return core.std.MaskedMerge(denoise, grain, adapt_mask)
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 36, 36) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain endcard = endcard_source(r'endcards\yande.re 602496 isekai_quartet minami_seira overlord raphtalia re_zero_kara_hajimeru_isekai_seikatsu tagme tate_no_yuusha_no_nariagari youjo_senki.jpg', src) endcard = core.resize.Bicubic(endcard, get_w(src.height, endcard.width/endcard.height, only_even=bool(endcard.format.name == 'YUV420P8')), src.height, range_in=1, range=0, dither_type='error_diffusion') final = core.std.Splice([out, endcard * 223], mismatch=True) return core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion')
def hybrid_denoise(clip: vs.VideoNode, knlm_h: float = 0.5, sigma: float = 2, knlm_args: Optional[Dict[str, Any]] = None, bm3d_args: Optional[Dict[str, Any]] = None) -> vs.VideoNode: """Denoise luma with BM3D and chroma with knlmeansCL Args: clip (vs.VideoNode): Source clip. knlm_h (float, optional): h parameter in knlm.KNLMeansCL. Defaults to 0.5. sigma (float, optional): Sigma parameter in mvf.BM3D. Defaults to 2. knlm_args (Optional[Dict[str, Any]], optional): Optional extra arguments for knlm.KNLMeansCL. Defaults to None. bm3d_args (Optional[Dict[str, Any]], optional): Optional extra arguments for mvf.BM3D. Defaults to None. Returns: vs.VideoNode: [description] """ knargs = dict(a=2, d=3, device_type='gpu', device_id=0, channels='UV') if knlm_args is not None: knargs.update(knlm_args) b3args = dict(radius1=1, profile1='fast') if bm3d_args is not None: b3args.update(bm3d_args) luma = get_y(clip) luma = mvf.BM3D(luma, sigma, **b3args) chroma = core.knlm.KNLMeansCL(clip, h=knlm_h, **knargs) return vdf.merge_chroma(luma, chroma)
def do_filter(): """Vapoursynth filtering""" src = SRC_CUT src = depth(src, 16) denoise = core.knlm.KNLMeansCL(src, a=2, h=0.8, d=3, device_type='gpu', channels='UV') denoise_mask = core.adg.Mask(src.std.PlaneStats(), 2).std.Invert() denoise = core.std.MaskedMerge(denoise, mvf.BM3D(denoise, 2), denoise_mask) antialias = lvf.sraa(denoise, 1.75, 6, sharp_downscale=True) antialias_mask = core.std.Prewitt(get_y(denoise)).std.Maximum() antialias = core.std.MaskedMerge(denoise, antialias, antialias_mask) preden = core.knlm.KNLMeansCL(antialias, a=2, h=1.5, d=0, device_type='gpu', channels='Y') deband_mask = lvf.denoise.detail_mask(preden, brz_a=2500, brz_b=1000) deband = dbs.f3kpf(preden, 17, 36, 36) diff = core.std.MakeDiff(antialias, preden) deband = core.std.MergeDiff(deband, diff) deband = core.std.MaskedMerge(deband, antialias, deband_mask) final = depth(deband, 10) return final
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 16) out = src ref = hvf.SMDegrain(out, thSAD=300) denoise = mvf.BM3D(out, [1.5, 1.25], radius1=1, ref=ref) out = denoise crop = core.std.Crop(out, left=12) crop = awf.bbmod(crop, left=2, thresh=20 << 8) resize = core.resize.Bicubic(crop, 1920) out = lvf.rfs(out, resize, [(78, 89)]) y = get_y(out) lineart = gf.EdgeDetect(y, 'scharr').morpho.Dilate(2, 2).std.Inflate() fkrescale = fake_rescale( y, 882, 0, 1, deringer=lambda x: gf.MaskedDHA(x, rx=1.85, ry=1.85, darkstr=0.25, brightstr=1.0, maskpull=100, maskpush=200), antialiser=lambda c: lvf.sraa(c, 2, 13, downscaler=core.resize.Bicubic) ) merged = core.std.MaskedMerge(y, fkrescale, lineart) out = vdf.merge_chroma(merged, out) dering = hvf.EdgeCleaner(out, 17, smode=1, hot=True) out = dering out = lvf.rfs( out, denoise, [(0, 11), (38, 77), (115, 133), (316, 395), (441, 460), (606, 779), (825, 844), (990, 1127)] ) detail_mask = lvf.mask.detail_mask(out, brz_a=2250, brz_b=1000) deband = vdf.dumb3kdb(out, 15, threshold=17, grain=(24, 0)) deband = core.std.MaskedMerge(deband, out, detail_mask) out = deband grain = adptvgrnMod(out, 0.3, static=True, grain_chroma=False, hi=[128, 240], seed=333) out = grain decz = vdf.decsiz(out, min_in=128 << 8, max_in=200 << 8) out = decz return depth(out, 10).std.Limiter(16 << 2, [235 << 2, 240 << 2], [0, 1, 2])
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 36, 36) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain return depth(out, 10)
def do_filter(): """Vapoursynth filtering""" src = SRC_CLIP src = depth(src, 16) denoise = core.knlm.KNLMeansCL(src, a=2, h=0.8, d=3, device_type='gpu', channels='UV') denoise_mask = core.adg.Mask(src.std.PlaneStats(), 6).std.Invert() denoise = core.std.MaskedMerge(denoise, mvf.BM3D(denoise, 1.25), denoise_mask) downscaler = lambda c, w, h: core.fmtc.resample( c, w, h, kernel='gauss', invks=True, invkstaps=1, taps=1, a1=32) antialias = lvf.sraa(denoise, 1.75, 6, downscaler=downscaler) antialias_mask = core.std.Prewitt(get_y(denoise)).std.Maximum() antialias = core.std.MaskedMerge(denoise, antialias, antialias_mask) preden = core.knlm.KNLMeansCL(antialias, a=2, h=1.5, d=0, device_type='gpu', channels='Y') deband_mask = lvf.denoise.detail_mask(preden, brz_a=2500, brz_b=1000) deband = dbs.f3kpf(preden, 17, 36, 36) diff = core.std.MakeDiff(antialias, preden) deband = core.std.MergeDiff(deband, diff) deband = core.std.MaskedMerge(deband, antialias, deband_mask) final = depth(deband, 10) return final
def ED(ed_in: vs.VideoNode) -> vs.VideoNode: src = ed_in # Rescale using a modified version of Zastin's dogahomo() rescale = rvs.questionable_rescale(vsutil.depth(src, 16), 810, b=1/3, c=1/3, mask_thresh=0.05) # Detail- and linemasking for denoising det_mask = lvf.mask.detail_mask(rescale, brz_a=0.25, brz_b=0.15) denoise_ya = core.knlm.KNLMeansCL(rescale, d=2, a=3, s=3, h=1.2, channels="Y") denoise_ca = core.knlm.KNLMeansCL(rescale, d=2, a=2, s=3, h=1.0, channels="UV") denoise_a = core.std.ShufflePlanes([denoise_ya,denoise_ca,denoise_ca], [0,1,2], colorfamily=vs.YUV) denoise_b = mvf.BM3D(rescale, sigma=[1.9], ref=denoise_a, profile1="fast", radius1=3) # BM3D left some gunk in chroma, most noticeably around hard contrast edges denoise = core.std.ShufflePlanes([denoise_b,denoise_a,denoise_a], [0,1,2], colorfamily=vs.YUV) denoise = core.std.MaskedMerge(denoise, rescale, det_mask) # Thanks for handling the effort of AA for me, Light aa = lvf.aa.nneedi3_clamp(denoise, strength=1.25, mthr=0.25) # Dehaloing it dehalom = rvs.dehalo_mask(aa, iter_out=3) dehalo_a = haf.DeHalo_alpha(aa, darkstr=0.9, brightstr=1.1) dehalo_a = vsutil.depth(dehalo_a, 16) dehalo = core.std.MaskedMerge(aa, dehalo_a, dehalom) # Generate a new detail mask and deband it, putting back fine detail the way it was det_mask = lvf.mask.detail_mask(dehalo, rad=2, radc=1, brz_a=0.05, brz_b=0.09) y,u,v = vsutil.split(dehalo) deband_a = vsutil.join([pdb(y, threshold=3.0, grain=6.5), pdb(u, threshold=3.0, grain=2.0), pdb(v, threshold=3.0, grain=2.0)]) deband = core.std.MaskedMerge(deband_a, dehalo, det_mask) # Finish up and output grain = kgf.adaptive_grain(deband, strength=0.65, luma_scaling=5) out = vsutil.depth(grain, 10) return out
def do_filter() -> vs.VideoNode: """Vapoursynth filtering""" src = JPBD.src_cut out = src luma = get_y(out) rows = [ core.std.CropAbs(luma, out.width, 1, top=out.height - 1), core.std.CropAbs(luma, out.width, 1, top=out.height - 2) ] diff = core.std.Expr(rows, 'x y - abs').std.PlaneStats() row_fix = vdf.merge_chroma( luma.fb.FillBorders(bottom=1, mode="fillmargins"), out.fb.FillBorders(bottom=2, mode="fillmargins")) fixrow = core.std.FrameEval(out, partial(_select_row, clip=out, row_fix=row_fix), prop_src=diff) out = fixrow fixedge_a = awf.bbmod(out, 1, 1, 1, 1, 20, blur=700, u=False, v=False) fixedge = out fixedge = lvf.rfs(fixedge, fixedge_a, [(EDSTART + 309, EDEND)]) out = fixedge out = depth(out, 16) dehalo = gf.MaskedDHA(out, rx=1.4, ry=1.4, darkstr=0.02, brightstr=1) dehalo = lvf.rfs(out, dehalo, [(EDEND + 1, src.num_frames - 1)]) out = dehalo resize = core.std.Crop(out, right=12, bottom=8).resize.Bicubic(1920, 1080) resize = lvf.rfs(out, resize, [(27005, 27076)]) out = resize # Denoising only the chroma pre = hvf.SMDegrain(out, tr=2, thSADC=300, plane=3) planes = split(out) planes[1], planes[2] = [ mvf.BM3D(planes[i], 1.25, radius2=2, pre=plane(pre, i)) for i in range(1, 3) ] out = join(planes) preden = core.dfttest.DFTTest(out, sbsize=16, sosize=12, tbsize=1) detail_mask = lvf.mask.detail_mask(preden, brz_a=2500, brz_b=1500) deband = vdf.dumb3kdb(preden, 16, threshold=[17, 17], grain=[24, 0]) deband = core.std.MergeDiff(deband, out.std.MakeDiff(preden)) deband = core.std.MaskedMerge(deband, out, detail_mask) out = deband decz = vdf.decsiz(out, min_in=128 << 8, max_in=192 << 8) out = decz return depth(out, 10).std.Limiter(16 << 2, [235 << 2, 240 << 2], [0, 1, 2])
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 16) out = src + src[-1] denoise = mvf.BM3D(out, [2.5, 1.5], radius1=1) diff = core.std.MakeDiff(out, denoise) out = denoise luma = get_y(out) dehalo = gf.MaskedDHA(luma, rx=2.5, ry=2.5, darkstr=0.15, brightstr=1.2, maskpull=48, maskpush=140) out = dehalo dering = gf.HQDeringmod(out, sharp=3, drrep=24, thr=24, darkthr=0) out = dering antialias_mask = gf.EdgeDetect(out, 'FDOG') antialias = lvf.sraa(out, 1.5, 13, gamma=100, downscaler=core.resize.Spline64) out = core.std.MaskedMerge(out, antialias, antialias_mask) out = vdf.merge_chroma(out, denoise) warp = xvs.WarpFixChromaBlend(out, 64, depth=8) out = warp deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1500).std.Median() deband = dbs.f3kpf(out, 17, 36, 36) deband_b = dbs.f3kpf(out, 17, 56, 48) deband = lvf.rfs(deband, deband_b, [(23708, 24371)]) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain_original = core.std.MergeDiff(out, diff) grain_new = core.grain.Add(out, 0.15, 0, constant=True) grain_mask = core.adg.Mask(out.std.PlaneStats(), 30).std.Expr(f'x x {96<<8} - 0.25 * +') grain = core.std.MaskedMerge(grain_new, grain_original, grain_mask) out = grain ending = lvf.rfs(out, src, [(31241, src.num_frames - 1)]) out = ending return depth(out, 10)
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) edstart, edend = 14313, 16383 denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 48, 48) deband_a = dbs.f3kbilateral(out, 22, 96, 96) deband = lvf.rfs(deband, deband_a, [(edstart, edend)]) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain endcard = endcard_source( r'endcards\yande.re 607473 cheerleader isekai_quartet pointy_ears ram_(re_zero) rem_(re_zero) satou_kazuma seifuku tagme tanya_degurechaff trap youjo_senki.jpg', src) endcard_ar = endcard.width / endcard.height endcard_ev = bool(endcard.format.name == 'YUV420P8') if endcard_ar > 16 / 9: w, h = get_w(src.height, endcard_ar, only_even=endcard_ev), src.height elif endcard_ar < 16 / 9: w, h = src.width, get_h(src.width, endcard_ar, only_even=endcard_ev) else: w, h = src.width, src.height endcard = core.resize.Bicubic(endcard, w, h, range_in=1, range=0, dither_type='error_diffusion') endcard = lvf.sraa(depth(endcard, 16), 1.5, 7) final = core.std.Splice([out, endcard * (17263 - src.num_frames)], mismatch=True) return core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion')
def inverse_scale(source: vs.VideoNode, width: int = None, height: int = 0, kernel: str = 'bilinear', taps: int = 4, b: float = 1 / 3, c: float = 1 / 3, mask_detail: bool = False, descale_mask_zones: str = '', denoise: bool = False, bm3d_sigma: float = 1, knl_strength: float = 0.4, use_gpu: bool = True) \ -> vs.VideoNode: """ Use descale to reverse the scaling on a given input clip. width, height, kernel, taps, a1, a2 are parameters for resizing. descale_mask_zones can be used to only mask certain zones to improve performance; uses rfs syntax. denoise, bm3d_sigma, knl_strength, use_gpu are parameters for denoising; denoise = False to disable use_gpu = True -> chroma will be denoised with KNLMeansCL (faster) """ if not height: raise ValueError( 'inverse_scale: you need to specify a value for the output height') only_luma = source.format.num_planes == 1 if get_depth(source) != 32: source = source.resize.Point(format=source.format.replace( bits_per_sample=32, sample_type=vs.FLOAT)) width = fallback(width, getw(height, source.width / source.height)) # if we denoise luma and chroma separately, do the chroma here while it’s still 540p if denoise and use_gpu and not only_luma: source = core.knlm.KNLMeansCL(source, a=2, h=knl_strength, d=3, device_type='gpu', device_id=0, channels='UV') planes = split(source) planes[0] = _descale_luma(planes[0], width, height, kernel, taps, b, c) if only_luma: return planes[0] planes = _descale_chroma(planes, width, height) if mask_detail: upscaled = fvf.Resize(planes[0], source.width, source.height, kernel=kernel, taps=taps, a1=b, a2=c) planes[0] = mask_descale(get_y(source), planes[0], upscaled, zones=descale_mask_zones) scaled = join(planes) return mvf.BM3D( scaled, radius1=1, sigma=[bm3d_sigma, 0] if use_gpu else bm3d_sigma) if denoise else scaled
def YAEM(clip, denoise=False, threshold=140): """ 256 > threshold > 0 the whole function is just moronic and ridicilously slow for a halo mask. use findehalo or whatever instead""" y = kf.getY(clip) max_ = core.std.Maximum(y) mask = core.std.MakeDiff(max_, y) denoise = mf.BM3D(mask, sigma=10) if denoise else False conv = core.std.Convolution(denoise or mask, [1] * 9) min_ = core.std.Minimum(mask) mask = core.std.Expr([mask, conv, min_], "x y < z x ?").std.Binarize( get_max(clip) * threshold / 255) infl = mask.std.Maximum() return core.std.Expr([mask, infl], "y x -")
def hybriddenoise(src, knl=0.5, sigma=2, radius1=1): """ denoise luma with BM3D (CPU-based) and chroma with KNLMeansCL (GPU-based) sigma = luma denoise strength knl = chroma denoise strength. The algorithm is different, so this value is different from sigma BM3D's sigma default is 5, KNL's is 1.2, to give you an idea of the order of magnitude radius1 = temporal radius of luma denoising, 0 for purely spatial denoising """ planes = clip_to_plane_array(src) planes[0] = mvf.BM3D(planes[0], radius1=radius1, sigma=sigma) planes[1], planes[2] = [core.knlm.KNLMeansCL(plane, a=2, h=knl, d=3, device_type='gpu', device_id=0) for plane in planes[1:]] return core.std.ShufflePlanes(clips=planes, planes=[0, 0, 0], colorfamily=vs.YUV)
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) edstart, edend = 14969, src.num_frames-1 denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 48, 48) deband_a = dbs.f3kbilateral(out, 22, 96, 96) deband = lvf.rfs(deband, deband_a, [(edstart, edend)]) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain endcard = endcard_source(r'endcards\yande.re 605709 albedo_(overlord) armor cleavage gun horns isekai_quartet maid overlord rem_(re_zero) tagme thighhighs uniform weapon youjo_senki.jpg', src) endcard_ar = endcard.width/endcard.height endcard_ev = bool(endcard.format.name == 'YUV420P8') endcard = depth(endcard, 16) endcard = gf.MaskedDHA(endcard, rx=2.0, ry=2.0, darkstr=0.3, brightstr=1.0, maskpull=48, maskpush=140) if endcard_ar > 16/9: w, h = get_w(src.height, endcard_ar, only_even=endcard_ev), src.height elif endcard_ar < 16/9: w, h = src.width, get_h(src.width, endcard_ar, only_even=endcard_ev) else: w, h = src.width, src.height endcard = core.resize.Bicubic(endcard, w, h, range_in=1, range=0, dither_type='error_diffusion') endcard = lvf.sraa(endcard, 1.45, 7) final = core.std.Splice([out, endcard * (17263 - src.num_frames)], mismatch=True) return core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion')
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 48, 48) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain endcard = endcard_source( r'endcards\yande.re 622847 animal_ears armor chibi dress emilia_(re_zero) firo horns isekai_quartet neko overlord pack_(re_zero) raphtalia uniform wallpaper youjo_senki.jpg', src) endcard_ar = endcard.width / endcard.height endcard_ev = bool(endcard.format.name == 'YUV420P8') if endcard_ar > 16 / 9: w, h = get_w(src.height, endcard_ar, only_even=endcard_ev), src.height elif endcard_ar < 16 / 9: w, h = src.width, get_h(src.width, endcard_ar, only_even=endcard_ev) else: w, h = src.width, src.height endcard = core.resize.Bicubic(endcard, w, h, range_in=1, range=0, dither_type='error_diffusion') final = core.std.Splice([out, endcard * (17263 - src.num_frames)], mismatch=True) return core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion')
def do_filter() -> vs.VideoNode: """Vapoursynth filtering""" src = JPBD.src_cut out = src luma = get_y(out) rows = [ core.std.CropAbs(luma, out.width, 1, top=out.height - 1), core.std.CropAbs(luma, out.width, 1, top=out.height - 2) ] diff = core.std.Expr(rows, 'x y - abs').std.PlaneStats() row_fix = vdf.merge_chroma( luma.fb.FillBorders(bottom=1, mode="fillmargins"), out.fb.FillBorders(bottom=2, mode="fillmargins")) fixrow = core.std.FrameEval(out, partial(_select_row, clip=out, row_fix=row_fix), prop_src=diff) out = fixrow out = depth(out, 16) # Denoising only the chroma pre = hvf.SMDegrain(out, tr=2, thSADC=300, plane=3) planes = split(out) planes[1], planes[2] = [ mvf.BM3D(planes[i], 1.25, radius2=2, pre=plane(pre, i)) for i in range(1, 3) ] out = join(planes) preden = core.dfttest.DFTTest(out, sbsize=16, sosize=12, tbsize=1) detail_mask = lvf.mask.detail_mask(preden, brz_a=2500, brz_b=1500) deband = vdf.dumb3kdb(preden, 16, threshold=[17, 17], grain=[24, 0]) deband = core.std.MergeDiff(deband, out.std.MakeDiff(preden)) deband = core.std.MaskedMerge(deband, out, detail_mask) out = deband decz = vdf.decsiz(out, min_in=128 << 8, max_in=192 << 8) out = decz ref = depth(src, 16) credit = out credit = lvf.rfs(out, ref, CREDITS) out = credit return depth(out, 10).std.Limiter(16 << 2, [235 << 2, 240 << 2], [0, 1, 2])
def quick_denoise(clip: vs.VideoNode, ref: vs.VideoNode = None, cmode: str = 'knlm', sigma: float = 2, **kwargs) -> vs.VideoNode: funcname = "quick_denoise" """ A rewrite of my old 'quick_denoise'. I still hate it, but whatever. This will probably be removed in a future commit. This wrapper is used to denoise both the luma and chroma using various denoisers of your choosing. If you wish to use just one denoiser, you're probably better off using that specific filter rather than this wrapper. BM3D is used for denoising the luma. Special thanks to kageru for helping me out with some ideas and pointers. :param sigma: Denoising strength for BM3D :param cmode: Chroma denoising modes: 1 - Use knlmeans for denoising the chroma 2 - Use tnlmeans for denoising the chroma 3 - Use dfttest for denoising the chroma (requires setting 'sbsize' in kwargs) 4 - Use SMDegrain for denoising the chroma :param ref: vs.VideoNode: Optional reference clip to replace BM3D's basic estimate """ y, u, v = kgf.split(clip) cmode = cmode.lower() if cmode in [1, 'knlm', 'knlmeanscl']: den_u = u.knlm.KNLMeansCL(d=3, a=2, **kwargs) den_v = v.knlm.KNLMeansCL(d=3, a=2, **kwargs) elif cmode in [2, 'tnlm', 'tnlmeans']: den_u = u.tnlm.TNLMeans(ax=2, ay=2, az=2, **kwargs) den_v = v.tnlm.TNLMeans(ax=2, ay=2, az=2, **kwargs) elif cmode in [3, 'dft', 'dfttest']: if 'sbsize' in kwargs: den_u = u.dfttest.DFTTest(sosize=kwargs['sbsize'] * 0.75, **kwargs) den_v = v.dfttest.DFTTest(sosize=kwargs['sbsize'] * 0.75, **kwargs) else: return error(funcname, "'sbsize' not specified") elif cmode in [4, 'smd', 'smdegrain']: den_u = haf.SMDegrain(u, prefilter=3, **kwargs) den_v = haf.SMDegrain(v, prefilter=3, **kwargs) else: return error(funcname, 'unknown cmode') den_y = mvf.BM3D(y, sigma=sigma, psample=0, radius1=1, ref=ref) return core.std.ShufflePlanes([den_y, den_u, den_v], 0, vs.YUV)
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) edstart, edend = 14969, src.num_frames-1 denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 48, 48) deband_a = dbs.f3kbilateral(out, 22, 96, 96) deband = lvf.rfs(deband, deband_a, [(edstart, edend)]) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain endcard = endcard_source(r'endcards\yande.re 617224 albedo crossover emilia_(re_zero) horns isekai_quartet megumin neko overlord pack_(re_zero) pointy_ears tagme uniform witch youjo_senki.jpg', src) endcard_ar = endcard.width/endcard.height endcard_ev = bool(endcard.format.name == 'YUV420P8') endcard = depth(endcard, 16) endcard = dbs.f3kpf(endcard, 22, 48, 48).grain.Add(50, constant=True) if endcard_ar > 16/9: w, h = get_w(src.height, endcard_ar, only_even=endcard_ev), src.height elif endcard_ar < 16/9: w, h = src.width, get_h(src.width, endcard_ar, only_even=endcard_ev) else: w, h = src.width, src.height endcard = core.resize.Bicubic(endcard, w, h, range_in=1, range=0, dither_type='error_diffusion') final = core.std.Splice([out, endcard * (17263 - src.num_frames)], mismatch=True) return core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion')
def hybrid_denoise(clip: vs.VideoNode, knlm_h: float = 0.5, sigma: float = 2, knlm_args: Optional[Dict[str, Any]] = None, bm3d_args: Optional[Dict[str, Any]] = None)-> vs.VideoNode: knargs = dict(a=2, d=3, device_type='gpu', device_id=0, channels='UV') if knlm_args is not None: knargs.update(knlm_args) b3args = dict(radius1=1, profile1='fast') if bm3d_args is not None: b3args.update(bm3d_args) luma = get_y(clip) luma = mvf.BM3D(luma, sigma, **b3args) chroma = core.knlm.KNLMeansCL(clip, h=knlm_h, **knargs) return vdf.merge_chroma(luma, chroma)
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 48, 48) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain endcard = endcard_source(r'endcards\yande.re 609548 albedo_(overlord) cleavage crossover dress horns isekai_quartet no_bra nopan ookuma_nekosuke overlord petelgeuse_romanee-conti valentine wings.jpg', src) endcard_ar = endcard.width/endcard.height endcard_ev = bool(endcard.format.name == 'YUV420P8') if endcard_ar > 16/9: w, h = get_w(src.height, endcard_ar, only_even=endcard_ev), src.height elif endcard_ar < 16/9: w, h = src.width, get_h(src.width, endcard_ar, only_even=endcard_ev) else: w, h = src.width, src.height endcard = core.resize.Bicubic(endcard, w, h, range_in=1, range=0, dither_type='error_diffusion') endcard = core.std.CropAbs(endcard, 1920, 1080, top=round((endcard.height - 1080)/2 / 2) * 2) final = core.std.Splice([out, endcard * (17263 - src.num_frames)], mismatch=True) return core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion')
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) edstart, edend = 14969, src.num_frames - 1 denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise antialias = lvf.sraa(out, 2, 13, downscaler=core.resize.Bicubic, gamma=500, nrad=2, mdis=16) out = antialias deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 54, 48) deband_a = dbs.f3kbilateral(out, 22, 96, 96) deband = lvf.rfs(deband, deband_a, [(edstart, edend)]) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain endcard = endcard_source( r'endcards\yande.re 603981 ass bikini breast_hold crossover horns isekai_quartet open_shirt overlord rem_(re_zero) swimsuits thong tsuji_santa weapon wings youjo_senki.jpg', src) endcard = core.resize.Bicubic( endcard, get_w(src.height, endcard.width / endcard.height, only_even=bool(endcard.format.name == 'YUV420P8')), src.height, range_in=1, range=0, dither_type='error_diffusion') final = core.std.Splice([out, endcard * 223], mismatch=True) return core.resize.Bicubic(final, format=vs.YUV420P10, dither_type='error_diffusion')
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 32) denoise = mvf.BM3D(src, 1.1, radius1=1, depth=16) out = denoise deband_mask = lvf.denoise.detail_mask(out, brz_a=2250, brz_b=1600).std.Median() deband = dbs.f3kbilateral(out, 17, 48, 48) deband_a = dbs.f3kbilateral(out, 22, 96, 96) deband = lvf.rfs(deband, deband_a, [(112, 2182)]) deband = core.std.MaskedMerge(deband, out, deband_mask) out = deband grain = core.grain.Add(out, 0.3, constant=True) out = grain return depth(out, 10)
def hybriddenoise(src, knl=0.5, sigma=2, radius1=1): """ denoise luma with BM3D (CPU-based) and chroma with KNLMeansCL (GPU-based) sigma = luma denoise strength knl = chroma denoise strength. The algorithm is different, so this value is different from sigma BM3D's sigma default is 5, KNL's is 1.2, to give you an idea of the order of magnitude radius1 = temporal radius of luma denoising, 0 for purely spatial denoising """ y = get_y(src) y = mvf.BM3D(y, radius1=radius1, sigma=sigma) denoised = core.knlm.KNLMeansCL(src, a=2, h=knl, d=3, device_type='gpu', device_id=0, channels='UV') return core.std.ShufflePlanes([y, denoised], planes=[0, 1, 2], colorfamily=vs.YUV)
def quick_denoise(clip: vs.VideoNode, mode='knlm', bm3d=True, sigma=3, h=1.0, refine_motion=True, sbsize=16, resample=True): """ Wrapper for generic denoising. Denoising is done by BM3D with a given denoisers being used for ref. Returns the denoised clip used as ref if BM3D=False. Mode 1 = KNLMeansCL Mode 2 = SMDegrain Mode 3 = DFTTest Will be removed eventuallyTM. """ if resample: if clip.format.bits_per_sample != 16: clip = fvf.Depth(clip, 16) clipY = core.std.ShufflePlanes(clip, 0, vs.GRAY) if mode in [1, 'knlm']: denoiseY = clipY.knlm.KNLMeansCL(d=3, a=2, h=h) elif mode in [2, 'SMD', 'SMDegrain']: denoiseY = haf.SMDegrain(clipY, prefilter=3, RefineMotion=refine_motion) elif mode in [3, 'DFT', 'dfttest']: denoiseY = clipY.dfttest.DFTTest(sigma=4.0, tbsize=1, sbsize=sbsize, sosize=sbsize*0.75) else: raise ValueError('denoise: unknown mode') if bm3d: denoisedY = mvf.BM3D(clipY, sigma=sigma, psample=0, radius1=1, ref=denoiseY) elif bm3d is False: denoisedY = denoiseY if clip.format.color_family is vs.GRAY: return denoisedY else: srcU = clip.std.ShufflePlanes(1, vs.GRAY) srcV = clip.std.ShufflePlanes(2, vs.GRAY) merged = core.std.ShufflePlanes([denoisedY, srcU, srcV], 0, vs.YUV) return merged
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 16) out = src ref = hvf.SMDegrain(out, thSAD=300) denoise = mvf.BM3D(out, [1.5, 1.25], radius1=1, ref=ref) out = denoise dering = hvf.EdgeCleaner(out, 17, smode=1, hot=True) out = dering detail_mask = lvf.mask.detail_mask(out, brz_a=2250, brz_b=1000) deband = vdf.dumb3kdb(out, 15, threshold=17, grain=(24, 0)) deband = core.std.MaskedMerge(deband, out, detail_mask) out = deband grain = adptvgrnMod(out, 0.3, static=True, grain_chroma=False, hi=[128, 240], seed=333) out = grain decz = vdf.decsiz(out, min_in=128 << 8, max_in=200 << 8) out = decz return depth(out, 10).std.Limiter(16 << 2, [235 << 2, 240 << 2], [0, 1, 2])
def do_filter(): """Vapoursynth filtering""" src = JPBD.src_cut src = depth(src, 16) out = src h = 900 w = get_w(h) # Remove the grain ref = hvf.SMDegrain(out, tr=1, thSAD=300, plane=4) degrain = mvf.BM3D(out, sigma=[1.5, 1], radius1=1, ref=ref) degrain = insert_clip(degrain, smhdegrain(out[5539:5670], 2, 280), 5539) degrain = insert_clip(degrain, smhdegrain(out[5933:5992], 2, 200), 5933) degrain = insert_clip(degrain, smhdegrain(out[6115:6180], 2, 200), 6115) degrain = insert_clip(degrain, smhdegrain(out[6180:6281], 2, 200), 6180) degrain = insert_clip(degrain, smhdegrain(out[39303:39482], 2, 280), 39303) degrain = insert_clip(degrain, smhdegrain(out[40391:40837], 2, 200), 40391) degrain = insert_clip(degrain, smhdegrain(out[40908:41087], 2, 280), 40908) degrain = insert_clip(degrain, smhdegrain(out[41671:41791], 2, 280), 41671) degrain = insert_clip(degrain, smhdegrain(out[41791:41977], 2, 280), 41791) degrain = insert_clip(degrain, smhdegrain(out[41977:42073], 2, 280), 41977) degrain = insert_clip(degrain, smhdegrain(out[43083:44462], 2, 350), 43083) degrain = lvf.rfs(degrain, out, [(51749, 52387)]) out = depth(degrain, 32) luma = get_y(out) line_mask = vdf.edge_detect(luma, 'kirsch', 0.075, (1, 1)).std.Median().std.Inflate() descale = core.descale.Debilinear(luma, w, h) upscale = eedi3_upscale(descale) antialias = single_rate_antialiasing(upscale, 13, alpha=0.2, beta=0.6, gamma=300, mdis=15).resize.Bicubic( src.width, src.height) rescale = core.std.MaskedMerge(luma, antialias, line_mask) merged = vdf.merge_chroma(rescale, out) out = depth(merged, 16) y = get_y(out) detail_light_mask = lvf.denoise.detail_mask(y.std.Median(), brz_a=2500, brz_b=1200) pf = out.std.Convolution([1] * 9).std.Merge(out, 0.45) diffdb = core.std.MakeDiff(out, pf) deband = dumb3kdb(pf, 16, 30) deband_b = dbs.f3kbilateral(pf, 20, 100) deband = lvf.rfs(deband, deband_b, [(43083, 44461)]) deband = core.std.MergeDiff(deband, diffdb) deband = core.std.MaskedMerge(deband, out, detail_light_mask) deband = lvf.rfs(deband, out, [(51749, 52387)]) out = deband sharp = hvf.LSFmod(out, strength=65, Smode=3, Lmode=1, edgemode=1, edgemaskHQ=True) out = sharp ref = get_y(out).std.PlaneStats() adgmask_a = core.adg.Mask(ref, 30) adgmask_b = core.adg.Mask(ref, 12) stgrain = sizedgrn(out, 0.1, 0.05, 1.00) stgrain = core.std.MaskedMerge(out, stgrain, adgmask_b) stgrain = core.std.MaskedMerge(out, stgrain, adgmask_a.std.Invert()) dygrain = sizedgrn(out, 0.2, 0.05, 1.05, sharp=60, static=False) dygrain = core.std.MaskedMerge(out, dygrain, adgmask_a) grain = core.std.MergeDiff(dygrain, out.std.MakeDiff(stgrain)) out = grain ref = src rescale_mask = vdf.drm(ref, h, mthr=65, sw=4, sh=4) credit = out credit = lvf.rfs(credit, core.std.MaskedMerge(credit, ref, rescale_mask, 0), [(0, 2956), (43104, 45749)]) credit = lvf.rfs(credit, ref, [(45824, 50401), (52388, src.num_frames - 1)]) out = credit return depth(out, 10)
def main(self: Filtering) -> vs.VideoNode: """Vapoursynth filtering""" src = JPBD.clip_cut src = depth(src, 16) out = src h = 800 # noqa w = get_w(h) # noqa opstart, opend = 2830, 4986 edstart, edend = 31504, 33661 inp = get_y(out) out = inp # Remove the grain ref = hvf.SMDegrain(out, tr=1, thSAD=300, plane=0) preden = mvf.BM3D(out, sigma=2, radius1=1, ref=ref) out = preden # Rescale / Antialiasing / Limiting out = depth(out, 32) lineart = vdf.mask.FDOG().get_mask(out, lthr=0.065, hthr=0.065).std.Maximum().std.Minimum() lineart = lineart.std.Median().std.Convolution([1] * 9) descale_clips = [core.resize.Bicubic(out, w, h, filter_param_a=1/3, filter_param_b=1/3), core.descale.Debicubic(out, w, h, 0, 1/2), core.descale.Debilinear(out, w, h)] descale = core.std.Expr(descale_clips, 'x y z min max y z max min z min') upscale = vdf.scale.fsrcnnx_upscale(descale, height=h * 2, shader_file=r'_shaders\FSRCNNX_x2_56-16-4-1.glsl', upscaled_smooth=vdf.scale.eedi3_upscale(descale), profile='zastin', sharpener=partial(gf.DetailSharpen, sstr=1.65, power=4, mode=0, med=True)) antialias = self.sraa_eedi3(upscale, 3, alpha=0.2, beta=0.4, gamma=100, mdis=20, nrad=3) downscale = muvf.SSIM_downsample(antialias, src.width, src.height, kernel='Bicubic', filter_param_a=0, filter_param_b=0) adaptmask = core.adg.Mask(downscale.std.PlaneStats(), 25).std.Minimum().std.Minimum().std.Convolution([1] * 9) contra = gf.ContraSharpening(downscale, depth(preden, 32), radius=2).rgsf.Repair(downscale, 1) contra = core.std.MaskedMerge(downscale, contra, adaptmask) scaled = core.std.MaskedMerge(out, contra, lineart) merged = vdf.misc.merge_chroma(depth(scaled, 16), src) out = merged detail_light_mask = lvf.mask.detail_mask(out, brz_a=1500, brz_b=600) deband = vdf.deband.dumb3kdb(out, 16, [33, 1], sample_mode=4, use_neo=True) deband = core.std.MaskedMerge(deband, out, detail_light_mask) out = deband # Restore the grain neutral = inp.std.BlankClip(960, 540, color=128 << 8) diff = join([inp.std.MakeDiff(preden), neutral, neutral]) grain = core.std.MergeDiff(out, diff) out = grain crop_a = self.crop_and_fix(out, src, top=128, bottom=136) crop_b = self.crop_and_fix(out, src, top=132, bottom=140) crop = out crop = lvf.rfs(crop, crop_a, [(25696, 25750), (25768, 25963), (26916, 27095), (27213, 27319), (27368, 27395), (27615, 27810)]) crop = lvf.rfs(crop, crop_b, [(25751, 25767), (25964, 26723), (26786, 26915), (27096, 27212), (27320, 27367), (27396, 27614)]) out = crop ref = src creditless_mask = vdf.mask.diff_creditless_mask( ref, src[opstart:opend+1], JPBD_NCOP.clip_cut[:opend-opstart+1], opstart, thr=25 << 8, sw=3, sh=3, prefilter=True ).std.Deflate() ringing_mask = hvf.HQDeringmod(ref, mrad=1, msmooth=2, mthr=40, show=True) credit = out credit = lvf.rfs(credit, ref, [(edstart, edend)]) credit = lvf.rfs(credit, core.std.MaskedMerge(credit, ref, creditless_mask, 0), [(opstart, opend)]) credit = lvf.rfs(credit, core.std.MaskedMerge(credit, ref, ringing_mask, 0), [(opstart + 169, opstart + 411)]) out = credit endcard = out + out[31757] * 119 out = endcard decs = vdf.noise.decsiz(out, sigmaS=10, min_in=110 << 8, max_in=192 << 8, gamma=1.1) out = decs return depth(out, 10).std.Limiter(16 << 2, [235 << 2, 240 << 2])