def deband(clip: vs.VideoNode, strong: Optional[List[Range]] = None, nuclear: Optional[List[Range]] = None) -> vs.VideoNode: dmask = detail_mask(clip) deb = dumb3kdb(clip, radius=16, threshold=30) if strong: debs = dumb3kdb(clip, radius=24, threshold=60) deb = replace_ranges(deb, debs, strong or []) if nuclear: debn = core.std.ShufflePlanes([ f3kbilateral(clip.std.ShufflePlanes(planes=0, colorfamily=vs.GRAY), y=60), deb ], planes=[0, 1, 2], colorfamily=vs.YUV) deb = replace_ranges(deb, debn, nuclear or []) return core.std.MaskedMerge(deb, clip, dmask)
def wraw_filterchain() -> vs.VideoNode: """Workraw filterchain with minimal filtering""" from vardefunc.deband import dumb3kdb from vsutil import depth src: vs.VideoNode = pre_freeze() src = depth(src, 16) deband = dumb3kdb(src, radius=16, threshold=30, grain=16) grain: vs.VideoNode = core.grain.Add(deband, 0.15) return grain
def masked_f3kdb(clip: vs.VideoNode, rad: int = 16, thr: Union[int, List[int]] = 24, grain: Union[int, List[int]] = [12, 0], mask_args: Dict[str, Any] = {}) -> vs.VideoNode: """Basic f3kdb debanding with detail mask """ from vardefunc.deband import dumb3kdb deb_mask_args: Dict[str, Any] = dict(brz=(1000, 2750)) deb_mask_args |= mask_args bits, clip = _get_bits(clip) deband_mask = detail_mask(clip, **deb_mask_args) deband = dumb3kdb(clip, radius=rad, threshold=thr, grain=grain) deband_masked = core.std.MaskedMerge(deband, clip, deband_mask) deband_masked = deband_masked if bits == 16 else depth(deband_masked, bits) return deband_masked
def main() -> Union[vs.VideoNode, Tuple[vs.VideoNode, ...]]: """Vapoursynth filtering""" # Don't worry, this script is barely readable anymore even for me import rekt from awsmfunc import bbmod from havsfunc import ContraSharpening from lvsfunc.aa import upscaled_sraa from lvsfunc.comparison import stack_compare from lvsfunc.mask import BoundingBox from lvsfunc.util import replace_ranges from vardefunc import dcm from vardefunc.deband import dumb3kdb from vardefunc.mask import FreyChen from vsutil import depth, get_y, insert_clip src = JP_BD.clip_cut b = core.std.BlankClip(src, length=1) if opstart is not False: src_NCOP = NCOP.clip_cut op_scomp = stack_compare( src[opstart:opstart + src_NCOP.num_frames - 1] + b, src_NCOP[:-op_offset] + b, make_diff=True) # noqa if edstart is not False: src_NCED = NCED.clip_cut #ed_scomp = stack_compare(src[edstart:edstart+src_NCED.num_frames-1]+b, src_NCED[:-ed_offset]+b, make_diff=True) # noqa # Masking credits op_mask = dcm( src, src[opstart:opstart+src_NCOP.num_frames], src_NCOP, start_frame=opstart, thr=25, prefilter=True) if opstart is not False \ else get_y(core.std.BlankClip(src)) ed_mask = dcm( src, src[edstart:edstart+src_NCED.num_frames], src_NCED, start_frame=edstart, thr=25, prefilter=True) if edstart is not False \ else get_y(core.std.BlankClip(src)) credit_mask = core.std.Expr([op_mask, ed_mask], expr='x y +') credit_mask = depth(credit_mask, 16).std.Binarize() # Fixing an animation f**k-up for f in op_replace: src = insert_clip(src, src[f], f - 1) # Edgefixing ef = rekt.rektlvls( src, prot_val=[16, 235], min=16, max=235, rownum=[0, src.height - 1], rowval=[16, 16], colnum=[0, src.width - 1], colval=[16, 16], ) bb_y = bbmod(ef, left=1, top=1, right=1, bottom=1, thresh=32, y=True, u=False, v=False) bb_uv = bbmod(bb_y, left=2, top=2, right=2, bottom=2, y=False, u=True, v=True) bb32 = depth(bb_uv, 32) # --- Very specific filtering that should probably be removed for future episodes entirely # Fading for some... well, fades. fade = flt.fader(bb32, start_frame=4437, end_frame=4452) fade = flt.fader(fade, start_frame=18660, end_frame=18697) # Different sport names rkt_aa_ranges: Union[Union[int, None, Tuple[Optional[int], Optional[int]]], List[Union[int, None, Tuple[Optional[int], Optional[int]]]], None] = [ # noqa (8824, 8907), (9828, 9911), (10995, 11078), (11904, 12010) ] rkt_aa = rekt.rekt_fast(fade, fun=lambda x: upscaled_sraa(x), top=854, left=422, bottom=60, right=422) rkt_aa = replace_ranges(fade, rkt_aa, rkt_aa_ranges) # QP GET! rkt_aa2_ranges: Union[Union[int, None, Tuple[Optional[int], Optional[int]]], List[Union[int, None, Tuple[Optional[int], Optional[int]]]], None] = [ # noqa (26333, 26333), (28291, 28344), (30271, 30364) ] rkt_aa2 = rekt.rekt_fast(rkt_aa, fun=lambda x: upscaled_sraa(x), top=714, left=354, bottom=224, right=354) rkt_aa2 = replace_ranges(fade, rkt_aa, rkt_aa2_ranges) # Table stuff rkt_aa3_ranges: Union[Union[int, None, Tuple[Optional[int], Optional[int]]], List[Union[int, None, Tuple[Optional[int], Optional[int]]]], None] = [ # noqa (32797, 32952) ] rkt_aa3 = rekt.rekt_fast(rkt_aa2, fun=lambda x: upscaled_sraa(x), top=488, left=312, bottom=390, right=850) rkt_aa3 = replace_ranges(fade, rkt_aa2, rkt_aa3_ranges) rkt_aa = rkt_aa3 # Clipping error Nyatalante/Achilles fixed_frame = source( JP_BD.workdir.to_str() + r"/assets/01/FGCBD_01_8970_fixed.png", rkt_aa) fix_error = replace_ranges(rkt_aa, fixed_frame, [(8968, 8970)]) sp_out32 = fix_error sp_out16 = depth(sp_out32, 16) # Rescaling l_mask = FreyChen().get_mask(get_y(sp_out16)).morpho.Close(size=6) l_mask = core.std.Binarize(l_mask, 24 << 8).std.Maximum().std.Maximum() scaled, credit_mask = flt.rescaler(sp_out32, height=720, shader_file=shader) scaled = core.std.MaskedMerge(sp_out16, scaled, l_mask) scaled = core.std.MaskedMerge(scaled, sp_out16, credit_mask) # Denoising denoise = flt.multi_denoise(scaled, l_mask) # Anti-aliasing aa_clamped = flt.clamp_aa(denoise, strength=3.0) aa_rfs = replace_ranges(denoise, aa_clamped, aa_ranges) # Fix edges because they get f****d during the denoising and AA stages box = BoundingBox((1, 1), (src.width - 2, src.height - 2)) fix_edges = core.std.MaskedMerge(scaled, aa_rfs, box.get_mask(scaled)) # Regular debanding, but then... deband = flt.multi_debander(fix_edges, sp_out16) # --- More very specific filtering that should almost definitely be removed for other episodes boxes = [ BoundingBox((0, 880), (1920, 200)), BoundingBox((1367, 0), (552, 1080)), BoundingBox((1143, 0), (466, 83)), BoundingBox((1233, 84), (237, 84)), ] boxed_deband = flt.placebo_debander(fix_edges, iterations=2, threshold=8, radius=14, grain=4) boxed_mask = core.std.BlankClip( boxed_deband.std.ShufflePlanes(planes=0, colorfamily=vs.GRAY)) for bx in boxes: # Gonna be awfully slow but OH WELLLLLL boxed_mask = core.std.Expr( [boxed_mask, bx.get_mask(boxed_mask)], "x y max") boxed_deband_merged = core.std.MaskedMerge(deband, boxed_deband, boxed_mask) boxed_deband_merged = replace_ranges(deband, boxed_deband_merged, [(20554, 20625)]) stronger_deband = dumb3kdb(fix_edges, radius=18, threshold=[48, 32]) stronger_deband = replace_ranges(boxed_deband_merged, stronger_deband, [(22547, 22912), (28615, 28846), (33499, 33708), (37223, 37572), (37636, 37791), (38047, 38102), (38411, 38733)]) deband_csharp = ContraSharpening(stronger_deband, scaled, 17) sp_out = deband_csharp # Back to regular graining grain = flt.grain(sp_out) return grain
def deband_tv(clip: vs.VideoNode) -> vs.VideoNode: dmask = detail_mask(clip) deb = dumb3kdb(clip, radius=16, threshold=40) return core.std.MaskedMerge(deb, clip, dmask)