Esempio n. 1
0
def quick_denoise(clip: vs.VideoNode,
                  ref: Optional[vs.VideoNode] = None,
                  cmode: str = 'knlm',
                  sigma: float = 2,
                  **kwargs: Any) -> vs.VideoNode:
    """
    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.

    A rewrite of my old 'quick_denoise'. I still hate it, but whatever.
    This will probably be removed in a future commit.

    BM3D is used for denoising the luma.

    Special thanks to kageru for helping me out with some ideas and pointers.

    Alias for this function is `lvsfunc.qden`.

    Dependencies: havsfunc (optional: SMDegrain mode), mvsfunc

    Deciphering havsfunc's dependencies is left as an excercise for the user.

    :param clip:         Input clip
    :param cmode:        Chroma denoising modes:
                          'knlm' - Use knlmeans for denoising the chroma (Default),
                          'tnlm' - Use tnlmeans for denoising the chroma,
                          'dft'  - Use dfttest for denoising the chroma (requires setting 'sbsize' in kwargs),
                          'smd'  - Use SMDegrain for denoising the chroma,
    :param sigma:        Denoising strength for BM3D (Default: 2)
    :param ref:          Optional reference clip to replace BM3D's basic estimate
    :param kwargs:       Parameters passed to chroma denoiser

    :return:             Denoised clip
    """
    try:
        import mvsfunc as mvf
    except ModuleNotFoundError:
        raise ModuleNotFoundError(
            "quick_denoise: missing dependency 'mvsfunc'")

    if clip.format is None or clip.format.color_family not in (vs.YUV,
                                                               vs.YCOCG,
                                                               vs.RGB):
        raise ValueError(
            "quick_denoise: input clip must be vs.YUV, vs.YCOCG, or vs.RGB")

    planes = split(clip)
    cmode = cmode.lower()

    if cmode in [1, 'knlm', 'knlmeanscl']:
        planes[1] = planes[1].knlm.KNLMeansCL(d=3, a=2, **kwargs)
        planes[2] = planes[2].knlm.KNLMeansCL(d=3, a=2, **kwargs)
    elif cmode in [2, 'tnlm', 'tnlmeans']:
        planes[1] = planes[1].tnlm.TNLMeans(ax=2, ay=2, az=2, **kwargs)
        planes[2] = planes[2].tnlm.TNLMeans(ax=2, ay=2, az=2, **kwargs)
    elif cmode in [3, 'dft', 'dfttest']:
        try:
            sbsize = cast(int, kwargs['sbsize'])
            planes[1] = planes[1].dfttest.DFTTest(sosize=int(sbsize * 0.75),
                                                  **kwargs)
            planes[2] = planes[2].dfttest.DFTTest(sosize=int(sbsize * 0.75),
                                                  **kwargs)
        except KeyError:
            raise ValueError("quick_denoise: '\"sbsize\" not specified'")
    elif cmode in [4, 'smd', 'smdegrain']:
        try:
            import havsfunc as haf
        except ModuleNotFoundError:
            raise ModuleNotFoundError(
                "quick_denoise: missing dependency 'havsfunc'")

        planes[1] = haf.SMDegrain(planes[1], prefilter=3, **kwargs)
        planes[2] = haf.SMDegrain(planes[2], prefilter=3, **kwargs)
    else:
        raise ValueError("quick_denoise: 'Unknown cmode'")

    ref = ref or planes[0]
    planes[0] = mvf.BM3D(planes[0], sigma=sigma, psample=0, radius1=1, ref=ref)
    return join(planes)
Esempio n. 2
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

    fixedge_a = awf.bbmod(out, 1, 1, 1, 1, 20, blur=700, u=False, v=False)

    fixedge_b = awf.FixRowBrightnessProtect2(out, 1077, -8)
    fixedge_b = awf.FixRowBrightnessProtect2(fixedge_b, 1078, 14)

    fixedge_c = awf.FixRowBrightnessProtect2(out, 1077, -15)
    fixedge_c = awf.FixRowBrightnessProtect2(fixedge_c, 1078, 4)

    fixedge = out
    fixedge = lvf.rfs(fixedge, fixedge_a, [(EDSTART + 309, EDEND)])
    fixedge = lvf.rfs(fixedge, fixedge_b, [(8114, 8191)])
    fixedge = lvf.rfs(fixedge, fixedge_c, [(9252, 9287)])
    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=4, bottom=6).resize.Bicubic(1920, 1080)
    resize = lvf.rfs(out, resize, [(24612, 24701)])
    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])
Esempio n. 3
0
def do_filter():
    """Vapoursynth filtering"""
    src = JPBD.src_cut
    # src += src[-1]
    src = depth(src, 16)
    out = src

    opstart, opend = 480, 2637
    edstart, edend = 32249, 34405



    # Remove the noise
    ref = hvf.SMDegrain(out, tr=1, thSAD=300, plane=4)
    denoise = mvf.BM3D(out, sigma=[2, 1], radius1=1, ref=ref)
    out = denoise




    # Limited antialiasing
    y = get_y(out)
    lineart = core.std.Sobel(y).std.Binarize(75<<8).std.Maximum().std.Inflate()
    aa = lvf.sraa(y, 2, 13, downscaler=partial(core.resize.Bicubic, filter_param_a=-0.5, filter_param_b=0.25))
    sharp = hvf.LSFmod(aa, strength=70, Smode=3, edgemode=0, source=y)


    y = core.std.MaskedMerge(y, sharp, lineart)
    out = vdf.merge_chroma(y, out)






    # Deband masks
    planes = split(out)

    preden = core.dfttest.DFTTest(out, sigma=14.0, sigma2=10.0, sbsize=1, sosize=0).rgvs.RemoveGrain(3)
    grad_mask, yrangebig = morpho_mask(preden)


    rgb = core.resize.Bicubic(preden, 960, 540, format=vs.RGB48).std.SetFrameProp('_Matrix', delete=True)
    chroma_masks = [core.std.Prewitt(p).std.Binarize(5500).rgvs.RemoveGrain(11) for p in split(rgb) + split(preden)[1:]]
    chroma_mask = core.std.Expr(chroma_masks, 'x y + z + a + b +').std.Maximum()
    chroma_mask = core.std.Merge(chroma_mask, chroma_mask.std.Minimum()).std.BoxBlur(0, 1, 1, 1, 1)

    fdogmask = vdf.edge_detect(preden.std.Median(), 'FDOG', 8250, (4, 1)).std.BoxBlur(0, 2, 1, 2, 1)
    detail_mask = lvf.denoise.detail_mask(planes[0].std.BoxBlur(0, 1, 1, 1, 1), brz_a=3300, brz_b=2000)


    # Debanding stages
    debands = [None] * 3
    deband_y_strong = dbs.f3kbilateral(planes[0], 16, 65)
    deband_y_normal = dumb3kdb(planes[0], 16, 36)
    deband_y_light = core.std.MaskedMerge(dumb3kdb(planes[0], 14, 32), planes[0], detail_mask)
    debands[1] = dbs.f3kbilateral(planes[1], 12, 50)
    debands[2] = dbs.f3kbilateral(planes[2], 12, 50)


    debands[0] = core.std.MaskedMerge(deband_y_strong, deband_y_normal, grad_mask)
    debands[0] = core.std.MaskedMerge(debands[0], deband_y_light, yrangebig)
    debands[1], debands[2] = [core.std.MaskedMerge(debands[i], planes[i], chroma_mask) for i in range(1, 3)]
    deband = join(debands)
    deband = lvf.rfs(deband, core.std.MaskedMerge(dbs.f3kbilateral(out, 20, 97), out, fdogmask), [(opstart+2019, opstart+2036), (opstart+1504, opstart+1574)])
    out = deband


    # Regraining
    ref = get_y(out).std.PlaneStats()
    adgmask_a = core.adg.Mask(ref, 25)
    adgmask_b = core.adg.Mask(ref, 10)

    stgrain_a = core.grain.Add(out, 0.1, 0, seed=333)
    stgrain_a = core.std.MaskedMerge(out, stgrain_a, adgmask_b.std.Invert())

    stgrain_b = sizedgrn(out, 0.2, 0.1, 1.15, sharp=80, seed=333)
    stgrain_b = core.std.MaskedMerge(out, stgrain_b, adgmask_b)
    stgrain_b = core.std.MaskedMerge(out, stgrain_b, adgmask_a.std.Invert())
    stgrain = core.std.MergeDiff(stgrain_b, out.std.MakeDiff(stgrain_a))

    dygrain = sizedgrn(out, 0.3, 0.1, 1.25, sharp=80, static=False, seed=333)
    dygrain = core.std.MaskedMerge(out, dygrain, adgmask_a)
    grain = core.std.MergeDiff(dygrain, out.std.MakeDiff(stgrain))
    out = grain



    # Credits OP and ED
    ref = src
    src_ncop, src_nced = [depth(c, 16) for c in [JPBD_NCOP.src_cut, JPBD_NCED.src_cut]]
    src_c, src_ncop, src_nced = [c.std.BoxBlur(0, 2, 1, 2, 1) for c in [src, src_ncop, src_nced]]

    opening_mask = vdf.dcm(out, src_c[opstart:opend+1], src_ncop[:opend-opstart+1], opstart, opend, 2, 2)
    ending_mask = vdf.dcm(out, src_c[edstart:edend+1], src_nced[:edend-edstart+1], edstart, edend, 2, 2)
    credit_mask = core.std.Expr([opening_mask, ending_mask], 'x y +').std.Inflate()

    credit = lvf.rfs(out, core.std.MaskedMerge(out, ref, credit_mask), [(opstart, opend), (edstart, edend)])
    out = credit





    # Fix letterboxes ending
    crop = core.std.Crop(out, 0, 0, 132, 132).edgefixer.ContinuityFixer(0, 1, 0, 0)
    crop = core.std.AddBorders(crop, 0, 0, 132, 132)
    out = lvf.rfs(out, crop, [(edstart, edend)])




    return depth(out, 10).std.Limiter(16<<2, [235<<2, 240<<2], [0, 1, 2])
Esempio n. 4
0
def upscaled_sraa(clip: vs.VideoNode,
                  rfactor: float = 1.5,
                  rep: Optional[int] = None,
                  h: Optional[int] = None,
                  ar: Optional[int] = None,
                  sharp_downscale: bool = False) -> vs.VideoNode:
    """
    Another AA written by Zastin and modified by LightArrowsEXE to perform
    an upscaled single-rate AA to deal with heavy aliasing.
    Useful for Web rips, where the source quality is not good enough to descale,
    but you still want to deal with some bad aliasing and lineart.

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

    :param clip:            Input clip
    :param rfactor:         Image enlargement factor. 1.3..2 makes it comparable in strength to vsTAAmbk.
                            It is not recommended to go below 1.3 (Default: 1.5)
    :param rep:             Repair mode (Default: None)
    :param h:               Set custom height. Width and aspect ratio are auto-calculated (Default: None)
    :param ar:              Force custom aspect ratio. Width is auto-calculated (Default: None)
    :param sharp_downscale: Use a sharper downscaling kernel (inverse gauss) (Default: False)

    :return:                Antialiased clip
    """
    planes = split(clip)

    nnargs = dict(nsize=0, nns=4, qual=2)
    eeargs = dict(alpha=0.2, beta=0.6, gamma=40, nrad=2,
                  mdis=20)  # TAAmbk defaults are 0.5, 0.2, 20, 3, 30

    ssw = round(clip.width * rfactor)
    ssh = round(clip.height * rfactor)

    while ssw % 2:
        ssw += 1
    while ssh % 2:
        ssh += 1

    if h:
        if not ar:
            ar = clip.width / clip.height
        w = get_w(h, aspect_ratio=ar)
    else:
        w, h = clip.width, clip.height

    # Nnedi3 upscale from source height to source height * rounding (Default 1.5)
    up_y = core.nnedi3.nnedi3(planes[0], 0, 1, 0, **nnargs)
    up_y = core.resize.Spline36(up_y, height=ssh, src_top=.5)
    up_y = core.std.Transpose(up_y)
    up_y = core.nnedi3.nnedi3(up_y, 0, 1, 0, **nnargs)
    up_y = core.resize.Spline36(up_y, height=ssw, src_top=.5)

    # Single-rate AA
    aa_y = core.eedi3m.EEDI3(up_y,
                             0,
                             0,
                             0,
                             **eeargs,
                             sclip=core.nnedi3.nnedi3(up_y, 0, 0, 0, **nnargs))
    aa_y = core.std.Transpose(aa_y)
    aa_y = core.eedi3m.EEDI3(aa_y,
                             0,
                             0,
                             0,
                             **eeargs,
                             sclip=core.nnedi3.nnedi3(aa_y, 0, 0, 0, **nnargs))

    # Back to source clip height or given height
    scaled = core.fmtc.resample(
        aa_y, w, h, kernel='gauss', invks=True, invkstaps=2, taps=1,
        a1=32) if sharp_downscale else core.resize.Spline36(aa_y, w, h)

    if rep:
        scaled = util.pick_repair(scaled)(scaled,
                                          planes[0].resize.Spline36(w, h), rep)
    return scaled if clip.format.color_family is vs.GRAY else core.std.ShufflePlanes(
        [scaled, clip], [0, 1, 2], vs.YUV)
Esempio n. 5
0
def do_filter():
    """Vapoursynth filtering"""
    def _fsrcnnx(clip: vs.VideoNode, width: int, height: int) -> vs.VideoNode:
        blank = core.std.BlankClip(clip, format=vs.GRAY16, color=128 << 8)
        clip = join([clip, blank, blank])
        clip = core.placebo.Shader(clip, 'FSRCNNX_x2_56-16-4-1.glsl',
                                   clip.width * 2, clip.height * 2)
        return core.resize.Spline36(get_y(clip), width, height)

    src = SRC_CUT

    fe = lvf.ef(src, [1, 1, 1])
    fe = depth(fe, 16)

    h = 864
    w = get_w(864)
    b, c = 0, 1 / 2
    luma = get_y(fe)
    descale = core.descale.Debicubic(depth(luma, 32), w, h, b, c)
    descale = depth(descale, 16)

    rescale_a = nnedi3_rpow2(descale,
                             2,
                             src.width,
                             src.height,
                             nns=4,
                             qual=2,
                             pscrn=2)
    rescale_b = _fsrcnnx(descale, src.width, src.height)
    rescale = core.std.Merge(rescale_a, rescale_b, 0.75)

    rescale_mask = vrf.drm(fe, 864, b=b, c=c, mthr=80, sw=4, sh=4)
    rescale = core.std.MaskedMerge(rescale, luma, rescale_mask)

    rescale = lvf.rfs(rescale, luma, [(OPSTART + 483, OPSTART + 721),
                                      (OPSTART + 822, OPSTART + 1083)])
    merge = core.std.ShufflePlanes([rescale, fe], [0, 1, 2], vs.YUV)

    antialias = join([lvf.sraa(plane) for plane in split(merge)])
    antialias = lvf.rfs(merge, antialias, [(2836, 2870)])

    denoise = core.knlm.KNLMeansCL(antialias,
                                   a=2,
                                   h=0.65,
                                   d=0,
                                   device_type='gpu',
                                   channels='UV')

    preden = CoolDegrain(denoise,
                         tr=2,
                         thsad=60,
                         blksize=8,
                         overlap=4,
                         plane=4)
    diff = core.std.MakeDiff(denoise, preden)
    deband_mask = lvf.denoise.detail_mask(preden, brz_a=3000, brz_b=1500)

    deband_a = dbs.f3kpf(preden, 17, 42, 42)
    deband_b = core.placebo.Deband(preden,
                                   radius=17,
                                   threshold=6,
                                   iterations=1,
                                   grain=0,
                                   planes=1 | 2 | 4)
    deband = lvf.rfs(deband_a, deband_b, [(2081, 2216), (2450, 2550),
                                          (3418, 3452), (3926, 3926)])

    deband = core.std.MaskedMerge(deband, preden, deband_mask)
    deband = core.std.MergeDiff(deband, diff)

    grain = kgf.adaptive_grain(deband, 0.25, luma_scaling=8)
    final = depth(grain, 10)

    return final
Esempio n. 6
0
def do_filter():
    """Vapoursynth filtering"""
    src = JPBD.src_cut
    src = depth(src, 16)
    out = src

    # Remove the noise
    ref = hvf.SMDegrain(out, tr=1, thSAD=300, plane=4)
    denoise = mvf.BM3D(out, sigma=[2, 1], radius1=1, ref=ref)
    out = denoise

    # Limited antialiasing
    y = get_y(out)
    lineart = core.std.Sobel(y).std.Binarize(
        75 << 8).std.Maximum().std.Inflate()
    aa = lvf.sraa(y,
                  2,
                  13,
                  downscaler=partial(core.resize.Bicubic,
                                     filter_param_a=-0.5,
                                     filter_param_b=0.25))
    sharp = hvf.LSFmod(aa, strength=70, Smode=3, edgemode=0, source=y)

    y = core.std.MaskedMerge(y, sharp, lineart)
    out = vdf.merge_chroma(y, out)

    # Deband masks
    planes = split(out)

    preden = core.dfttest.DFTTest(out,
                                  sigma=14.0,
                                  sigma2=10.0,
                                  sbsize=1,
                                  sosize=0,
                                  planes=[0, 1, 2]).rgvs.RemoveGrain(3)
    grad_mask, yrangebig = morpho_mask(preden)

    rgb = core.resize.Bicubic(preden, 960, 540,
                              format=vs.RGB48).std.SetFrameProp('_Matrix',
                                                                delete=True)
    chroma_masks = [
        core.std.Prewitt(p).std.Binarize(5500).rgvs.RemoveGrain(11)
        for p in split(rgb) + split(preden)[1:]
    ]
    chroma_mask = core.std.Expr(chroma_masks,
                                'x y + z + a + b +').std.Maximum()
    chroma_mask = core.std.Merge(chroma_mask,
                                 chroma_mask.std.Minimum()).std.BoxBlur(
                                     0, 1, 1, 1, 1)

    detail_mask = lvf.denoise.detail_mask(planes[0].std.BoxBlur(0, 1, 1, 1, 1),
                                          brz_a=3300,
                                          brz_b=2000)

    # Debanding stages
    debands = [None] * 3
    deband_y_strong = dbs.f3kbilateral(planes[0], 16, 65)
    deband_y_normal = dumb3kdb(planes[0], 16, 41)
    deband_y_light = core.std.MaskedMerge(dumb3kdb(planes[0], 14, 32),
                                          planes[0], detail_mask)
    debands[1] = dbs.f3kbilateral(planes[1], 12, 50)
    debands[2] = dbs.f3kbilateral(planes[2], 12, 50)

    debands[0] = core.std.MaskedMerge(deband_y_strong, deband_y_normal,
                                      grad_mask)
    debands[0] = core.std.MaskedMerge(debands[0], deband_y_light, yrangebig)
    debands[1], debands[2] = [
        core.std.MaskedMerge(debands[i], planes[i], chroma_mask)
        for i in range(1, 3)
    ]
    deband = join(debands)
    out = deband

    # Regraining
    ref = get_y(out).std.PlaneStats()
    adgmask_a = core.adg.Mask(ref, 25)
    adgmask_b = core.adg.Mask(ref, 10)

    stgrain_a = core.grain.Add(out, 0.1, 0, seed=333)
    stgrain_a = core.std.MaskedMerge(out, stgrain_a, adgmask_b.std.Invert())

    stgrain_b = sizedgrn(out, 0.2, 0.1, 1.15, sharp=80, seed=333)
    stgrain_b = core.std.MaskedMerge(out, stgrain_b, adgmask_b)
    stgrain_b = core.std.MaskedMerge(out, stgrain_b, adgmask_a.std.Invert())
    stgrain = core.std.MergeDiff(stgrain_b, out.std.MakeDiff(stgrain_a))

    dygrain = sizedgrn(out, 0.3, 0.1, 1.25, sharp=80, static=False, seed=333)
    dygrain = core.std.MaskedMerge(out, dygrain, adgmask_a)
    grain = core.std.MergeDiff(dygrain, out.std.MakeDiff(stgrain))
    out = grain

    return depth(out, 10).std.Limiter(16 << 2, [235 << 2, 240 << 2], [0, 1, 2])
Esempio n. 7
0
def sraa(clip: vs.VideoNode,
         rfactor: list[float] = [1.5, 1.5, 1.5],
         planes: list[int] = [0, 1, 2]) -> vs.VideoNode:
    from typing import Callable
    from lvsfunc.aa import upscaled_sraa
    from vsutil import get_y, split, join, get_w
    from functools import partial

    if isinstance(rfactor, float): rfactor = [rfactor, rfactor, rfactor]

    def nnedi3(opencl: bool = True,
               **override: Any) -> Callable[[vs.VideoNode], vs.VideoNode]:

        nnedi3_args: Dict[str, Any] = dict(field=0,
                                           dh=True,
                                           nsize=3,
                                           nns=3,
                                           qual=1)
        nnedi3_args.update(override)

        def _nnedi3(clip: vs.VideoNode) -> vs.VideoNode:
            return clip.nnedi3cl.NNEDI3CL(**nnedi3_args) if opencl \
                else clip.nnedi3.nnedi3(**nnedi3_args)

        return _nnedi3

    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

    def eedi3(opencl: bool = True,
              **override: Any) -> Callable[[vs.VideoNode], vs.VideoNode]:

        eedi3_args: Dict[str, Any] = dict(field=0,
                                          dh=True,
                                          alpha=0.25,
                                          beta=0.5,
                                          gamma=40,
                                          nrad=2,
                                          mdis=20)
        eedi3_args.update(override)

        def _eedi3(clip: vs.VideoNode) -> vs.VideoNode:
            return clip.eedi3m.EEDI3CL(**eedi3_args) if opencl \
                else clip.eedi3m.EEDI3(**eedi3_args)

        return _eedi3

    def _eedi3_singlerate(clip: vs.VideoNode,
                          opencl: bool = False) -> vs.VideoNode:
        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, opencl=opencl)(y)

    planar = split(clip)

    if 0 in planes:
        planar[0] = upscaled_sraa(planar[0],
                                  rfactor=rfactor[0],
                                  supersampler=partial(_nnedi3_supersample,
                                                       opencl=True),
                                  aafun=partial(_eedi3_singlerate,
                                                opencl=True))
    if 1 in planes:
        planar[1] = upscaled_sraa(planar[1],
                                  rfactor=rfactor[1],
                                  supersampler=partial(_nnedi3_supersample,
                                                       opencl=False),
                                  aafun=partial(_eedi3_singlerate,
                                                opencl=False))
    if 2 in planes:
        planar[2] = upscaled_sraa(planar[2],
                                  rfactor=rfactor[2],
                                  supersampler=partial(_nnedi3_supersample,
                                                       opencl=False),
                                  aafun=partial(_eedi3_singlerate,
                                                opencl=False))

    return join(planar)
Esempio n. 8
0
 def test_split_join(self):
     planes = vsutil.split(self.BLACK_SAMPLE_CLIP)
     self.assertEqual(len(planes), 3)
     self.assert_same_metadata(self.BLACK_SAMPLE_CLIP, vsutil.join(planes))
Esempio n. 9
0
def do_filter():
    """Vapoursynth filtering"""
    scene_change = []
    with open('k.log') as file:
        lines = file.readlines()
        for line in lines:
            line = line.split()
            scene_change.append(int(line[0]))

    src = CLIP_SRC

    # Lol?
    border = awf.bbmod(src, 4, thresh=128, blur=15, y=True, u=True, v=True)
    border = lvf.ef(border, [6, 3, 3], radius=[12, 6, 6])
    border = lvf.rfs(src, border, scene_change)
    out = depth(border, 16)

    # joletb has stronk eyes
    planes = split(out)
    planes[1], planes[2] = [
        core.resize.Spline16(plane, src_top=-0.25) for plane in planes[1:]
    ]
    out = join(planes)

    # qual=2 produces weird artefacts and a stronger alpha/beta/gamma smudges details.
    new_fields = core.eedi3m.EEDI3(out,
                                   1,
                                   alpha=0.25,
                                   beta=0.3,
                                   gamma=400,
                                   nrad=3,
                                   mdis=20,
                                   vcheck=3,
                                   sclip=core.nnedi3.nnedi3(out,
                                                            1,
                                                            nsize=3,
                                                            nns=3,
                                                            qual=1,
                                                            pscrn=4))
    out = new_fields

    # omegartifacted frames
    def freeze_frame_after(clip, frame):
        return core.std.FreezeFrames(clip, frame, frame, frame + 1)

    def freeze_frame_before(clip, frame):
        return core.std.FreezeFrames(clip, frame, frame, frame - 1)

    cursed_frames = [
        2326, 8907, 12211, 12551, 13990, 14403, 15462, 17673, 19382, 23099,
        23738, 24031, 24802, 25083
    ]
    for cursed_frame in cursed_frames:
        out = freeze_frame_after(out, cursed_frame)
    cursed_frames = [5695, 9115, 9116, 17671, 18432]
    for cursed_frame in cursed_frames:
        out = freeze_frame_before(out, cursed_frame)

    # omegartifacted frames ²
    denoise_li = hvf.SMDegrain(out, thSAD=200)
    denoise_hi = hvf.SMDegrain(out, thSAD=350)
    denoise = lvf.rfs(denoise_li, denoise_hi, scene_change)

    def hard_denoise(clip):
        clip = hvf.SMDegrain(clip, thSAD=500)
        clip = knlm_denoise(clip, (2, 2), dict(a=8))
        return clip

    cursed_frames = [
        595, 1191, 2643, 2663, 2664, 2665, 2666, 2667, 2671, 2672, 2674, 2675,
        2679, 3999, 4419, 6351, 6355, 6547, 8906, 11731, 14176, 14177, 14178,
        14179, 18430, 18435, 18437, 18438, 18439, 27766
    ]
    cursed_frames += range(10767, 10776)
    cursed_frames += range(25013, 25018)
    cursed_frames += range(27663, 27668)
    cursed_frames += range(29642, 29646)
    cursed_frames += range(31384, 31388)

    uncursed = hard_denoise(out)
    denoise = lvf.rfs(denoise, uncursed, cursed_frames)
    out = denoise

    # It helps to fix the the aliasing left
    antialias = lvf.sraa(out, rep=13)
    out = antialias

    # Compensative line darkening and sharpening
    luma = get_y(out)
    darken = hvf.Toon(luma, 0.20)
    darken_mask = core.std.Expr([
        core.std.Convolution(
            luma, [5, 10, 5, 0, 0, 0, -5, -10, -5], divisor=4, saturate=False),
        core.std.Convolution(
            luma, [5, 0, -5, 10, 0, -10, 5, 0, -5], divisor=4, saturate=False)
    ], [
        'x y max {neutral} / 0.86 pow {peak} *'.format(
            neutral=1 << (luma.format.bits_per_sample - 1),
            peak=(1 << luma.format.bits_per_sample) - 1)
    ])
    darken = core.std.MaskedMerge(luma, darken, darken_mask)

    # Slight sharp through CAS
    sharp = hvf.LSFmod(darken,
                       strength=65,
                       Smode=3,
                       Lmode=1,
                       edgemode=1,
                       edgemaskHQ=True)
    out = vdf.merge_chroma(sharp, out)

    # Chroma planes are pure crap
    chromableed = xvs.WarpFixChromaBlend(out, 96, depth=8)
    out = chromableed

    detail_mask = lvf.denoise.detail_mask(out, brz_a=2700, brz_b=1500)
    deband = placebo.deband(out, 17, 5.75, grain=4)
    deband_b = placebo.deband(out, 24, 8, 2, grain=4)
    deband_c = placebo.deband(out, 17, 8, grain=4)
    deband_d = placebo.deband(out, 20, 12, 3, grain=4)

    deband = lvf.rfs(deband, deband_b, [(4596, 4669), (23036, 23098)])
    deband = lvf.rfs(deband, deband_c, [(1646, 1711), (29768, 29840),
                                        (29932, 30037), (30163, 30243)])
    deband = lvf.rfs(deband, deband_d, [(1712, 1830)])

    deband = core.std.MaskedMerge(deband, out, detail_mask)
    out = deband

    return depth(out, 10)
Esempio n. 10
0
    For 4:2:0 subsampled clips, the two half-sized planes will be stacked in the opposite direction specified
    (vertical by default),
    then stacked with the full-sized plane in the direction specified (horizontal by default).

    :param clip:           Input clip (must be in YUV or RGB planar format)
    :param stack_vertical: Stack the planes vertically (Default: ``False``)

    :return:               Clip with stacked planes
    """
    if clip.format is None:
        raise ValueError("stack_planes: variable-format clips not allowed")
    if clip.format.num_planes != 3:
        raise ValueError(
            "stack_planes: input clip must be in YUV or RGB planar format")

    split_planes = vsutil.split(clip)

    if clip.format.color_family == vs.ColorFamily.YUV:
        planes: Dict[str, vs.VideoNode] = {
            'Y': split_planes[0],
            'U': split_planes[1],
            'V': split_planes[2]
        }
    elif clip.format.color_family == vs.ColorFamily.RGB:
        planes = {
            'R': split_planes[0],
            'G': split_planes[1],
            'B': split_planes[2]
        }
    else:
        raise ValueError(
def sizedgrn(clip,
             strength=0.25,
             cstrength=None,
             size=1,
             sharp=50,
             static=False,
             grain_chroma=True,
             grainer=None,
             fade_edges=True,
             tv_range=True,
             lo=None,
             hi=None,
             protect_neutral=True,
             seed=-1):
    dpth = get_depth(clip)
    neutral = 1 << (get_depth(clip) - 1)

    def m4(x):
        return 16 if x < 16 else math.floor(x / 4 + 0.5) * 4

    cw = clip.width  # ox
    ch = clip.height  # oy

    sx = m4(cw / size) if size != 1 else cw
    sy = m4(ch / size) if size != 1 else ch
    sxa = m4((cw + sx) / 2)
    sya = m4((ch + sy) / 2)
    b = sharp / -50 + 1
    c = (1 - b) / 2
    if cstrength is None and grain_chroma:
        cstrength = .5 * strength
    elif cstrength != 0 and cstrength is not None and not grain_chroma:
        raise ValueError(
            "cstrength must be None or 0 if grain_chroma is False!")
    elif cstrength is None and not grain_chroma:
        cstrength = 0

    blank = core.std.BlankClip(clip,
                               sx,
                               sy,
                               color=[neutral for i in split(clip)])
    if grainer is None:
        grained = core.grain.Add(blank,
                                 var=strength,
                                 uvar=cstrength,
                                 constant=static,
                                 seed=seed)
    else:
        grained = grainer(blank)
    if size != 1 and (sx != cw or sy != ch):
        if size > 1.5:
            grained = core.resize.Bicubic(grained,
                                          sxa,
                                          sya,
                                          filter_param_a=b,
                                          filter_param_b=c)
        grained = core.resize.Bicubic(grained,
                                      cw,
                                      ch,
                                      filter_param_a=b,
                                      filter_param_b=c)

    if fade_edges:
        if isinstance(hi, int) and len(hi) == 2:
            hi = hi + hi[1]
        if lo:
            lo = lo << (dpth - 8)
        if hi:
            hi = [_ << (dpth - 8) for _ in hi]
        if tv_range:
            if not lo:
                lo = 16 << (dpth - 8)
            if not hi:
                hi = [235 << (dpth - 8)] + 2 * [240 << (dpth - 8)]
        else:
            if not lo:
                lo = 0
            if not hi:
                hi = 3 * [(1 << dpth) - 1]
        limit_expr = "x y {0} - abs - {1} < x y {0} - abs + {2} > or x y {0} - x + ?"
        grained = core.std.Expr([clip, grained], [
            limit_expr.format(neutral, lo, hi[_])
            for _ in range(0, clip.format.num_planes)
        ])
        if protect_neutral and (grain_chroma or cstrength > 0
                                ) and clip.format.color_family == vs.YUV:
            max_value = round(3 * cstrength) << (dpth - 8)
            neutral_mask = core.std.Expr(
                split(depth(clip.resize.Bilinear(format=vs.YUV444P16), dpth)),
                "x {0} <= x {1} >= or y {2} - abs {3} <= and z {2} - abs {3} <= and {4} {5} ?"
                .format(lo + max_value, hi[1] - max_value, neutral, max_value,
                        (1 << dpth) - 1, 0))
            grained = core.std.MaskedMerge(grained,
                                           clip,
                                           neutral_mask,
                                           planes=[1, 2])
    else:
        grained = core.std.MergeDiff(clip, grained)
    return grained
Esempio n. 12
0
def OP(op_in: vs.VideoNode) -> vs.VideoNode:
    src = op_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=0.75, mthr=0.30)
    # 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
Esempio n. 13
0
def deband(clip: vs.VideoNode,
           radius: float = 16.0,
           threshold: Union[float, List[float]] = 4.0,
           iterations: int = 1,
           grain: Union[float, List[float]] = 6.0,
           chroma: bool = True,
           **kwargs) -> vs.VideoNode:
    """Wrapper for placebo.Deband
       https://github.com/Lypheo/vs-placebo#vs-placebo

    Args:
        clip (vs.VideoNode): Source clip.

        radius (float, optional):
            The debanding filter's initial radius. The radius increases linearly for each iteration.
            A higher radius will find more gradients, but a lower radius will smooth more aggressively.
            Defaults to 16.0.

        threshold (Union[float, List[float]], optional):
            The debanding filter's cut-off threshold.
            Higher numbers increase the debanding strength dramatically,
            but progressively diminish image details. Defaults to 4.0.

        iterations (int, optional):
            The number of debanding steps to perform per sample. Each step reduces a bit more banding,
            but takes time to compute. Note that the strength of each step falls off very quickly,
            so high numbers (>4) are practically useless. Defaults to 1.

        grain (Union[float, List[float]], optional):
            Add some extra noise to the image.
            This significantly helps cover up remaining quantization artifacts.
            Higher numbers add more noise.

            Note: When debanding HDR sources, even a small amount of grain can result
            in a very big change to the brightness level.
            It's recommended to either scale this value down or disable it entirely for HDR.
            Defaults to 6.0, which is very mild.

        chroma (bool, optional): Process chroma planes or not.
            Defaults to True if the input clip has chroma planes.

    Returns:
        vs.VideoNode: Debanded clip.
    """
    if chroma and clip.format.num_planes > 1:
        threshold = [threshold] * 3 if isinstance(
            threshold,
            float) else threshold + [threshold[-1]] * (3 - len(threshold))
        grain = [grain] * 3 if isinstance(
            grain, float) else grain + [grain[-1]] * (3 - len(grain))

        planes = split(clip)

        for i, (thr, gra) in enumerate(zip(threshold, grain)):
            planes[i] = planes[i].placebo.Deband(1, iterations, thr, radius,
                                                 gra, **kwargs)
        clip = join(planes)
    else:
        clip = clip.placebo.Deband(1, iterations, threshold, radius, grain,
                                   **kwargs)

    return clip
Esempio n. 14
0
def do_filter():
    """Vapoursynth filtering"""
    src = JPBD.src_cut
    src = depth(src, 32)
    out = src

    full_range = core.resize.Bicubic(out,
                                     range_in=0,
                                     range=1,
                                     dither_type='error_diffusion')
    out = full_range

    radius = 3
    y, u, v = split(out)

    y_m = core.resize.Point(y, 960, 1080, src_left=-1)
    y_m = core.resize.Bicubic(y_m, 960, 540)

    def demangle(clip):
        return vdf.nnedi3_upscale(clip, pscrn=0,
                                  correct_shift=False).resize.Spline16(
                                      src_left=0.5 + 0.25, src_top=.5)

    y_m, u, v = map(demangle, (y_m, u, v))

    y_fixup = core.std.MakeDiff(y, y_m)
    yu, yv = Regress(y_m, u, v, radius=radius)

    u_fixup = ReconstructMulti(y_fixup, yu, radius=radius)
    u_r = core.std.MergeDiff(u, u_fixup)

    v_fixup = ReconstructMulti(y_fixup, yv, radius=radius)
    v_r = core.std.MergeDiff(v, v_fixup)

    out = join([y, u_r, v_r])
    out = depth(out, 16)

    dehalo = gf.MaskedDHA(out,
                          rx=1.25,
                          ry=1.25,
                          darkstr=0.10,
                          brightstr=1.0,
                          maskpull=46,
                          maskpush=148)
    out = dehalo

    upscale = atf.eedi3Scale(out, 2160, pscrn=0)
    out = upscale

    dehalo = gf.MaskedDHA(out,
                          rx=1.15,
                          ry=1.15,
                          darkstr=0.10,
                          brightstr=1.0,
                          maskpull=46,
                          maskpush=148)
    out = dehalo

    deband_mask = lvf.denoise.detail_mask(out, brz_a=2000, brz_b=1000)
    deband = dbs.f3kpf(out, 28, 48, 48)
    deband = core.std.MaskedMerge(deband, out, deband_mask)
    out = deband

    grain = core.grain.Add(out, 1)
    out = grain

    return out.std.AssumeFPS(fpsnum=1, fpsden=1)
Esempio n. 15
0
def do_filter():
    """Vapoursynth filtering"""
    src = CLIP_SRC
    out = depth(src, 16)

    clip = out
    clip = core.std.FreezeFrames(clip, 1432, 1433, 1434)
    clip = core.std.FreezeFrames(clip, 1503, 1514, 1515)
    out = clip

    planes = split(out)
    planes[1], planes[2] = [
        core.resize.Spline16(plane, src_left=-0.25) for plane in planes[1:]
    ]
    out = join(planes)

    # qual=2 produces weird artefacts and a stronger alpha/beta/gamma smudges details.
    new_fields = core.eedi3m.EEDI3(out,
                                   1,
                                   alpha=0.4,
                                   beta=0.5,
                                   gamma=300,
                                   nrad=3,
                                   mdis=20,
                                   vcheck=3,
                                   sclip=core.nnedi3.nnedi3(out,
                                                            1,
                                                            nsize=3,
                                                            nns=3,
                                                            qual=1,
                                                            pscrn=4))
    out = new_fields

    denoise = gf.MCDegrainSharp(
        out,
        tr=3,
        bblur=0.65,
        csharp=lambda x: hvf.LSFmod(
            x, strength=85, Smode=3, Lmode=1, edgemode=0),
        thSAD=285,
        rec=True)
    out = denoise

    edge_cleaner = hvf.EdgeCleaner(out, 35, rmode=13, smode=1, hot=True)
    out = edge_cleaner

    antialias = lvf.sraa(out,
                         2,
                         13,
                         downscaler=core.resize.Bicubic,
                         alpha=0.25,
                         beta=0.35,
                         gamma=400)
    antialias_a = lvf.sraa(out, 1.4, 9, downscaler=core.resize.Bicubic)
    antialias = lvf.rfs(antialias, antialias_a, [(1223, 1229)])
    out = antialias

    chromableed = xvs.WarpFixChromaBlend(out, 72, depth=8)
    out = chromableed

    detail_mask = lvf.denoise.detail_mask(out, brz_a=2300, brz_b=1000)
    deband = placebo.deband(out, 17, 4.25, grain=6)
    deband_a = placebo.deband(out, 17, 8, 2, grain=6)
    deband_b = placebo.deband(out, 17, 6, grain=6)
    deband = lvf.rfs(deband, deband_a, [(1230, 1330)])
    deband = lvf.rfs(deband, deband_b, [(1678, 1889)])

    deband = core.std.MaskedMerge(deband, out, detail_mask)
    out = deband

    return depth(out, 10)