示例#1
0
def detail_mask(
        clip: vs.VideoNode,
        sigma: float = 1.0,
        detail_brz: int = 2500,
        lines_brz: int = 4500,
        blur_func: Callable[
            [vs.VideoNode, vs.VideoNode, float],
            vs.VideoNode] = core.bilateral.Bilateral,  # type: ignore
        edgemask_func: Callable[[vs.VideoNode],
                                vs.VideoNode] = core.std.Prewitt,
        rg_mode: int = 17) -> vs.VideoNode:
    """
    A detail mask aimed at preserving as much detail as possible within darker areas,
    even if it winds up being mostly noise.
    Currently still in the beta stage.
    Please report any problems or feedback in the IEW Discord (link in the README).
    :param clip:            Input clip
    :param sigma:           Sigma for the detail mask.
                            Higher means more detail and noise will be caught.
    :param detail_brz:      Binarizing for the detail mask.
                            Default values assume a 16bit clip, so you may need to adjust it yourself.
                            Will not binarize if set to 0.
    :param lines_brz:       Binarizing for the prewitt mask.
                            Default values assume a 16bit clip, so you may need to adjust it yourself.
                            Will not binarize if set to 0.
    :param blur_func:       Blurring function used for the detail detection.
                            Must accept the following parameters: ``clip``, ``ref_clip``, ``sigma``.
    :param edgemask_func:   Edgemasking function used for the edge detection
    :param rg_mode:         Removegrain mode performed on the final output
    """
    import lvsfunc as lvf
    from vsutil import get_y, iterate

    if clip.format is None:
        raise ValueError("detail_mask: 'Variable-format clips not supported'")

    clip_y = get_y(clip)
    blur_pf = core.bilateral.Gaussian(clip_y, sigma=sigma / 4 * 3)

    blur_pref = blur_func(clip_y, blur_pf, sigma)
    blur_pref_diff = core.std.Expr([blur_pref, clip_y], "x y -").std.Deflate()
    blur_pref = iterate(blur_pref_diff, core.std.Inflate, 4)

    prew_mask = edgemask_func(clip_y).std.Deflate().std.Inflate()

    if detail_brz > 0:
        blur_pref = blur_pref.std.Binarize(detail_brz)
    if lines_brz > 0:
        prew_mask = prew_mask.std.Binarize(lines_brz)

    merged = core.std.Expr([blur_pref, prew_mask], "x y +")
    rm_grain = lvf.util.pick_removegrain(merged)(merged, rg_mode)

    return depth(rm_grain, clip.format.bits_per_sample)
示例#2
0
def linemask(clip: vs.VideoNode,
             strength: int = 200,
             protection: int = 2,
             luma_cap: int = 224,
             threshold: float = 3) -> Tuple[vs.VideoNode, vs.VideoNode]:
    """
    Lineart mask from havsfunc.FastLineDarkenMod, using the very same syntax.

    Furthermore, it checks the overall planestatsaverage of the frame
    to determine if it's a super grainy scene or not.
    """
    import math
    from functools import partial
    from typing import List

    from lvsfunc.misc import get_prop
    from vsutil import depth, get_depth, get_y

    def _reduce_grain(n: int, f: vs.VideoFrame,
                      clips: List[vs.VideoNode]) -> vs.VideoNode:
        return clips[1] if get_prop(f, 'PlaneStatsAverage',
                                    float) > 0.032 else clips[0]

    def _cround(x: float) -> float:
        return math.floor(x + 0.5) if x > 0 else math.ceil(x - 0.5)

    assert clip.format

    clip_y = get_y(depth(clip, 8))
    bits = clip.format.bits_per_sample

    peak = (1 << get_depth(clip_y)) - 1

    strngth = strength / 128
    lum = _cround(luma_cap * peak / 255) if peak != 1 else luma_cap / 255
    thr = _cround(threshold * peak / 255) if peak != 1 else threshold / 255

    maxed = clip_y.std.Maximum(threshold=peak / (protection + 1)).std.Minimum()
    dark = core.std.Expr(
        [clip_y, maxed],
        expr=
        f'y {lum} < y {lum} ? x {thr} + > x y {lum} < y {lum} ? - 0 ? {strngth} * x +'
    )
    extr = core.std.Lut2(clip_y,
                         dark,
                         function=lambda x, y: 255 if abs(x - y) else 0)

    dedot = extr.rgvs.RemoveGrain(6)
    blur = dedot.std.Convolution(matrix=[1, 2, 1, 2, 0, 2, 1, 2, 1])
    degrain = core.std.FrameEval(dedot,
                                 partial(_reduce_grain, clips=[dedot, blur]),
                                 dedot.std.PlaneStats())

    return dark, depth(degrain, bits)
示例#3
0
 def _fsrcnnx(clip: vs.VideoNode) -> vs.VideoNode:
     blank = core.std.BlankClip(clip, format=vs.GRAY16, color=128 << 8)
     clip = join([clip, blank, blank])
     # The chroma is upscaled with box AKA nearest but we don't care since we only need the luma.
     # It's especially faster and speed is the key :^)
     clip = core.placebo.Shader(clip,
                                'Shaders/FSRCNNX_x2_56-16-4-1.glsl',
                                clip.width * 2,
                                clip.height * 2,
                                filter='box')
     return get_y(clip)
示例#4
0
def detail_mask(clip: vs.VideoNode,
                pre_denoise: Optional[float] = None,
                rad: int = 3,
                radc: int = 2,
                brz_a: float = 0.005,
                brz_b: float = 0.005) -> vs.VideoNode:
    """
        A wrapper for creating a detail mask to be used during denoising and/or debanding.
        The detail mask is created using debandshit's rangemask,
        and is then merged with Prewitt to catch lines it may have missed.

        Dependencies: knlmeans (optional: pre_denoise), debandshit

        :param clip:        Input clip
        :param pre_denoise: Denoise the clip before creating the mask (Default: False)
        :brz_a:             Binarizing for the detail mask (Default: 0.05)
        :brz_b:             Binarizing for the edge mask (Default: 0.05)

        :return:            Detail mask
    """
    try:
        from debandshit import rangemask
    except ModuleNotFoundError:
        raise ModuleNotFoundError(
            "detail_mask: missing dependency 'debandshit'")

    if pre_denoise is not None:
        clip = core.knlm.KNLMeansCL(clip, d=2, a=3, h=pre_denoise)

    mask_a = util.resampler(
        get_y(clip), 16) if clip.format.bits_per_sample < 32 else get_y(clip)
    mask_a = rangemask(mask_a, rad=rad, radc=radc)
    mask_a = util.resampler(mask_a, clip.format.bits_per_sample)
    mask_a = core.std.Binarize(mask_a, brz_a)

    mask_b = core.std.Prewitt(get_y(clip))
    mask_b = core.std.Binarize(mask_b, brz_b)

    mask = core.std.Expr([mask_a, mask_b], 'x y max')
    mask = util.pick_removegrain(mask)(mask, 22)
    return util.pick_removegrain(mask)(mask, 11)
示例#5
0
文件: aa.py 项目: pog42/lvsfunc
def transpose_aa(clip: vs.VideoNode,
                 eedi3: bool = False,
                 rep: int = 13) -> vs.VideoNode:
    """
    Function that performs anti-aliasing over a clip by using nnedi3/eedi3 and transposing multiple times.
    This results in overall stronger anti-aliasing.
    Useful for shows like Yuru Camp with bad lineart problems.

    Original function written by Zastin, modified by LightArrowsEXE.

    Dependencies: rgsf (optional: 32 bit clip), vapoursynth-eedi3, vapoursynth-nnedi3, znedi3

    :param clip:      Input clip
    :param eedi3:     Use eedi3 for the interpolation (Default: False)
    :param rep:       Repair mode. Pass it 0 to not repair (Default: 13)

    :return:          Antialiased clip
    """
    if clip.format is None:
        raise ValueError("transpose_aa: 'Variable-format clips not supported'")

    clip_y = get_y(clip)

    if eedi3:
        def _aa(clip_y: vs.VideoNode) -> vs.VideoNode:
            clip_y = clip_y.std.Transpose()
            clip_y = clip_y.eedi3m.EEDI3(0, 1, 0, 0.5, 0.2)
            clip_y = clip_y.znedi3.nnedi3(1, 0, 0, 3, 4, 2)
            clip_y = clip_y.resize.Spline36(clip.height, clip.width, src_top=.5)
            clip_y = clip_y.std.Transpose()
            clip_y = clip_y.eedi3m.EEDI3(0, 1, 0, 0.5, 0.2)
            clip_y = clip_y.znedi3.nnedi3(1, 0, 0, 3, 4, 2)
            return clip_y.resize.Spline36(clip.width, clip.height, src_top=.5)
    else:
        def _aa(clip_y: vs.VideoNode) -> vs.VideoNode:
            clip_y = clip_y.std.Transpose()
            clip_y = clip_y.nnedi3.nnedi3(0, 1, 0, 3, 3, 2)
            clip_y = clip_y.nnedi3.nnedi3(1, 0, 0, 3, 3, 2)
            clip_y = clip_y.resize.Spline36(clip.height, clip.width, src_top=.5)
            clip_y = clip_y.std.Transpose()
            clip_y = clip_y.nnedi3.nnedi3(0, 1, 0, 3, 3, 2)
            clip_y = clip_y.nnedi3.nnedi3(1, 0, 0, 3, 3, 2)
            return clip_y.resize.Spline36(clip.width, clip.height, src_top=.5)

    def _csharp(flt: vs.VideoNode, clip: vs.VideoNode) -> vs.VideoNode:
        blur = core.std.Convolution(flt, [1] * 9)
        return core.std.Expr([flt, clip, blur], 'x y < x x + z - x max y min x x + z - x min y max ?')

    aaclip = _aa(clip_y)
    aaclip = _csharp(aaclip, clip_y)
    aaclip = util.pick_repair(clip_y)(aaclip, clip_y, rep)

    return aaclip if clip.format.color_family is vs.GRAY else core.std.ShufflePlanes([aaclip, clip], [0, 1, 2], vs.YUV)
示例#6
0
def do_filter():
    """Vapoursynth filtering"""
    src = JPBD.src_cut
    src = depth(src, 32)
    ed = (30089, 32247)

    denoise = kgf.hybriddenoise(src, 0.45, 2)
    out = denoise

    h = 720
    w = get_w(h)
    b, c = vdf.get_bicubic_params('mitchell')


    luma = get_y(out)
    line_mask = shf.edge_mask_simple(luma, 'FDOG', 0.08, (1, 1))


    descale = core.descale.Debicubic(luma, w, h, b, c)
    upscale = shf.fsrcnnx_upscale(descale, src.height, 'shaders/FSRCNNX_x2_56-16-4-1.glsl',
                                  partial(SSIM_downsample, kernel='Bicubic'))
    rescale = core.std.MaskedMerge(luma, upscale, line_mask)
    merged = vdf.merge_chroma(rescale, denoise)
    out = depth(merged, 16)



    mask = shf.detail_mask(out, (10000, 4000), (12000, 3500), [(2, 2), (2, 2)], sigma=[50, 250, 400], upper_thr=0.005)
    deband = dbs.f3kpf(out, 17, 42, 48, thrc=0.4)
    deband = core.std.MaskedMerge(deband, out, mask)

    deband_b = placebo.deband(out, 27, 8, 3, 0)
    deband = lvf.rfs(deband, deband_b, [(3404, 3450)])

    deband_c = shf.deband_stonks(out, 20, 8, 3, shf.edge_mask_simple(out, 'prewitt', 2500, (8, 1)))
    deband = lvf.rfs(deband, deband_c, [(5642, 5784), (6222, 6479), (7798, 8073), (8133, 8256), (9699, 9817)])

    deband_d = placebo.deband(out, 17, 7.5, 1, 0)
    deband_d = core.std.MaskedMerge(deband_d, out, mask)
    deband = lvf.rfs(deband, deband_d, [(8074, 8132), (8711, 8766), (12267, 12433), (28468, 28507)])

    grain = core.neo_f3kdb.Deband(deband, preset='depth', grainy=24, grainc=24)
    out = grain


    grain = adptvgrnMod(out, 0.3, size=4/3, sharp=55, luma_scaling=14, grain_chroma=False)
    out = grain


    ending = shinyori_ed01.filtering(src, *ed)
    final = lvf.rfs(out, ending, [ed])

    return depth(final, 10)
示例#7
0
def filterchain() -> Union[vs.VideoNode, Tuple[vs.VideoNode, ...]]:
    """Regular VapourSynth filterchain"""
    import havsfunc as haf
    import lvsfunc as lvf
    import vardefunc as vdf
    from adptvgrnMod import adptvgrnMod
    from muvsfunc import SSIM_downsample
    from vsutil import depth, get_y, iterate

    src = pre_freeze()
    src = depth(src, 16)

    # TO-DO: Figure out how they post-sharpened it. Probably some form of unsharpening?
    src_y = depth(get_y(src), 32)
    descale = lvf.kernels.Bicubic(b=0, c=3 / 4).descale(src_y, 1440, 810)
    double = vdf.scale.nnedi3cl_double(descale, pscrn=1)
    rescale = depth(SSIM_downsample(double, 1920, 1080), 16)
    scaled = vdf.misc.merge_chroma(rescale, src)

    denoise = core.knlm.KNLMeansCL(scaled, d=1, a=3, s=4, h=0.3, channels='Y')
    decs = vdf.noise.decsiz(denoise,
                            sigmaS=4,
                            min_in=208 << 8,
                            max_in=232 << 8)

    dehalo = haf.YAHR(decs, blur=2, depth=28)
    halo_mask = lvf.mask.halo_mask(decs, rad=3, brz=0.3, thma=0.42)
    dehalo_masked = core.std.MaskedMerge(decs, dehalo, halo_mask)

    aa = lvf.aa.nneedi3_clamp(dehalo_masked, strength=1.5)
    # Some scenes have super strong aliasing that I really don't wanna scenefilter until BDs. Thanks, Silver Link!
    aa_strong = lvf.sraa(dehalo_masked, rfactor=1.35)
    aa_spliced = lvf.rfs(aa, aa_strong, [()])

    upscale = lvf.kernels.Bicubic(b=0, c=3 / 4).scale(descale, 1920, 1080)
    credit_mask = lvf.scale.descale_detail_mask(src_y, upscale, threshold=0.08)
    credit_mask = iterate(credit_mask, core.std.Deflate, 3)
    credit_mask = iterate(credit_mask, core.std.Inflate, 3)
    credit_mask = iterate(credit_mask, core.std.Maximum, 2)
    merge_credits = core.std.MaskedMerge(aa_spliced, src,
                                         depth(credit_mask, 16))

    deband = flt.masked_f3kdb(merge_credits, rad=18, thr=32, grain=[24, 0])
    grain: vs.VideoNode = adptvgrnMod(deband,
                                      seed=42069,
                                      strength=0.15,
                                      luma_scaling=10,
                                      size=1.25,
                                      sharp=80,
                                      static=True,
                                      grain_chroma=False)

    return grain
示例#8
0
def mask_nc(clip: vs.VideoNode,
            src: vs.VideoNode,
            ncop: FileInfo,
            nced: FileInfo,
            OP: Optional[int] = None,
            ED: Optional[int] = None) -> vs.VideoNode:
    mask_op = vdf.dcm(src,
                      src[OP:OP + ncop.clip_cut.num_frames],
                      ncop.clip_cut,
                      OP,
                      thr=128,
                      prefilter=True) if OP else get_y(core.std.BlankClip(src))
    mask_ed = vdf.dcm(src,
                      src[ED:ED + nced.clip_cut.num_frames],
                      nced.clip_cut,
                      ED,
                      thr=128,
                      prefilter=True) if ED else get_y(core.std.BlankClip(src))
    credit_mask = depth(core.std.Expr([mask_op, mask_ed], expr='x y +'), 16)
    merge = core.std.MaskedMerge(depth(clip, 16), depth(src, 16), credit_mask)
    return merge
示例#9
0
    def _vdf_fsrcnnx(clip: vs.VideoNode, width: int,
                     height: int) -> vs.VideoNode:
        clip = core.std.ShufflePlanes([
            vsutil.depth(clip.resize.Point(vsutil.get_w(864), 864), 16),
            src.resize.Bicubic(vsutil.get_w(864), 864)
        ],
                                      planes=[0, 1, 2],
                                      colorfamily=vs.YUV)

        return vsutil.get_y(
            vsutil.depth(vdf.fsrcnnx_upscale(clip, width, height, FSRCNNX),
                         32))
示例#10
0
def filterchain() -> Union[vs.VideoNode, Tuple[vs.VideoNode, ...]]:
    """Main filterchain"""
    import lvsfunc as lvf
    import rekt
    import vardefunc as vdf
    from muvsfunc import SSIM_downsample
    from vsutil import depth, get_y

    src = JP_BD.clip_cut
    rkt = rekt.rektlvls(src, [0, -1], [15, 15], [0, -1], [15, 15])
    cloc = depth(rkt, 32).resize.Bicubic(chromaloc_in=1, chromaloc=0)

    descale = lvf.kernels.Bilinear().descale(get_y(cloc), 1280, 720)
    supersample = vdf.scale.nnedi3_upscale(descale)
    downscaled = SSIM_downsample(supersample,
                                 src.width,
                                 src.height,
                                 smooth=((3**2 - 1) / 12)**0.5,
                                 sigmoid=True,
                                 filter_param_a=0,
                                 filter_param_b=0)
    scaled = vdf.misc.merge_chroma(downscaled, cloc)
    scaled = depth(scaled, 16)

    dft = core.dfttest.DFTTest(scaled,
                               sigma=0.6,
                               sbsize=8,
                               sosize=6,
                               tbsize=3,
                               tosize=1)
    decs = vdf.noise.decsiz(dft, sigmaS=4, min_in=200 << 8, max_in=232 << 8)

    baa = lvf.aa.based_aa(decs, str(shader_file))
    sraa = lvf.sraa(decs, rfactor=1.5)
    clmp = lvf.aa.clamp_aa(decs, baa, sraa, strength=1.5)

    deband = flt.masked_f3kdb(clmp, rad=16, thr=[20, 16])

    grain = vdf.noise.Graigasm(thrs=[x << 8 for x in (32, 80, 128, 176)],
                               strengths=[(0.25, 0.0), (0.20, 0.0),
                                          (0.15, 0.0), (0.0, 0.0)],
                               sizes=(1.20, 1.15, 1.10, 1),
                               sharps=(80, 70, 60, 50),
                               grainers=[
                                   vdf.noise.AddGrain(seed=69420,
                                                      constant=False),
                                   vdf.noise.AddGrain(seed=69420,
                                                      constant=False),
                                   vdf.noise.AddGrain(seed=69420,
                                                      constant=True)
                               ]).graining(deband)

    return grain
示例#11
0
    def _nneedi3_clamp(clip: vs.VideoNode, strength: int = 1):
        bits = clip.format.bits_per_sample - 8
        thr = strength * (1 >> bits)

        luma = get_y(clip)

        strong = TAAmbk(luma, aatype='Eedi3', alpha=0.4, beta=0.4)
        weak = TAAmbk(luma, aatype='Nnedi3')
        expr = 'x z - y z - * 0 < y x y {0} + min y {0} - max ?'.format(thr)

        clip_aa = core.std.Expr([strong, weak, luma], expr)
        return core.std.ShufflePlanes([clip_aa, clip], [0, 1, 2], vs.YUV)
示例#12
0
def do_filter():
    """Vapoursynth filtering"""
    def _nnedi3(clip: vs.VideoNode, factor: float, args: dict)-> vs.VideoNode:
        upscale = clip.std.Transpose().nnedi3.nnedi3(0, True, **args) \
            .std.Transpose().nnedi3.nnedi3(0, True, **args)
        sraa = _sraa(upscale, dict(nsize=3, nns=3, qual=1, pscrn=1))
        return core.resize.Bicubic(sraa, clip.width*factor, clip.height*factor,
                                   src_top=.5, src_left=.5, filter_param_a=0, filter_param_b=0.25)

    # My GPU’s dying on it
    def _sraa(clip: vs.VideoNode, nnargs: dict)-> vs.VideoNode:
        clip = clip.nnedi3cl.NNEDI3CL(0, False, **nnargs).std.Transpose()
        clip = clip.nnedi3cl.NNEDI3CL(0, False, **nnargs).std.Transpose()
        return clip

    # Fun part / Cutting
    src_funi, src_wkn = [depth(c, 16) for c in CLIPS_SRC]
    src_funi, src_wkn = src_funi[744:], src_wkn[0] + src_wkn

    # Dehardsubbing
    # comp = lvf.comparison.stack_compare(src_funi, src_wkn, make_diff=True)
    src = core.std.MaskedMerge(src_wkn, src_funi, kgf.hardsubmask(src_wkn, src_funi))
    hardsub_rem = core.std.MaskedMerge(src, src_funi, kgf.hardsubmask_fades(src, src_funi, 8, 2000))
    src = lvf.rfs(src, hardsub_rem, [(3917, 4024)])


    # Regular filterchain
    op, ed = (17238, 19468), (31889, 34045)
    h = 846
    w = get_w(h)
    b, c = vdf.get_bicubic_params('robidoux')

    luma = get_y(src)

    thr = 8000
    line_mask = gf.EdgeDetect(luma, 'FDOG').std.Median().std.Expr(f'x {thr} < x x 3 * ?')

    descale = core.descale.Debicubic(depth(luma, 32), w, h, b, c)
    rescaled = _nnedi3(depth(descale, 16), src.height/h, dict(nsize=0, nns=4, qual=2, pscrn=2))
    rescaled = core.std.MaskedMerge(luma, rescaled, line_mask)
    merged = vdf.merge_chroma(rescaled, src)
    out = merged

    cred_m = vdf.drm(src, h, b=b, c=c, mthr=80, mode='ellipse')
    credit = lvf.rfs(out, core.std.MaskedMerge(out, src, cred_m), [op])
    credit = lvf.rfs(credit, src, [ed])
    out = credit

    deband = dbs.f3kpf(out, 17, 36, 36)
    deband = core.std.MaskedMerge(deband, out, line_mask)
    grain = core.grain.Add(deband, 0.25)

    return depth(grain, 10)
示例#13
0
def filterchain() -> Union[vs.VideoNode, Tuple[vs.VideoNode, ...]]:
    """Main VapourSynth filterchain"""
    import EoEfunc as eoe
    import lvsfunc as lvf
    import vardefunc as vdf
    from ccd import ccd
    from finedehalo import fine_dehalo
    from vsutil import depth, get_y

    src, ep = JP_BD.clip_cut, JP_EP.clip_cut
    src = lvf.rfs(src, ep, [(811, 859)])
    src = depth(src, 16)

    # This noise can burn in hell.
    denoise_pre = get_y(src.dfttest.DFTTest(sigma=1.0))
    denoise_ret = core.retinex.MSRCP(denoise_pre, sigma=[50, 200, 350], upper_thr=0.005)
    denoise_mask = flt.detail_mask(denoise_ret, sigma=2.0, lines_brz=3000).rgvs.RemoveGrain(4)

    denoise_pre = core.dfttest.DFTTest(src, sigma=4.0)
    denoise_smd = eoe.dn.CMDegrain(src, tr=5, thSAD=275, freq_merge=True, prefilter=denoise_pre)
    denoise_masked = core.std.MaskedMerge(denoise_smd, src, denoise_mask)

    denoise_uv = ccd(denoise_masked, threshold=6)
    decs = vdf.noise.decsiz(denoise_uv, sigmaS=8, min_in=200 << 8, max_in=235 << 8)

    # F**K THIS SHOW'S LINEART HOLY SHIT
    baa = lvf.aa.based_aa(decs.std.Transpose(), str(shader_file), gamma=120)
    baa = lvf.aa.based_aa(baa.std.Transpose(), str(shader_file), gamma=120)
    sraa = lvf.sraa(decs, rfactor=1.4)
    clmp_aa = lvf.aa.clamp_aa(decs, baa, sraa, strength=1.65)

    # AAing introduces some haloing (zzzzzz)
    restr_edges = fine_dehalo(clmp_aa, decs)
    restr_dark = core.std.Expr([clmp_aa, restr_edges], "x y min")

    deband = core.average.Mean([
        flt.masked_f3kdb(restr_dark, rad=17, thr=[28, 20], grain=[12, 8]),
        flt.masked_f3kdb(restr_dark, rad=21, thr=[36, 32], grain=[24, 12]),
        flt.masked_placebo(restr_dark, rad=6.5, thr=2.5, itr=2, grain=4)
    ])

    grain = vdf.noise.Graigasm(
        thrs=[x << 8 for x in (32, 80, 128, 176)],
        strengths=[(0.25, 0.0), (0.20, 0.0), (0.15, 0.0), (0.0, 0.0)],
        sizes=(1.20, 1.15, 1.10, 1),
        sharps=(80, 70, 60, 50),
        grainers=[
            vdf.noise.AddGrain(seed=69420, constant=True),
            vdf.noise.AddGrain(seed=69420, constant=False),
            vdf.noise.AddGrain(seed=69420, constant=False)
        ]).graining(deband)

    return grain
示例#14
0
    def _perform_motion_mask(clip: vs.VideoNode, brz: int)-> vs.VideoNode:
        clip = depth(clip, 8)
        sup = core.hqdn3d.Hqdn3d(clip).neo_fft3d.FFT3D().mv.Super(sharp=1)
        fv1 = core.mv.Analyse(sup, isb=False, delta=1, truemotion=False, dct=2)
        fv2 = core.mv.Analyse(sup, isb=True, delta=1, truemotion=True, dct=2)

        momask1 = core.mv.Mask(clip, fv1, ml=2, kind=1)
        momask2 = core.mv.Mask(clip, fv2, ml=3, kind=1)
        momask = core.std.Merge(momask1, momask2).rgvs.RemoveGrain(3).std.Binarize(brz)
        momask = momask.std.Minimum().std.Minimum()

        return depth(get_y(momask), 16)
示例#15
0
    def _nnedi3_supersample(clip: vs.VideoNode,
                            width: int,
                            height: int,
                            opencl: bool = True) -> vs.VideoNode:

        nnargs: Dict[str, Any] = dict(field=0, dh=True, nsize=0, nns=4, qual=2)
        _nnedi3 = nnedi3(opencl=opencl, **nnargs)
        up_y = _nnedi3(get_y(clip))
        up_y = up_y.resize.Spline36(height=height, src_top=0.5).std.Transpose()
        up_y = _nnedi3(up_y)
        up_y = up_y.resize.Spline36(height=width, src_top=0.5)
        return up_y
示例#16
0
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 = 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)
示例#17
0
def descale_detail_mask(clip: vs.VideoNode, rescaled_clip: vs.VideoNode,
                        threshold: float = 0.05) -> vs.VideoNode:
    """
    Generate a detail mask given a clip and a clip rescaled with the same
    kernel.

    Function is curried to allow parameter tuning when passing to :py:func:`lvsfunc.scale.descale`

    :param clip:           Original clip
    :param rescaled_clip:  Clip downscaled and reupscaled using the same kernel
    :param threshold:      Binarization threshold for mask (Default: 0.05)

    :return:               Mask of lost detail
    """
    check_variable(clip, "descale_detail_mask")
    check_variable(rescaled_clip, "descale_detail_mask")

    mask = core.std.Expr([get_y(clip), get_y(rescaled_clip)], 'x y - abs') \
        .std.Binarize(threshold)
    mask = iterate(mask, core.std.Maximum, 4)
    return iterate(mask, core.std.Inflate, 2)
示例#18
0
def do_filter():
    """Vapoursynth filtering"""

    def _fsrcnnx(clip: vs.VideoNode) -> vs.VideoNode:
        blank = core.std.BlankClip(clip, format=vs.GRAY16, color=128 << 8)
        clip = join([clip, blank, blank])
        # The chroma is upscaled with box AKA nearest but we don't care since we only need the luma.
        # It's especially faster and speed is the key :^)
        clip = core.placebo.Shader(clip, 'Shaders/FSRCNNX_x2_56-16-4-1.glsl', clip.width*2, clip.height*2, filter='box')
        return get_y(clip)

    def _nnedi(clip: vs.VideoNode) -> vs.VideoNode:
        args = dict(nsize=4, nns=4, qual=2, pscrn=2)
        clip = clip.std.Transpose().nnedi3.nnedi3(0, True, **args) \
            .std.Transpose().nnedi3.nnedi3(0, True, **args)
        return core.resize.Spline36(clip, src_top=.5, src_left=.5)

    def _rescale(clip: vs.VideoNode, thr: int, downscaler: Callable[[vs.VideoNode], vs.VideoNode]) -> vs.VideoNode:
        return downscaler(core.std.Merge(_nnedi(clip), _fsrcnnx(clip), thr))

    src = SRC_CUT

    fixedges = lvf.ef(src, [1, 1, 1])

    denoise = CoolDegrain(depth(fixedges, 16), tr=1, thsad=48, thsadc=84, blksize=8, overlap=4, plane=4)


    w, h = 1280, 720
    b, c = vdf.get_bicubic_params('robidoux')
    luma = get_y(denoise)
    descale = depth(core.descale.Debicubic(depth(luma, 32), w, h, b, c), 16)
    rescale = _rescale(descale, 0.55, lambda c: core.resize.Bicubic(c, src.width, src.height, filter_param_a=0, filter_param_b=0))

    line_mask = lvf.denoise.detail_mask(rescale, brz_a=7000, brz_b=2000)
    rescale = core.std.MaskedMerge(luma, rescale, line_mask)



    credit_mask = vdf.drm(luma, b=b, c=c, mode='ellipse', sw=3, sh=3)
    credit = core.std.MaskedMerge(rescale, luma, credit_mask)


    merged = vdf.merge_chroma(credit, denoise)


    deband_mask = lvf.denoise.detail_mask(merged, brz_a=3000, brz_b=1500)
    deband = dbs.f3kpf(merged, 17, 36, 36)
    deband = core.std.MaskedMerge(deband, merged, deband_mask)
    grain = core.neo_f3kdb.Deband(deband, preset='depth', grainy=32, output_depth=10,
                                  dither_algo=3, keep_tv_range=True)

    return grain
示例#19
0
def _eedi3_singlerate(clip: vs.VideoNode) -> vs.VideoNode:
    check_variable(clip, "_eedi3_singlerate")

    eeargs: Dict[str, Any] = dict(field=0,
                                  dh=False,
                                  alpha=0.2,
                                  beta=0.6,
                                  gamma=40,
                                  nrad=2,
                                  mdis=20)
    nnargs: Dict[str, Any] = dict(field=0, dh=False, nsize=0, nns=4, qual=2)
    y = get_y(clip)
    return eedi3(sclip=nnedi3(**nnargs)(y), **eeargs)(y)
示例#20
0
文件: scale.py 项目: noaione/n4ofunc
def _retinex_edgemask(src: vs.VideoNode, sigma: int = 1) -> vs.VideoNode:
    """
    Use retinex to greatly improve the accuracy of the edge detection in dark scenes.
    sigma is the sigma of tcanny

    From kagefunc.py, moved here so I don't need to import it.
    """
    luma = get_y(src)
    max_value = 1 if src.format.sample_type == vs.FLOAT else (
        1 << get_depth(src)) - 1
    ret = core.retinex.MSRCP(luma, sigma=[50, 200, 350], upper_thr=0.005)
    tcanny = ret.tcanny.TCanny(
        mode=1, sigma=sigma).std.Minimum(coordinates=[1, 0, 1, 0, 0, 1, 0, 1])
    return core.std.Expr([_kirsch(luma), tcanny], f"x y + {max_value} min")
示例#21
0
def test_descale(clip: vs.VideoNode,
                 width: Optional[int] = None,
                 height: int = 720,
                 kernel: kernels.Kernel = kernels.Bicubic(b=0, c=1 / 2),
                 show_error: bool = True) -> Tuple[vs.VideoNode, ScaleAttempt]:
    """
    Generic function to test descales with;
    descales and reupscales a given clip, allowing you to compare the two easily.
    Also returns a :py:class:`lvsfunc.scale.ScaleAttempt` with additional
    information.

    When comparing, it is recommended to do atleast a 4x zoom using Nearest Neighbor.
    I also suggest using 'compare' (:py:func:`lvsfunc.comparison.compare`),
    as that will make comparing the output with the source clip a lot easier.

    Some of this code was leveraged from DescaleAA found in fvsfunc.

    Dependencies:
    * vapoursynth-descale

    :param clip:           Input clip
    :param width:          Target descale width. If None, determine from `height`
    :param height:         Target descale height (Default: 720)
    :param kernel:         Kernel used to descale (see :py:class:`lvsfunc.kernels.Kernel`,
                           Default: kernels.Bicubic(b=0, c=1/2))
    :param show_error:     Render PlaneStatsDiff on the reupscaled frame (Default: True)

    :return: A tuple containing a clip re-upscaled with the same kernel and
             a ScaleAttempt tuple.
    """
    if clip.format is None:
        raise ValueError("test_descale: 'Variable-format clips not supported'")

    width = width or get_w(height, clip.width / clip.height)

    clip_y = depth(get_y(clip), 32)

    descale = _perform_descale(Resolution(width, height), clip_y, kernel)
    rescaled = depth(core.std.PlaneStats(descale.rescaled, clip_y),
                     get_depth(clip))

    if clip.format.num_planes == 1:
        rescaled = core.text.FrameProps(
            rescaled, "PlaneStatsDiff") if show_error else rescaled
    else:
        merge = core.std.ShufflePlanes([rescaled, clip], [0, 1, 2], vs.YUV)
        rescaled = core.text.FrameProps(
            merge, "PlaneStatsDiff") if show_error else merge

    return rescaled, descale
示例#22
0
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])
示例#23
0
def _aa_extra(clip: vs.VideoNode) -> vs.VideoNode:
    downscaler_fun = lambda x, wid, hei: \
        core.fmtc.resample(x, wid, hei, kernel='gauss', invks=True, invkstaps=2, taps=1, a1=32)
    luma = get_y(clip)
    antiaa = lvf.sraa(luma, 2, height=720)
    antiaa = TAAmbk(antiaa,
                    'Eedi3SangNom',
                    mtype=2,
                    alpha=0.75,
                    beta=0.2,
                    gamma=40,
                    aa=96)
    antiaa = lvf.sraa(antiaa, 2, height=clip.height, downscaler=downscaler_fun)
    return vdf.merge_chroma(antiaa, clip)
示例#24
0
def descale720(clip: vs.VideoNode,
               src: vs.VideoNode,
               ranges: List[Range] = []) -> vs.VideoNode:
    y = ldescale(vsutil.get_y(src),
                 upscaler=_sraa_reupscale,
                 height=720,
                 kernel=Bicubic(b=1 / 3, c=1 / 3),
                 threshold=0,
                 mask=_inverse_mask)
    scaled = core.std.ShufflePlanes([y, src],
                                    planes=[0, 1, 2],
                                    colorfamily=vs.YUV)
    scaled = replace_ranges(clip, scaled, ranges)
    return scaled
示例#25
0
def fineline_mask(clip: vs.VideoNode, thresh: int = 95) -> vs.VideoNode:
    """
    Generates a very fine mask for lineart protection. Not perfect yet

    The generated mask is GRAY8, keep this in mind for conversions.

    :param clip:        The clip to generate the mask for.
    :param thresh:      The threshold for the binarization step.
    """

    prew = core.std.Prewitt(clip, planes=[0])
    thin = core.std.Minimum(prew)

    yp, yt = get_y(prew), get_y(thin)

    maska = core.std.Expr([yp, yt], ["x y < y x ?"])

    bin_mask = core.std.Binarize(maska, threshold=thresh)
    bin_mask = depth(bin_mask, 8)

    redo = int(floor(thresh / 2.5) * 2)

    return core.std.Expr([bin_mask, maska], [f"x y < y x ? {redo} < 0 255 ?"])
示例#26
0
def transpose_aa(clip: vs.VideoNode,
                 eedi3: bool = False,
                 rep: int = 13) -> vs.VideoNode:
    """
    Function that performs anti-aliasing over a clip by using nnedi3/eedi3 and transposing multiple times.
    This results in overall stronger anti-aliasing.
    Useful for shows like Yuru Camp with bad lineart problems.

    Original function written by Zastin, modified by LightArrowsEXE.

    Dependencies:

    * RGSF (optional: 32 bit clip)
    * vapoursynth-EEDI3
    * vapoursynth-nnedi3
    * znedi3

    :param clip:      Input clip
    :param eedi3:     Use eedi3 for the interpolation (Default: False)
    :param rep:       Repair mode. Pass it 0 to not repair (Default: 13)

    :return:          Antialiased clip
    """
    check_variable(clip, "transpose_aa")
    assert clip.format

    clip_y = get_y(clip)

    def _aafun(clip: vs.VideoNode) -> vs.VideoNode:
        return clip.eedi3m.EEDI3(0, 1, 0, 0.5, 0.2).znedi3.nnedi3(1, 0, 0, 3, 4, 2) if eedi3 \
            else clip.nnedi3.nnedi3(0, 1, 0, 3, 3, 2).nnedi3.nnedi3(1, 0, 0, 3, 3, 2)

    def _taa(clip: vs.VideoNode) -> vs.VideoNode:
        aa = _aafun(clip.std.Transpose())
        aa = Catrom().scale(aa, clip.height, clip.width, shift=(0.5, 0))
        aa = _aafun(aa.std.Transpose())
        return Catrom().scale(aa, clip.width, clip.height, shift=(0.5, 0))

    def _csharp(flt: vs.VideoNode, clip: vs.VideoNode) -> vs.VideoNode:
        blur = core.std.Convolution(flt, [1] * 9)
        return core.std.Expr(
            [flt, clip, blur],
            'x y < x x + z - x max y min x x + z - x min y max ?')

    aaclip = _taa(clip_y)
    aaclip = _csharp(aaclip, clip_y)
    aaclip = pick_repair(clip_y)(aaclip, clip_y, rep)

    return aaclip if clip.format.color_family is vs.GRAY else core.std.ShufflePlanes(
        [aaclip, clip], [0, 1, 2], vs.YUV)
示例#27
0
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

    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

    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])
示例#28
0
def filterchain() -> Union[vs.VideoNode, Tuple[vs.VideoNode, ...]]:
    """Main filterchain"""
    import havsfunc as haf
    import lvsfunc as lvf
    import rekt
    import vardefunc as vdf
    from adptvgrnMod import adptvgrnMod
    from ccd import ccd
    from vsutil import depth, get_w, get_y

    src = JP_BD.clip_cut

    rkt = rekt.rektlvls(src, [0, 1079], [7, 7], [0, 1919], [7, 7],
                        prot_val=None)
    rkt = depth(rkt, 16)

    denoise_uv = ccd(rkt, threshold=7, matrix='709')
    stab = haf.GSMC(denoise_uv, radius=1, thSAD=200, planes=[0])
    decs = vdf.noise.decsiz(stab, sigmaS=8, min_in=208 << 8, max_in=232 << 8)

    l_mask = vdf.mask.FDOG().get_mask(get_y(decs), lthr=0.065,
                                      hthr=0.065).std.Maximum().std.Minimum()
    l_mask = l_mask.std.Median().std.Convolution([1] * 9)

    aa_weak = lvf.aa.taa(decs, lvf.aa.nnedi3(opencl=True))
    aa_strong = lvf.aa.upscaled_sraa(decs,
                                     downscaler=lvf.kernels.Bicubic(b=-1 / 2,
                                                                    c=1 /
                                                                    4).scale)
    aa_clamp = lvf.aa.clamp_aa(decs, aa_weak, aa_strong, strength=1.5)
    aa_masked = core.std.MaskedMerge(decs, aa_clamp, l_mask)

    dehalo = haf.FineDehalo(aa_masked,
                            rx=1.6,
                            ry=1.6,
                            darkstr=0,
                            brightstr=1.25)
    darken = flt.line_darkening(dehalo, 0.275).warp.AWarpSharp2(depth=2)

    deband = flt.masked_f3kdb(darken, rad=18, thr=32, grain=[32, 12])
    grain: vs.VideoNode = adptvgrnMod(deband,
                                      seed=42069,
                                      strength=0.35,
                                      luma_scaling=8,
                                      size=1.05,
                                      sharp=80,
                                      grain_chroma=False)

    return grain
示例#29
0
def eedi3_singlerate_custom(clip: vs.VideoNode) -> vs.VideoNode:
    import lvsfunc as lvf
    from vsutil import get_y

    eeargs: Dict[str, Any] = dict(field=0,
                                  dh=False,
                                  alpha=0.4,
                                  beta=0.6,
                                  gamma=30,
                                  nrad=2,
                                  mdis=30)
    nnargs: Dict[str, Any] = dict(field=0, dh=False, nsize=0, nns=4, qual=2)

    y = get_y(clip)
    return lvf.aa.eedi3(sclip=lvf.aa.nnedi3(**nnargs)(y), **eeargs)(y)
示例#30
0
def morpho_mask(clip: vs.VideoNode):
    # y, u, v = split(clip)
    y = get_y(clip)
    # stats = y.std.PlaneStats()
    # agm3 = core.adg.Mask(stats, 3)
    # agm6 = core.adg.Mask(stats, 6)

    ymax = maxm(y, sw=40, mode='ellipse')
    ymin = minm(y, sw=40, mode='ellipse')
    # umax = maxm(u, sw=16, mode='ellipse')
    # umin = minm(u, sw=16, mode='ellipse')
    # vmax = maxm(v, sw=12, mode='ellipse')
    # vmin = minm(v, sw=12, mode='ellipse')

    thr = 3.2 * 256
    ypw0 = y.std.Prewitt()
    ypw = ypw0.std.Binarize(thr).rgvs.RemoveGrain(11)

    rad = 3
    thr = 2.5 * 256
    yrangesml = core.std.Expr([ymax[3], ymin[3]], 'x y - abs')
    yrangesml = yrangesml.std.Binarize(thr).std.BoxBlur(0, 2, 1, 2, 1)

    rad = 16
    thr = 4 * 256
    yrangebig0 = core.std.Expr([ymax[rad], ymin[rad]], 'x y - abs')
    yrangebig = yrangebig0.std.Binarize(thr)
    yrangebig = minm(yrangebig,
                     sw=rad * 3 // 4,
                     threshold=65536 // ((rad * 3 // 4) + 1),
                     mode='ellipse')[-1]
    yrangebig = yrangebig.std.BoxBlur(0, rad // 4, 1, rad // 4, 1)

    rad = 30
    thr = 1 * 256
    ymph = core.std.Expr([
        y,
        maxm(ymin[rad], sw=rad, mode='ellipse')[rad],
        minm(ymax[rad], sw=rad, mode='ellipse')[rad]
    ], 'x y - z x - max')
    ymph = ymph.std.Binarize(384)
    ymph = ymph.std.Minimum().std.Maximum()
    ymph = ymph.std.BoxBlur(0, 4, 1, 4, 1)

    grad_mask = zzf.combine([ymph, yrangesml, ypw])
    # grain_mask = core.std.Expr([yrangebig, grad_mask, ypw0.std.Binarize(2000).std.Maximum().std.Maximum()], '65535 y - x min z -').std.BoxBlur(0,16,1,16,1)

    return grad_mask, yrangebig