Beispiel #1
0
    def __init__(self, clip, strength=0, down8=False, **args):
        super(AAEedi3, self).__init__(clip, strength, down8)
        self.eedi3_args = {
            'alpha': args.get('alpha', 0.5),
            'beta': args.get('beta', 0.2),
            'gamma': args.get('gamma', 20),
            'nrad': args.get('nrad', 3),
            'mdis': args.get('mdis', 30)
        }

        self.opencl = args.get('opencl', False)
        if self.opencl is True:
            try:
                self.eedi3 = self.core.eedi3m.EEDI3CL
                self.eedi3_args['device'] = args.get('opencl_device', 0)
            except AttributeError:
                self.eedi3 = self.core.eedi3.eedi3
                if self.process_depth > 8:
                    self.clip = mvf.Depth(self.clip, 8)
        else:
            try:
                self.eedi3 = self.core.eedi3m.EEDI3
            except AttributeError:
                self.eedi3 = self.core.eedi3.eedi3
                if self.process_depth > 8:
                    self.clip = mvf.Depth(self.clip, 8)
Beispiel #2
0
def BernsteinFilter(clip, iter=30, **depth_args):
    """Bernstein Filter

    Bernstein filter is an efficient filter solver, which can implicitly minimize the mean curvature.

    Internal precision is always float.

    Args:
        clip: Input.

        iter: (int) Num of iterations. Default is 30

        depth_args: (dict) Additional arguments passed to mvf.Depth() in the form of keyword arguments.
            Default is {}.

    Ref:
        [1] Gong, Y. (2016, March). Bernstein filter: A new solver for mean curvature regularized models. In Acoustics, Speech and Signal Processing (ICASSP), 2016 IEEE International Conference on (pp. 1701-1705). IEEE.

    """

    bits = clip.format.bits_per_sample
    sample = clip.format.sample_type

    clip = mvf.Depth(clip, depth=32, sample=vs.FLOAT, **depth_args)

    for i in range(iter):
        d1 = core.std.Convolution(clip, [1, -2, 1], divisor=2, mode='h')
        d2 = core.std.Convolution(clip, [1, -2, 1], divisor=2, mode='v')
        clip = core.std.Expr([clip, d1, d2], ['y abs z abs < x y + x z + ?'])

    return mvf.Depth(clip, depth=bits, sample=sample, **depth_args)
Beispiel #3
0
def Wiener2(input, radius_v=3, radius_h=None, noise=None, **depth_args):
    """2-D adaptive noise-removal filtering. (wiener2 from MATLAB)

    Wiener2 lowpass filters an intensity image that has been degraded by constant power additive noise.
    Wiener2 uses a pixel-wise adaptive Wiener method based on statistics estimated from a local neighborhood of each pixel.

    Estimate of the additive noise power will not be returned.

    Args:
        input: Input clip. Only the first plane will be processed.

        radius_v, radius_h: (int) Size of neighborhoods to estimate the local image mean and standard deviation. The size is (radius_v*2-1) * (radius_h*2-1).
            If "radius_h" is None, it will be set to "radius_v".
            Default is 3.

        noise: (float) Variance of addictive noise. If it is not given, average of all the local estimated variances will be used.
            Default is {}.

        depth_args: (dict) Additional arguments passed to mvf.Depth() in the form of keyword arguments.
            Default is {}.

    Ref:
        [1] Lim, J. S. (1990). Two-dimensional signal and image processing. Englewood Cliffs, NJ, Prentice Hall, 1990, 710 p, p. 538, equations 9.26, 9.27, and 9.29.
        [2] 2-D adaptive noise-removal filtering - MATLAB wiener2 - MathWorks (https://www.mathworks.com/help/images/ref/wiener2.html)

    """

    core = vs.get_core()
    funcName = 'Wiener2'

    if not isinstance(input, vs.VideoNode) or input.format.num_planes > 1:
        raise TypeError(funcName + ': \"input\" must be a gray-scale/single channel clip!')

    bits = input.format.bits_per_sample
    sampleType = input.format.sample_type

    if radius_h is None:
        radius_h = radius_v

    input32 = mvf.Depth(input, depth=32, sample=vs.FLOAT, **depth_args)

    localMean = muf.BoxFilter(input32, radius_h+1, radius_v+1)
    localVar = muf.BoxFilter(core.std.Expr([input32], ['x dup *']), radius_h+1, radius_v+1)
    localVar = core.std.Expr([localVar, localMean], ['x y dup * -'])

    if noise is None:
        localVarStats = core.std.PlaneStats(localVar, plane=[0])

        def FLT(n, f, clip, core, localMean, localVar):
            noise = f.props.PlaneStatsAverage

            return core.std.Expr([clip, localMean, localVar], ['y z {noise} - 0 max z {noise} max / x y - * +'.format(noise=noise)])

        flt = core.std.FrameEval(input32, functools.partial(FLT, clip=input32, core=core, localMean=localMean, localVar=localVar), prop_src=[localVarStats])
    else:
        flt = core.std.Expr([input32, localMean, localVar], ['y z {noise} - 0 max z {noise} max / x y - * +'.format(noise=noise)])

    return mvf.Depth(flt, depth=bits, sample=sampleType, **depth_args)
Beispiel #4
0
 def out(self):
     aaed = self.core.fmtc.resample(self.clip, self.clip_width, self.uph4, kernel="spline64")
     aaed = mvf.Depth(aaed, self.process_depth)
     aaed = self.core.sangnom.SangNom(aaed, aa=self.aa)
     aaed = self.core.std.Transpose(self.resize(aaed, self.clip_width, self.clip_height, 0))
     aaed = self.core.fmtc.resample(aaed, self.clip_height, self.upw4, kernel="spline64")
     aaed = mvf.Depth(aaed, self.process_depth)
     aaed = self.core.sangnom.SangNom(aaed, aa=self.aa)
     aaed = self.core.std.Transpose(self.resize(aaed, self.clip_height, self.clip_width, 0))
     return aaed
def SSR(clip, sigma=50, full=None, **args):
    """Single-scale Retinex

    Args:
        clip: Input. Only the first plane will be processed.

        sigma: (int) Standard deviation of gaussian blur. Default is 50.

        full: (bool) Whether input clip is of full range. Default is None.

    Ref:
        [1] Jobson, D. J., Rahman, Z. U., & Woodell, G. A. (1997). Properties and performance of a center/surround retinex. IEEE transactions on image processing, 6(3), 451-462.

    """

    bits = clip.format.bits_per_sample
    sampleType = clip.format.sample_type
    isGray = clip.format.color_family == vs.GRAY

    if not isGray:
        clip_src = clip
        clip = mvf.GetPlane(clip)

    lowFre = gauss(clip, sigma=sigma, **args)

    clip = mvf.Depth(clip, 32, fulls=full)
    lowFre = mvf.Depth(
        lowFre, 32,
        fulls=full)  # core.bilateral.Gaussian() doesn't support float input.

    expr = 'x 1 + log y 1 + log -'
    clip = core.std.Expr([clip, lowFre], [expr])

    stats = core.std.PlaneStats(clip, plane=[0])

    # Dynamic range stretching
    def Stretch(n, f, clip, core):
        alpha = f.props['PlaneStatsMax'] - f.props['PlaneStatsMin']
        beta = f.props['PlaneStatsMin']

        expr = 'x {beta} - {alpha} /'.format(beta=beta, alpha=alpha)
        return core.std.Expr([clip], [expr])

    clip = core.std.FrameEval(clip,
                              functools.partial(Stretch, clip=clip, core=core),
                              prop_src=stats)

    clip = mvf.Depth(clip, depth=bits, sample=sampleType, fulld=full)

    if not isGray:
        clip = core.std.ShufflePlanes([clip, clip_src],
                                      list(range(clip_src.format.num_planes)),
                                      clip_src.format.color_family)

    return clip
Beispiel #6
0
 def out(self):
     aa_spline64 = self.core.fmtc.resample(self.clip, self.upw4, self.uph4, kernel='spline64')
     aa_spline64 = mvf.Depth(aa_spline64, self.process_depth)
     aa_gaussian = self.core.fmtc.resample(self.clip, self.upw4, self.uph4, kernel='gaussian', a1=100)
     aa_gaussian = mvf.Depth(aa_gaussian, self.process_depth)
     aaed = self.core.rgvs.Repair(aa_spline64, aa_gaussian, 1)
     aaed = self.core.sangnom.SangNom(aaed, aa=self.aa)
     aaed = self.core.std.Transpose(aaed)
     aaed = self.core.sangnom.SangNom(aaed, aa=self.aa)
     aaed = self.core.std.Transpose(aaed)
     aaed = self.resize(aaed, self.clip_width, self.clip_height, shift=0)
     return aaed
Beispiel #7
0
 def __init__(self, clip):
     super(MaskParent, self).__init__(clip)
     if clip.format.color_family is not vs.GRAY:
         self.clip = self.core.std.ShufflePlanes(self.clip, 0, vs.GRAY)
     self.clip = mvf.Depth(self.clip, 8)  # Mask will always be processed in 8bit scale
     self.mask = None
     self.multi = ((1 << self.clip_bits) - 1) // 255
Beispiel #8
0
def mask_lthresh(clip, mthrs, lthreshes, mask_kernel, inexpand, **kwargs):
    core = vs.get_core()
    gray8 = mvf.Depth(clip, 8) if clip.format.bits_per_sample != 8 else clip
    gray8 = core.std.ShufflePlanes(
        gray8, 0, vs.GRAY) if clip.format.color_family != vs.GRAY else gray8
    mthrs = mthrs if isinstance(mthrs, (list, tuple)) else [mthrs]
    lthreshes = lthreshes if isinstance(lthreshes,
                                        (list, tuple)) else [lthreshes]
    inexpand = inexpand if isinstance(
        inexpand, (list, tuple)) and len(inexpand) >= 2 else [inexpand, 0]

    mask_kernels = [mask_kernel(mthr, **kwargs) for mthr in mthrs]
    masks = [kernel(gray8) for kernel in mask_kernels]
    mask = ((len(mthrs) - len(lthreshes) == 1) and functools.reduce(
        lambda x, y: core.std.Expr([x, y, gray8], 'z %d < x y ?' % lthreshes[
            masks.index(y) - 1]), masks)) or masks[0]
    mask = [mask] + [core.std.Maximum] * inexpand[0]
    mask = functools.reduce(lambda x, y: y(x), mask)
    mask = [mask] + [core.std.Minimum] * inexpand[1]
    mask = functools.reduce(lambda x, y: y(x), mask)

    bps = clip.format.bits_per_sample
    mask = (bps > 8 and core.std.Expr(
        mask, 'x %d *' % (((1 << clip.format.bits_per_sample) - 1) // 255),
        eval('vs.GRAY' + str(bps)))) or mask
    return lambda clip_a, clip_b, show=False: (
        show is False and core.std.MaskedMerge(clip_a, clip_b, mask)) or mask
Beispiel #9
0
 def resize(self, clip, w, h, shift):
     try:
         resized = self.core.resize.Spline36(clip, w, h, src_top=shift)
     except vs.Error:
         resized = self.core.fmtc.resample(clip, w, h, sy=shift)
         if resized.format.bits_per_sample != self.process_depth:
             mvf.Depth(resized, self.process_depth)
     return resized
Beispiel #10
0
 def output(self, aaed):
     if self.process_depth != self.clip_bits:
         return mvf.LimitFilter(self.clip,
                                mvf.Depth(aaed, self.clip_bits),
                                thr=1.0,
                                elast=2.0)
     else:
         return aaed
Beispiel #11
0
 def out(self):
     aaed = self.eedi3(self.clip, field=1, dh=True, **self.eedi3_args)
     aaed = self.resize(aaed, self.dw, self.clip_height, shift=-0.5)
     aaed = self.core.std.Transpose(aaed)
     aaed = self.eedi3(aaed, field=1, dh=True, **self.eedi3_args)
     aaed = self.resize(aaed, self.clip_height, self.clip_width, shift=-0.5)
     aaed = self.core.std.Transpose(aaed)
     aaed_bits = aaed.format.bits_per_sample
     return aaed if aaed_bits == self.process_depth else mvf.Depth(aaed, self.process_depth)
Beispiel #12
0
def camp(src):
    src16 = core.fmtc.bitdepth(src, bits=16)

    src_rgb = mvf.ToRGB(src16,depth=32)
    nr16_rgb = core.pdn.BM3DBasic(src_rgb, sigma=[0.5, 0.2, 0.2])
    nr16 = mvf.ToYUV(nr16_rgb, css="420",depth=16)
    noise16 = core.std.MakeDiff(src16, nr16)

    pre16 = core.std.ShufflePlanes([nr16,src16],[0,1,2],vs.YUV)
    pre8 = mvf.Depth(pre16, depth=8, dither=5)

    eemask = core.tcanny.TCanny(pre8,sigma=0.6,op=2,gmmax=255,planes=[0,1,2],mode=1)
    eemask_u = core.std.ShufflePlanes(eemask, [1,1,1], vs.YUV).fmtc.resample(1920,1080,sx=0.25,css="420")
    eemask_v = core.std.ShufflePlanes(eemask, [2,2,2], vs.YUV).fmtc.resample(1920,1080,sx=0.25,css="420")
    weighted = core.std.Expr([eemask,eemask_u,eemask_v],["x 64 * y + z +",""],vs.YUV420P16)

    luma = core.std.ShufflePlanes(pre8, 0, vs.YUV).resize.Bilinear(format=vs.YUV420P8)
    eemask = core.std.Expr([eemask,luma],["x x * 20 * 255 y - dup * 0.2 * + 50000 min","x x * 30 * 255 y - dup * 0.3 * + 60000 min"],vs.YUV420P16)
    eemask = core.std.Maximum(eemask,planes=[0,1,2])
    eemask = core.rgvs.RemoveGrain(eemask, [20,11]).rgvs.RemoveGrain([20,11]).rgvs.RemoveGrain([20,11])

    aamask = core.std.Binarize(weighted, 8000, 0)
    Y = core.std.ShufflePlanes(src16, 0, vs.YUV).resize.Bicubic(1920, 1080, format=vs.YUV420P16, filter_param_a=0, filter_param_b=0.5)
    U = core.std.ShufflePlanes(src16, [1,1,1], vs.YUV).resize.Bicubic(1920, 1080, format=vs.YUV420P16, filter_param_a=0, filter_param_b=0.5)
    V = core.std.ShufflePlanes(src16, [2,2,2], vs.YUV).resize.Bicubic(1920, 1080, format=vs.YUV420P16, filter_param_a=0, filter_param_b=0.5)
    textmask0 = core.std.Expr([Y,U,V], ["x 60000 > y 32768 - abs 768 < and z 32768 - abs 768 < and 65535 0 ?","0"])
    #textmasks = core.std.Expr([Y,U,V], ["x 58000 > y 32768 - abs 512 < and z 32768 - abs 512 < and 65535 0 ?","0"])
    textmask1 = core.std.Minimum(textmask0, 0).std.Minimum(planes=0).std.Minimum(planes=0).std.Maximum(0).std.Maximum(0).std.Maximum(0)
    textmask2 = core.misc.Hysteresis(textmask1, textmask0, planes=0)
    textmask = core.std.Expr([textmask0, textmask2], "x y > x 0 ?")
    #textmask = core.misc.Hysteresis(textmasks, textmaskb, planes=0)
    textmask = core.std.Maximum(textmask,0).std.Maximum(0).std.Maximum(0)#.std.Maximum(0)#.std.Maximum(0)#.std.Maximum(0)#.std.Minimum(0)

    debd = bbf.deband_2pass(nr16)

    w  = 1920
    h  = 1080
    oaa_y = core.std.ShufflePlanes(nr16, 0, vs.GRAY)

    aa_y = core.eedi2.EEDI2(oaa_y,field=1,mthresh=10,lthresh=20,vthresh=20,maxd=24,nt=50).fmtc.resample(w,h,sy=-0.5, kernel='bicubic', a1=0, a2=0.5,).std.Transpose()
    aa_y = core.eedi2.EEDI2(aa_y,field=1,mthresh=10,lthresh=20,vthresh=20,maxd=24,nt=50).fmtc.resample(h,w,sy=-0.5, kernel='bicubic', a1=0, a2=0.5,).std.Transpose()

    aa_clip = core.std.ShufflePlanes([aa_y,debd], [0,1,2], vs.YUV)
    aaed = core.std.MaskedMerge(debd, aa_clip, aamask, 0, True)
    aaed = core.std.MaskedMerge(aaed, debd, textmask, 0, False)

    dif = core.std.MakeDiff(aaed, core.rgvs.RemoveGrain(aaed,20))
    sharp = core.std.MergeDiff(aaed, dif)
    sharped = core.std.MaskedMerge(sharp, aaed, eemask, [0,1,2], False)

    noise16 = core.std.Expr(noise16,["x 32768 - 1.05 * 32768 +",""])
    nullclip = core.std.Expr(src16,["32768",""])
    nrweight = core.std.Expr(pre8, ["x 48 - 0 max dup * 5 * ",""], vs.YUV420P16)
    noise16 = core.std.MaskedMerge(noise16,nullclip,nrweight,0,True)
    res = core.std.MergeDiff(sharped,noise16,0)

    return res
def retinex_edgemask(src: vs.VideoNode, sigma=1, draft=False) -> vs.VideoNode:
    core = vs.core
    import mvsfunc as mvf
    src = mvf.Depth(src, 16)
    luma = mvf.GetPlane(src, 0)
    if draft:
        ret = core.std.Expr(luma, 'x 65535 / sqrt 65535 *')
    else:
        ret = core.retinex.MSRCP(luma, sigma=[50, 200, 350], upper_thr=0.005)
    mask = core.std.Expr([
        kirsch(luma),
        ret.tcanny.TCanny(mode=1, sigma=sigma).std.Minimum(
            coordinates=[1, 0, 1, 0, 0, 1, 0, 1])
    ], 'x y +')
    return mask
Beispiel #14
0
import sys
sys.path.append("/usr/local/share/vsscripts")

import vapoursynth as vs
import math

core = vs.get_core(threads=20)
import mvsfunc as mvf
import havsfunc as haf
import CSMOD as cs
ret = core.lsmas.LWLibavSource(
    source=
    "/opt/How.to.Train.Your.Dragon.The.Hidden.World.2019.1080p.BluRay.x264.TrueHD.7.1.Atmos-FGT.mkv",
    format="YUV420P16")  #
#ret = core.ffms2.Source(source=r'H:\115download\509 Blood Money\BDMV\STREAM\00000.m2ts')
#ret = core.std.CropRel(ret, left=0,  right=0, top=138, bottom=138)

ret = mvf.Depth(ret, depth=16)
ret = haf.SMDegrain(input=ret, tr=3,
                    contrasharp=30)  # plane=3  ,contrasharp=30

# ret = core.knlm.KNLMeansCL(clip=ret,d = 1, a = 4, h = 2,device_type="cpu")
# ret = mvf.BM3D(ret, sigma=[10,10,10], radius1=1)

# ret =cs.CSMOD(ret,preset = "medium",strength=16)#, edgemode=1
ret = haf.LSFmod(ret, strength=10)
# ret = core.f3kdb.Deband(ret,output_depth=16) #

ret = mvf.Depth(ret, depth=10)
ret.set_output()
Beispiel #15
0
def nnedi3_resample(input,
                    target_width=None,
                    target_height=None,
                    src_left=None,
                    src_top=None,
                    src_width=None,
                    src_height=None,
                    csp=None,
                    mats=None,
                    matd=None,
                    cplaces=None,
                    cplaced=None,
                    fulls=None,
                    fulld=None,
                    curves=None,
                    curved=None,
                    sigmoid=None,
                    scale_thr=None,
                    nsize=None,
                    nns=None,
                    qual=None,
                    etype=None,
                    pscrn=None,
                    opt=None,
                    int16_prescreener=None,
                    int16_predictor=None,
                    exp=None,
                    kernel=None,
                    invks=False,
                    taps=None,
                    invkstaps=3,
                    a1=None,
                    a2=None,
                    chromak_up=None,
                    chromak_up_taps=None,
                    chromak_up_a1=None,
                    chromak_up_a2=None,
                    chromak_down=None,
                    chromak_down_invks=False,
                    chromak_down_invkstaps=3,
                    chromak_down_taps=None,
                    chromak_down_a1=None,
                    chromak_down_a2=None,
                    opencl=False,
                    device=-1):
    core = vs.get_core()
    funcName = 'nnedi3_resample'

    # Get property about input clip
    if not isinstance(input, vs.VideoNode):
        raise TypeError(funcName + ': This is not a clip!')

    sFormat = input.format

    sColorFamily = sFormat.color_family
    if sColorFamily == vs.COMPAT:
        raise ValueError(
            funcName +
            ': Color family *COMPAT* of input clip is not supported!')
    sIsGRAY = sColorFamily == vs.GRAY
    sIsYUV = sColorFamily == vs.YUV or sColorFamily == vs.YCOCG
    sIsRGB = sColorFamily == vs.RGB

    sbitPS = sFormat.bits_per_sample

    sHSubS = 1 << sFormat.subsampling_w
    sVSubS = 1 << sFormat.subsampling_h
    sIsSubS = sHSubS > 1 or sVSubS > 1

    sPlaneNum = sFormat.num_planes

    # Get property about output clip
    dFormat = sFormat if csp is None else core.get_format(csp)

    dColorFamily = dFormat.color_family
    if dColorFamily == vs.COMPAT:
        raise ValueError(
            funcName +
            ': Color family *COMPAT* of output clip is not supported!')
    dIsGRAY = dColorFamily == vs.GRAY
    dIsYUV = dColorFamily == vs.YUV or dColorFamily == vs.YCOCG
    dIsRGB = dColorFamily == vs.RGB

    dbitPS = dFormat.bits_per_sample

    dHSubS = 1 << dFormat.subsampling_w
    dVSubS = 1 << dFormat.subsampling_h
    dIsSubS = dHSubS > 1 or dVSubS > 1

    dPlaneNum = dFormat.num_planes

    # Parameters of format
    SD = input.width <= 1024 and input.height <= 576
    HD = input.width <= 2048 and input.height <= 1536

    if mats is None:
        mats = "601" if SD else "709" if HD else "2020"
    else:
        mats = mats.lower()
    if matd is None:
        matd = mats
    else:
        matd = matd.lower()
        # Matrix of output clip makes sense only if dst is not of RGB
        if dIsRGB:
            matd = mats
        # Matrix of input clip makes sense only src is not of GRAY or RGB
        if sIsGRAY or sIsRGB:
            mats = matd
    if cplaces is None:
        if sHSubS == 4:
            cplaces = 'dv'
        else:
            cplaces = 'mpeg2'
    else:
        cplaces = cplaces.lower()
    if cplaced is None:
        if dHSubS == 4:
            cplaced = 'dv'
        else:
            cplaced = cplaces
    else:
        cplaced = cplaced.lower()
    if fulls is None:
        fulls = sColorFamily == vs.YCOCG or sColorFamily == vs.RGB
    if fulld is None:
        if dColorFamily == sColorFamily:
            fulld = fulls
        else:
            fulld = dColorFamily == vs.YCOCG or dColorFamily == vs.RGB
    if curves is None:
        curves = 'linear'
    else:
        curves = curves.lower()
    if curved is None:
        curved = curves
    else:
        curved = curved.lower()
    if sigmoid is None:
        sigmoid = False

    # Parameters of scaling
    if target_width is None:
        target_width = input.width
    if target_height is None:
        target_height = input.height
    if src_left is None:
        src_left = 0
    if src_top is None:
        src_top = 0
    if src_width is None:
        src_width = input.width
    elif src_width <= 0:
        src_width = input.width - src_left + src_width
    if src_height is None:
        src_height = input.height
    elif src_height <= 0:
        src_height = input.height - src_top + src_height
    if scale_thr is None:
        scale_thr = 1.125

    src_right = src_width - input.width + src_left
    src_bottom = src_height - input.height + src_top

    hScale = target_width / src_width
    vScale = target_height / src_height

    # Parameters of nnedi3
    if nsize is None:
        nsize = 0
    if nns is None:
        nns = 3
    if qual is None:
        qual = 2

    # Parameters of fmtc.resample
    if kernel is None:
        if not invks:
            kernel = 'spline36'
        else:
            kernel = 'bilinear'
    else:
        kernel = kernel.lower()
    if chromak_up is None:
        chromak_up = 'nnedi3'
    else:
        chromak_up = chromak_up.lower()
    if chromak_up == 'softcubic':
        chromak_up = 'bicubic'
        if chromak_up_a1 is None:
            chromak_up_a1 = 75
        chromak_up_a1 = chromak_up_a1 / 100
        chromak_up_a2 = 1 - chromak_up_a1
    if chromak_down is None:
        chromak_down = 'bicubic'
    else:
        chromak_down = chromak_down.lower()
    if chromak_down == 'softcubic':
        chromak_down = 'bicubic'
        if chromak_down_a1 is None:
            chromak_down_a1 = 75
        chromak_down_a1 = chromak_down_a1 / 100
        chromak_down_a2 = 1 - chromak_down_a1

    # Procedure decision
    hIsScale = hScale != 1
    vIsScale = vScale != 1
    isScale = hIsScale or vIsScale
    hResample = hIsScale or int(src_left) != src_left or int(
        src_right) != src_right
    vResample = vIsScale or int(src_top) != src_top or int(
        src_bottom) != src_bottom
    resample = hResample or vResample
    hReSubS = dHSubS != sHSubS
    vReSubS = dVSubS != sVSubS
    reSubS = hReSubS or vReSubS
    sigmoid = sigmoid and resample
    sGammaConv = curves != 'linear'
    dGammaConv = curved != 'linear'
    gammaConv = (sGammaConv or dGammaConv or sigmoid) and (resample
                                                           or curved != curves)
    scaleInGRAY = sIsGRAY or dIsGRAY
    scaleInYUV = not scaleInGRAY and mats == matd and not gammaConv and (
        reSubS or (sIsYUV and dIsYUV))
    scaleInRGB = not scaleInGRAY and not scaleInYUV
    # If matrix conversion or gamma correction is applied, scaling will be done in RGB. Otherwise, if at least one of input&output clip
    # is RGB and no chroma subsampling is involved, scaling will be done in RGB.

    # Chroma placement relative to the frame center in luma scale
    sCLeftAlign = cplaces == 'mpeg2' or cplaces == 'dv'
    sHCPlace = 0 if not sCLeftAlign else 0.5 - sHSubS / 2
    sVCPlace = 0
    dCLeftAlign = cplaced == 'mpeg2' or cplaced == 'dv'
    dHCPlace = 0 if not dCLeftAlign else 0.5 - dHSubS / 2
    dVCPlace = 0

    # Convert depth to 16-bit
    last = mvf.Depth(input, depth=16, fulls=fulls)

    # Color space conversion before scaling
    if scaleInGRAY and sIsYUV:
        if mats != matd:
            last = core.fmtc.matrix(last,
                                    mats=mats,
                                    matd=matd,
                                    fulls=fulls,
                                    fulld=fulld,
                                    col_fam=vs.GRAY,
                                    singleout=0)
        last = core.std.ShufflePlanes(last, [0], vs.GRAY)
    elif scaleInGRAY and sIsRGB:
        # Matrix conversion for output clip of GRAY
        last = core.fmtc.matrix(last,
                                mat=matd,
                                fulls=fulls,
                                fulld=fulld,
                                col_fam=vs.GRAY,
                                singleout=0)
        fulls = fulld
    elif scaleInRGB and sIsYUV:
        # Chroma upsampling
        if sIsSubS:
            if chromak_up == 'nnedi3':
                # Separate planes
                Y = core.std.ShufflePlanes(last, [0], vs.GRAY)
                U = core.std.ShufflePlanes(last, [1], vs.GRAY)
                V = core.std.ShufflePlanes(last, [2], vs.GRAY)
                # Chroma up-scaling
                U = nnedi3_resample_kernel(
                    U, Y.width, Y.height, -sHCPlace / sHSubS,
                    -sVCPlace / sVSubS, None, None, 1, nsize, nns, qual, etype,
                    pscrn, opt, int16_prescreener, int16_predictor, exp,
                    kernel, taps, a1, a2, opencl, device)
                V = nnedi3_resample_kernel(
                    V, Y.width, Y.height, -sHCPlace / sHSubS,
                    -sVCPlace / sVSubS, None, None, 1, nsize, nns, qual, etype,
                    pscrn, opt, int16_prescreener, int16_predictor, exp,
                    kernel, taps, a1, a2, opencl, device)
                # Merge planes
                last = core.std.ShufflePlanes([Y, U, V], [0, 0, 0],
                                              last.format.color_family)
            else:
                last = core.fmtc.resample(last,
                                          kernel=chromak_up,
                                          taps=chromak_up_taps,
                                          a1=chromak_up_a1,
                                          a2=chromak_up_a2,
                                          css="444",
                                          fulls=fulls,
                                          cplaces=cplaces)
        # Matrix conversion
        if mats == '2020cl':
            last = core.fmtc.matrix2020cl(last, fulls)
        else:
            last = core.fmtc.matrix(last,
                                    mat=mats,
                                    fulls=fulls,
                                    fulld=True,
                                    col_fam=vs.RGB,
                                    singleout=-1)
        fulls = True
    elif scaleInYUV and sIsRGB:
        # Matrix conversion
        if matd == '2020cl':
            last = core.fmtc.matrix2020cl(last, fulld)
        else:
            last = core.fmtc.matrix(last,
                                    mat=matd,
                                    fulls=fulls,
                                    fulld=fulld,
                                    col_fam=vs.YUV,
                                    singleout=-1)
        fulls = fulld

    # Scaling
    if scaleInGRAY or scaleInRGB:
        if gammaConv and sGammaConv:
            last = GammaToLinear(last, fulls, fulls, curves, sigmoid=sigmoid)
        elif sigmoid:
            last = SigmoidInverse(last)
        last = nnedi3_resample_kernel(last, target_width, target_height,
                                      src_left, src_top, src_width, src_height,
                                      scale_thr, nsize, nns, qual, etype,
                                      pscrn, opt, int16_prescreener,
                                      int16_predictor, exp, kernel, taps, a1,
                                      a2, invks, invkstaps, opencl, device)
        if gammaConv and dGammaConv:
            last = LinearToGamma(last, fulls, fulls, curved, sigmoid=sigmoid)
        elif sigmoid:
            last = SigmoidDirect(last)
    elif scaleInYUV:
        # Separate planes
        Y = core.std.ShufflePlanes(last, [0], vs.GRAY)
        U = core.std.ShufflePlanes(last, [1], vs.GRAY)
        V = core.std.ShufflePlanes(last, [2], vs.GRAY)
        # Scale Y
        Y = nnedi3_resample_kernel(Y, target_width, target_height, src_left,
                                   src_top, src_width, src_height, scale_thr,
                                   nsize, nns, qual, etype, pscrn, opt,
                                   int16_prescreener, int16_predictor, exp,
                                   kernel, taps, a1, a2, opencl, device)
        # Scale UV
        dCw = target_width // dHSubS
        dCh = target_height // dVSubS
        dCsx = ((src_left - sHCPlace) * hScale + dHCPlace) / hScale / sHSubS
        dCsy = ((src_top - sVCPlace) * vScale + dVCPlace) / vScale / sVSubS
        dCsw = src_width / sHSubS
        dCsh = src_height / sVSubS
        U = nnedi3_resample_kernel(U, dCw, dCh, dCsx, dCsy, dCsw, dCsh,
                                   scale_thr, nsize, nns, qual, etype, pscrn,
                                   opt, int16_prescreener, int16_predictor,
                                   exp, kernel, taps, a1, a2, opencl, device)
        V = nnedi3_resample_kernel(V, dCw, dCh, dCsx, dCsy, dCsw, dCsh,
                                   scale_thr, nsize, nns, qual, etype, pscrn,
                                   opt, int16_prescreener, int16_predictor,
                                   exp, kernel, taps, a1, a2, opencl, device)
        # Merge planes
        last = core.std.ShufflePlanes([Y, U, V], [0, 0, 0],
                                      last.format.color_family)

    # Color space conversion after scaling
    if scaleInGRAY and dIsYUV:
        dCw = target_width // dHSubS
        dCh = target_height // dVSubS
        last = mvf.Depth(last, depth=dbitPS, fulls=fulls, fulld=fulld)
        blkUV = core.std.BlankClip(last, dCw, dCh, color=[1 << (dbitPS - 1)])
        last = core.std.ShufflePlanes([last, blkUV, blkUV], [0, 0, 0],
                                      dColorFamily)
    elif scaleInGRAY and dIsRGB:
        last = mvf.Depth(last, depth=dbitPS, fulls=fulls, fulld=fulld)
        last = core.std.ShufflePlanes([last, last, last], [0, 0, 0],
                                      dColorFamily)
    elif scaleInRGB and dIsYUV:
        # Matrix conversion
        if matd == '2020cl':
            last = core.fmtc.matrix2020cl(last, fulld)
        else:
            last = core.fmtc.matrix(last,
                                    mat=matd,
                                    fulls=fulls,
                                    fulld=fulld,
                                    col_fam=dColorFamily,
                                    singleout=-1)
        # Chroma subsampling
        if dIsSubS:
            dCSS = '411' if dHSubS == 4 else '420' if dVSubS == 2 else '422'
            last = core.fmtc.resample(last,
                                      kernel=chromak_down,
                                      taps=chromak_down_taps,
                                      a1=chromak_down_a1,
                                      a2=chromak_down_a2,
                                      css=dCSS,
                                      fulls=fulld,
                                      cplaced=cplaced,
                                      invks=chromak_down_invks,
                                      invkstaps=chromak_down_invkstaps,
                                      planes=[2, 3, 3])
        last = mvf.Depth(last, depth=dbitPS, fulls=fulld)
    elif scaleInYUV and dIsRGB:
        # Matrix conversion
        if mats == '2020cl':
            last = core.fmtc.matrix2020cl(last, fulls)
        else:
            last = core.fmtc.matrix(last,
                                    mat=mats,
                                    fulls=fulls,
                                    fulld=True,
                                    col_fam=vs.RGB,
                                    singleout=-1)
        last = mvf.Depth(last, depth=dbitPS, fulls=True, fulld=fulld)
    else:
        last = mvf.Depth(last, depth=dbitPS, fulls=fulls, fulld=fulld)

    # Output
    return last
Beispiel #16
0
def mask_fadetxt(clip,
                 lthr=225,
                 cthr=(2, 2),
                 expand=2,
                 fade_num=(5, 5),
                 apply_range=None):
    core = vs.get_core()
    if clip.format.color_family != vs.YUV:
        raise TypeError(MODULE_NAME +
                        ': fadetxt mask: only yuv clips are supported.')
    w = clip.width
    h = clip.height
    bps = clip.format.bits_per_sample
    ceil = (1 << bps) - 1
    neutral = 1 << (bps - 1)
    frame_count = clip.num_frames

    yuv = [
        core.std.ShufflePlanes(clip, i, vs.GRAY)
        for i in range(clip.format.num_planes)
    ]
    try:
        yuv444 = [
            core.resize.Bicubic(plane, w, h, src_left=0.25)
            if yuv.index(plane) > 0 else plane for plane in yuv
        ]
    except vs.Error:
        yuv444 = [
            mvf.Depth(core.fmtc.resample(plane, w, h, sx=0.25), 8)
            if yuv.index(plane) > 0 else plane for plane in yuv
        ]
    cthr_u = cthr if not isinstance(cthr, (list, tuple)) else cthr[0]
    cthr_v = cthr if not isinstance(cthr, (list, tuple)) else cthr[1]
    expr = 'x %d > y %d - abs %d < and z %d - abs %d < and %d 0 ?' % (
        lthr, neutral, cthr_u, neutral, cthr_v, ceil)
    mask = core.std.Expr(yuv444, expr)
    mask = [mask] + [core.std.Maximum] * expand
    mask = functools.reduce(lambda x, y: y(x), mask)

    if fade_num is not 0:

        def shift_backward(n, mask_clip, num):
            return mask_clip[frame_count -
                             1] if n + num > frame_count - 1 else mask_clip[
                                 n + num]

        def shift_forward(n, mask_clip, num):
            return mask_clip[0] if n - num < 0 else mask_clip[n - num]

        fade_in_num = fade_num if not isinstance(fade_num,
                                                 (list,
                                                  tuple)) else fade_num[0]
        fade_out_num = fade_num if not isinstance(fade_num,
                                                  (list,
                                                   tuple)) else fade_num[1]
        fade_in = core.std.FrameEval(
            mask,
            functools.partial(shift_backward, mask_clip=mask, num=fade_in_num))
        fade_out = core.std.FrameEval(
            mask,
            functools.partial(shift_forward, mask_clip=mask, num=fade_out_num))
        mask = core.std.Expr([mask, fade_in, fade_out], 'x y max z max')
        if apply_range is not None and isinstance(apply_range, (list, tuple)):
            try:
                blank = core.std.BlankClip(mask)
                if 0 in apply_range:
                    mask = mask[apply_range[0]:apply_range[1]] + blank[
                        apply_range[1]:]
                elif frame_count in apply_range:
                    mask = blank[0:apply_range[0]] + mask[
                        apply_range[0]:apply_range[1]]
                else:
                    mask = blank[0:apply_range[0]] + mask[
                        apply_range[0]:apply_range[1]] + blank[apply_range[1]:]
            except vs.Error:
                raise ValueError(
                    MODULE_NAME +
                    ': incorrect apply range setting. Possibly end less than start'
                )
            except IndexError:
                raise ValueError(
                    MODULE_NAME + ': incorrect apply range setting. '
                    'Apply range must be a tuple/list with 2 elements')
    return mask
Beispiel #17
0
 def down_8(self):
     self.process_depth = 8
     self.aa_clip = mvf.Depth(self.aa_clip, 8)

prefix = 'train'
suffix = '.h5'
labelOutput = prefix + '_label' + suffix
dataOutput = prefix + '_data' + suffix

data = '00003.mp4'  # Edit it to your video source
label = '00003.m2ts'
dataDim = 80
padDim = 6  # Actually 6 on each side
paddedDim = dataDim + 2 * padDim

# Get source and extract Y
core = vs.get_core()
dataClip = mvf.Depth(core.lsmas.LWLibavSource(data),
                     32).std.ShufflePlanes(0, vs.GRAY)
labelClip = mvf.Depth(core.lsmas.LWLibavSource(label),
                      32).std.ShufflePlanes(0, vs.GRAY)
assert isinstance(dataClip, vs.VideoNode)
assert isinstance(labelClip, vs.VideoNode)
assert labelClip.num_frames == dataClip.num_frames
assert dataClip.height == labelClip.height
assert dataClip.width == labelClip.width
frameNum = dataClip.num_frames
frame_h = dataClip.height
frame_w = dataClip.width

sampleFrameNum = 5000
samplePerFrame = 10
sampleNum = sampleFrameNum * samplePerFrame
assert labelClip.num_frames >= sampleFrameNum
Beispiel #19
0
def fade_text_mask(src,
                   lthr=225,
                   cthr=2,
                   expand=2,
                   fade_nums=8,
                   apply_range=None):
    """
    A very very simple textmask creating function to handle fading text on screen
    Version: 0.2.0
    :param src: source clip, vs.YUV
    :param lthr: <int> threshold of luma in 8bit scale. Default:225
    :param cthr: <int> threshold of chroma in 8bit scale. Default:2
    :param expand: <int> times of expansion of textmask. Default:2
    :param fade_nums: <int, list or tuple> the length of fading. Use list or tuple to specify fade-in and fade-out
                       separately. Default:8
    :param apply_range: <list or tuple> range of src clip to apply mask.
    :return: mask clip, vs.GRAY
    """
    core = vs.get_core()
    depth = src.format.bits_per_sample
    color_family = src.format.color_family
    w = src.width
    h = src.height
    func_name = 'Fade Text Mask'

    if not isinstance(src, vs.VideoNode):
        raise TypeError(func_name + ': src is not a video clip.')
    if color_family is not vs.YUV:
        raise TypeError(func_name + ': src should be a YUV clip.')
    if depth > 8:
        src = mvf.Depth(src, 8)

    y = core.std.ShufflePlanes(src, 0, vs.GRAY)
    u = core.std.ShufflePlanes(src, 1, vs.GRAY)
    v = core.std.ShufflePlanes(src, 2, vs.GRAY)

    try:
        u = core.resize.Bicubic(u, w, h, src_left=0.25)
        v = core.resize.Bicubic(v, w, h, src_left=0.25)
    except vs.Error:
        u = mvf.Depth(core.fmtc.resample(u, w, h, sx=0.25), 8)
        v = mvf.Depth(core.fmtc.resample(v, w, h, sx=0.25), 8)

    expr = "x {lthr} > y 128 - abs {cthr} < and z 128 - abs {cthr} < and 255 0 ?".format(
        lthr=lthr, cthr=cthr)
    tmask = core.std.Expr([y, u, v], expr)
    if expand > 1:
        for i in range(expand):
            tmask = core.std.Maximum(tmask)

    frame_count = src.num_frames

    def shift_backward(n, clip, num):
        if n + num > frame_count - 1:
            return clip[frame_count - 1]
        else:
            return clip[n + num]

    def shift_forward(n, clip, num):
        if n - num < 0:
            return clip[0]
        else:
            return clip[n - num]

    if isinstance(fade_nums, int):
        in_num = fade_nums
        out_num = fade_nums
    elif isinstance(fade_nums, (list, tuple)):
        if len(fade_nums) != 2:
            raise ValueError(func_name + ': incorrect fade_nums setting.')
        in_num = fade_nums[0]
        out_num = fade_nums[1]
    else:
        raise TypeError(func_name +
                        ': fade_num can only be int, list or tuple.')

    fade_in = core.std.FrameEval(
        tmask, functools.partial(shift_backward, clip=tmask, num=in_num))
    fade_out = core.std.FrameEval(
        tmask, functools.partial(shift_forward, clip=tmask, num=out_num))
    combined = core.std.Expr([tmask, fade_in, fade_out], "x y max z max")

    if apply_range is not None:
        if not isinstance(apply_range, (list, tuple)):
            raise TypeError(func_name +
                            ': apply range can only be list or tuple')
        elif len(apply_range) != 2:
            raise ValueError(func_name + ': incorrect apply range setting.')
        else:
            try:
                blank_clip = core.std.BlankClip(tmask)
                if 0 in apply_range:
                    combined = combined[apply_range[0]:apply_range[
                        1]] + blank_clip[apply_range[1]:]
                elif frame_count in apply_range:
                    combined = blank_clip[0:apply_range[0]] + combined[
                        apply_range[0]:apply_range[1]]
                else:
                    combined = (blank_clip[0:apply_range[0]] +
                                combined[apply_range[0]:apply_range[1]] +
                                blank_clip[apply_range[1]:])
            except vs.Error:
                raise ValueError(
                    func_name +
                    ': incorrect apply range setting. Possible end less than start.'
                )

    if depth > 8:
        scale = ((1 << depth) - 1) // 255
        out_depth = "vs.GRAY{out_depth}".format(out_depth=depth)
        combined = core.std.Expr(combined, "x " + str(scale) + " *",
                                 eval(out_depth))

    return combined
Beispiel #20
0
    def __init__(self, clip, **kwargs):
        super(FadeTextMask, self).__init__(clip)
        self.clip = mvf.Depth(clip, 8)
        self.lthr = kwargs.get('lthr', 225)
        self.cthr = kwargs.get('cthr', 2)
        self.mexpand = kwargs.get('expand', 2)
        self.fade_nums = kwargs.get('fade_num', 8)
        self.apply_range = kwargs.get('apply_range', None)

        if self.clip_color_family is not vs.YUV:
            raise TypeError(MODULE_NAME + ': clip should be a YUV clip')

        y = self.core.std.ShufflePlanes(self.clip, 0, vs.GRAY)
        u = self.core.std.ShufflePlanes(self.clip, 1, vs.GRAY)
        v = self.core.std.ShufflePlanes(self.clip, 2, vs.GRAY)
        try:
            u = self.core.resize.Bicubic(u,
                                         self.clip_width,
                                         self.clip_height,
                                         src_left=0.25)
            v = self.core.resize.Bicubic(v,
                                         self.clip_width,
                                         self.clip_height,
                                         src_left=0.25)
        except vs.Error:
            u = mvf.Depth(
                self.core.fmtc.resample(u,
                                        self.clip_width,
                                        self.clip_height,
                                        sx=0.25), 8)
            v = mvf.Depth(
                self.core.fmtc.resample(v,
                                        self.clip_width,
                                        self.clip_height,
                                        sx=0.25), 8)

        expr = "x {lthr} > y 128 - abs {cthr} < and z 128 - abs {cthr} < and 255 0 ?".format(
            lthr=self.lthr, cthr=self.cthr)
        self.mask = self.core.std.Expr([y, u, v], expr)
        if self.mexpand > 0:
            self.expand(self.mexpand)

        frame_count = self.clip.num_frames

        def shift_backward(n, clip, num):
            if n + num > frame_count - 1:
                return clip[frame_count - 1]
            else:
                return clip[n + num]

        def shift_forward(n, clip, num):
            if n - num < 0:
                return clip[0]
            else:
                return clip[n - num]

        if isinstance(self.fade_nums, int):
            in_num = self.fade_nums
            out_num = self.fade_nums
        elif isinstance(self.fade_nums, (list, tuple)):
            if len(self.fade_nums) != 2:
                raise ValueError(MODULE_NAME +
                                 ': incorrect fade_nums setting.')
            in_num = self.fade_nums[0]
            out_num = self.fade_nums[1]
        else:
            raise TypeError(MODULE_NAME +
                            ': fade_num can only be int, tuple or list.')

        if self.fade_nums is not 0:
            fade_in = self.core.std.FrameEval(
                self.mask,
                functools.partial(shift_backward, clip=self.mask, num=in_num))
            fade_out = self.core.std.FrameEval(
                self.mask,
                functools.partial(shift_forward, clip=self.mask, num=out_num))
            self.mask = self.core.std.Expr([self.mask, fade_in, fade_out],
                                           " x y max z max")

        if self.apply_range is not None:
            if not isinstance(self.apply_range, (list, tuple)):
                raise TypeError(MODULE_NAME +
                                ': apply range can only be list or tuple.')
            elif len(self.apply_range) != 2:
                raise ValueError(MODULE_NAME +
                                 ': incorrect apply range setting.')
            else:
                try:
                    blank_clip = self.core.std.BlankClip(self.mask)
                    if 0 in self.apply_range:
                        self.mask = self.mask[self.apply_range[0]:self.apply_range[1]] + \
                                    blank_clip[self.apply_range[1]:]
                    elif frame_count in self.apply_range:
                        self.mask = blank_clip[0:self.apply_range[0]] + \
                                    self.mask[self.apply_range[0]:self.apply_range[1]]
                    else:
                        self.mask = blank_clip[0:self.apply_range[0]] + \
                                    self.mask[self.apply_range[0]:self.apply_range[1]] + \
                                    blank_clip[self.apply_range[1]:]
                except vs.Error:
                    raise ValueError(
                        MODULE_NAME +
                        ': incorrect apply range setting. Possible end less than start.'
                    )
Beispiel #21
0
def TAAmbk(clip,
           aatype=1,
           aatypeu=None,
           aatypev=None,
           preaa=0,
           strength=0.0,
           cycle=0,
           mtype=None,
           mclip=None,
           mthr=None,
           mthr2=None,
           mlthresh=None,
           mpand=(1, 0),
           txtmask=0,
           txtfade=0,
           thin=0,
           dark=0.0,
           sharp=0,
           aarepair=0,
           postaa=None,
           src=None,
           stabilize=0,
           down8=True,
           showmask=0,
           opencl=False,
           opencl_device=0,
           **args):
    core = vs.get_core()
    aatypeu = aatype if aatypeu is None else aatypeu
    aatypev = aatype if aatypev is None else aatypev

    if mtype is None:
        mtype = 0 if preaa == 0 and True not in (aatype, aatypeu,
                                                 aatypev) else 1

    if postaa is None:
        postaa = True if abs(sharp) > 70 or (0.4 < abs(sharp) < 1) else False

    if src is None:
        src = clip
    else:
        if clip.format.id != src.format.id:
            raise ValueError(MODULE_NAME +
                             ': clip format and src format mismatch.')
        elif clip.width != src.width or clip.height != src.height:
            raise ValueError(MODULE_NAME +
                             ': clip resolution and src resolution mismatch.')

    preaa_clip = clip if preaa == 0 else daa(clip, preaa)

    if thin == 0 and dark == 0:
        edge_enhanced_clip = preaa_clip
    elif thin != 0 and dark != 0:
        edge_enhanced_clip = haf.Toon(core.warp.AWarpSharp2(preaa_clip,
                                                            depth=int(thin)),
                                      str=float(dark))
    elif thin == 0:
        edge_enhanced_clip = haf.Toon(preaa_clip, str=float(dark))
    else:
        edge_enhanced_clip = core.warp.AWarpSharp2(preaa_clip, depth=int(thin))

    aa_kernel = {
        1: AAEedi2,
        2: AAEedi3,
        3: AANnedi3,
        4: AANnedi3UpscaleSangNom,
        5: AASpline64NRSangNom,
        6: AASpline64SangNom,
        -1: AAEedi2SangNom,
        -2: AAEedi3SangNom,
        -3: AANnedi3SangNom,
        'Eedi2': AAEedi2,
        'Eedi3': AAEedi3,
        'Nnedi3': AANnedi3,
        'Nnedi3UpscaleSangNom': AANnedi3UpscaleSangNom,
        'Spline64NrSangNom': AASpline64NRSangNom,
        'Spline64SangNom': AASpline64SangNom,
        'Eedi2SangNom': AAEedi2SangNom,
        'Eedi3SangNom': AAEedi3SangNom,
        'Nnedi3SangNom': AANnedi3SangNom,
        'PointSangNom': AAPointSangNom
    }

    aaed_clip = None
    if clip.format.color_family is vs.YUV:
        y = core.std.ShufflePlanes(edge_enhanced_clip, 0, vs.GRAY)
        u = core.std.ShufflePlanes(edge_enhanced_clip, 1, vs.GRAY)
        v = core.std.ShufflePlanes(edge_enhanced_clip, 2, vs.GRAY)
        if aatype != 0:
            try:
                y = aa_kernel[aatype](y,
                                      strength,
                                      down8,
                                      opencl=opencl,
                                      opencl_device=opencl_device,
                                      **args).out()
                cycle_y = cycle
                while cycle_y > 0:
                    y = aa_kernel[aatype](y,
                                          strength,
                                          down8,
                                          opencl=opencl,
                                          opencl_device=opencl_device,
                                          **args).out()
                    cycle_y -= 1
                y = mvf.Depth(
                    y, clip.format.bits_per_sample) if down8 is True else y
            except KeyError:
                raise ValueError(MODULE_NAME + ': unknown aatype.')
        if aatypeu != 0:
            try:
                u = aa_kernel[aatypeu](
                    u,
                    0,
                    down8,
                    opencl=opencl,
                    opencl_device=opencl_device,
                    **args).out()  # Won't do predown for u plane
                cycle_u = cycle
                while cycle_u > 0:
                    u = aa_kernel[aatypeu](u,
                                           0,
                                           down8,
                                           opencl=opencl,
                                           opencl_device=opencl_device,
                                           **args).out()
                    cycle_u -= 1
                u = mvf.Depth(
                    u, clip.format.bits_per_sample) if down8 is True else u
            except KeyError:
                raise ValueError(MODULE_NAME + ': unknown aatypeu.')
        if aatypev != 0:
            try:
                v = aa_kernel[aatypev](
                    v,
                    0,
                    down8,
                    opencl=opencl,
                    opencl_device=opencl_device,
                    **args).out()  # Won't do predown for v plane
                cycle_v = cycle
                while cycle_v > 0:
                    v = aa_kernel[aatypev](v,
                                           0,
                                           down8,
                                           opencl=opencl,
                                           opencl_device=opencl_device,
                                           **args).out()
                    cycle_v -= 1
                v = mvf.Depth(
                    v, clip.format.bits_per_sample) if down8 is True else v
            except KeyError:
                raise ValueError(MODULE_NAME + ': unknown aatypev.')
        aaed_clip = core.std.ShufflePlanes([y, u, v], [0, 0, 0], vs.YUV)
    elif clip.format.color_family is vs.GRAY:
        y = edge_enhanced_clip
        if aatype != 0:
            try:
                y = aa_kernel[aatype](y, strength, down8, **args).out()
                cycle_y = cycle
                while cycle_y > 0:
                    y = aa_kernel[aatype](y, strength, down8, **args).out()
                    cycle_y -= 1
                aaed_clip = mvf.Depth(
                    y, clip.format.bits_per_sample) if down8 is True else y
            except KeyError:
                raise ValueError(MODULE_NAME + ': unknown aatype.')
    else:
        raise ValueError(MODULE_NAME + ': Unsupported color family.')

    abs_sharp = abs(sharp)
    if sharp >= 1:
        sharped_clip = haf.LSFmod(aaed_clip,
                                  strength=int(abs_sharp),
                                  defaults='old',
                                  source=src)
    elif sharp > 0:
        per = int(40 * abs_sharp)
        matrix = [-1, -2, -1, -2, 52 - per, -2, -1, -2, -1]
        sharped_clip = core.std.Convolution(aaed_clip, matrix)
    elif sharp == 0:
        sharped_clip = aaed_clip
    elif sharp > -1:
        sharped_clip = haf.LSFmod(aaed_clip,
                                  strength=round(abs_sharp * 100),
                                  defaults='fast',
                                  source=src)
    elif sharp == -1:
        blured = core.rgvs.RemoveGrain(
            aaed_clip, mode=20 if aaed_clip.width > 1100 else 11)
        diff = core.std.MakeDiff(aaed_clip, blured)
        diff = core.rgvs.Repair(diff,
                                core.std.MakeDiff(src, aaed_clip),
                                mode=13)
        sharped_clip = core.std.MergeDiff(aaed_clip, diff)
    else:
        sharped_clip = aaed_clip

    postaa_clip = sharped_clip if postaa is False else soothe(
        sharped_clip, src, 24)
    repaired_clip = postaa_clip if aarepair == 0 else core.rgvs.Repair(
        src, postaa_clip, aarepair)
    stabilized_clip = repaired_clip if stabilize == 0 else temporal_stabilize(
        repaired_clip, src, stabilize)

    if mclip is not None:
        mask = mclip
        try:
            masked_clip = core.std.MaskedMerge(src,
                                               stabilized_clip,
                                               mask,
                                               first_plane=True)
        except vs.Error:
            raise RuntimeError(MODULE_NAME +
                               ': Something wrong with your mclip. '
                               'Maybe resolution or bit_depth mismatch.')
    elif mtype != 0:
        if mtype == 1 or mtype is 'Canny':
            opencl_device = args.get('opencl_device', 0)
            mthr = 1.2 if mthr is None else mthr
            mthr2 = 8.0 if mthr2 is None else mthr2
            mask = MaskCanny(clip,
                             sigma=mthr,
                             t_h=mthr2,
                             lthresh=mlthresh,
                             mpand=mpand,
                             opencl=opencl,
                             opencl_devices=opencl_device).out()
        elif mtype == 2 or mtype is 'Sobel':
            mthr = 1.2 if mthr is None else mthr
            mthr2 = 48 if mthr2 is None else mthr2
            mask = MaskSobel(clip,
                             sigma=mthr,
                             binarize=mthr2,
                             lthresh=mlthresh,
                             mpand=mpand).out()
        elif mtype == 3 or mtype is 'prewitt':
            mthr = 62 if mthr is None else mthr
            mask = MaskPrewitt(clip,
                               factor=mthr,
                               lthresh=mlthresh,
                               mpand=mpand).out()
        else:
            raise ValueError(MODULE_NAME + ': unknown mtype.')
        masked_clip = core.std.MaskedMerge(src, stabilized_clip, mask)
    else:
        masked_clip = stabilized_clip

    if txtmask > 0 and clip.format.color_family is not vs.GRAY:
        text_mask = FadeTextMask(clip, lthr=txtmask, fade_nums=txtfade).out()
        txt_protected_clip = core.std.MaskedMerge(masked_clip,
                                                  src,
                                                  text_mask,
                                                  first_plane=True)
    else:
        txt_protected_clip = masked_clip

    if clip.format.bits_per_sample > 8 and down8 is True:
        clamped_clip = mvf.LimitFilter(src,
                                       txt_protected_clip,
                                       thr=1.0,
                                       elast=2.0)
    else:
        clamped_clip = txt_protected_clip

    try:
        if showmask == -1:
            return text_mask
        elif showmask == 1:
            return mask
        elif showmask == 2:
            return core.std.StackVertical([
                core.std.ShufflePlanes([mask, core.std.BlankClip(src)],
                                       [0, 1, 2], vs.YUV), src
            ])
        elif showmask == 3:
            return core.std.Interleave([
                core.std.ShufflePlanes([mask, core.std.BlankClip(src)],
                                       [0, 1, 2], vs.YUV), src
            ])
        else:
            return clamped_clip
    except UnboundLocalError:
        raise RuntimeError(MODULE_NAME +
                           ': No mask to show if you don\'t have one.')
Beispiel #22
0
def L0Smooth(clip, lamda=2e-2, kappa=2, color=True, **depth_args):
    """L0 Smooth in VapourSynth

    It is also known as "L0 Gradient Minimization".

    L0 smooth is a new image editing method, particularly effective for sharpening major edges
    by increasing the steepness of transitions while eliminating a manageable degree of low-amplitude structures.
    It is achieved in an unconventional optimization framework making use of L0 gradient minimization,
    which can globally control how many non-zero gradients are resulted to approximate prominent structures in a structure-sparsity-management manner.
    Unlike other edge-preserving smoothing approaches, this method does not depend on local features and globally locates important edges.
    It, as a fundamental tool, finds many applications and is particularly beneficial to edge extraction, clip-art JPEG artifact removal, and non-photorealistic image generation.

    All the internal calculations are done at 32-bit float.

    Args:
        clip: Input clip with no chroma subsampling.

        lamda: (float) Smoothing parameter controlling the degree of smooth.
            A large "lamda" makes the result have very few edges.
            Typically it is within the range [0.001, 0.1].
            This parameter is renamed from "lambda" for better compatibility with Python.
            Default is 0.02.

        kappa: (float) Parameter that controls the convergence rate of alternating minimization algorithm.
            Small "kappa" results in more iteratioins and with sharper edges.
            kappa = 2 is suggested for natural images, which is a good balance between efficiency and performance.
            Default is 2.

        color: (bool) Whether to process data collaboratively.
            If true, the gradient magnitude in the model is defined as the sum of gradient magnitudes in the original color space.
            If false, channels in "clip" will be processed separately.
            Default is True.

        depth_args: (dict) Additional arguments passed to mvf.Depth() in the form of keyword arguments.
            Default is {}.

    Ref:
        [1] Xu, L., Lu, C., Xu, Y., & Jia, J. (2011, December). Image smoothing via L0 gradient minimization. In ACM Transactions on Graphics (TOG) (Vol. 30, No. 6, p. 174). ACM.
        [2] http://www.cse.cuhk.edu.hk/~leojia/projects/L0smoothing/index.html

    TODO: Optimize FFT using pyfftw library.

    """

    funcName = 'L0Smooth'

    core = vs.get_core()

    if not isinstance(clip, vs.VideoNode) or any(
        (clip.format.subsampling_w, clip.format.subsampling_h)):
        raise TypeError(
            funcName + ': \"clip\" must be a clip with no chroma subsampling!')

    # Internal parameters
    bits = clip.format.bits_per_sample
    sampleType = clip.format.sample_type
    per_plane = not color or clip.format.num_planes == 1

    # Convert to floating point
    clip = mvf.Depth(clip, depth=32, sample=vs.FLOAT, **depth_args)

    # Add padding for real Fast Fourier Transform
    if clip.width & 1:
        pad = True
        clip = core.std.AddBorders(clip, left=1)
    else:
        pad = False

    # Pre-calculate constant 2-D matrix
    size2D = (clip.height, clip.width)
    Denormin2 = L0Smooth_generate_denormin2(size2D)

    # Process
    clip = numpy_process(clip,
                         functools.partial(L0Smooth_core,
                                           lamda=lamda,
                                           kappa=kappa,
                                           Denormin2=Denormin2,
                                           copy=True),
                         per_plane=per_plane)

    # Crop the padding
    if pad:
        clip = core.std.CropRel(clip, left=1)

    # Convert the bit depth and sample type of output to the same as input
    clip = mvf.Depth(clip, depth=bits, sample=sampleType, **depth_args)

    return clip
Beispiel #23
0
scale = 2
linear_scale = False
upfilter = 'bicubic'

# data = '00003.m2ts'
data = r'I:\Anime\The Garden of Words\BDROM\BDMV\STREAM\00000.m2ts'
data_dim = 41
planes = 3 if useRGB else 1

# Get source and do format conversion
core = vs.get_core()
label_clip = core.lsmas.LWLibavSource(data)
if useRGB:
    label_clip = mvf.ToRGB(label_clip, depth=32)
else:
    label_clip = mvf.Depth(label_clip.std.ShufflePlanes(0, vs.GRAY), 32)

# Prepare data
down_lists = list(range(1, 8))
data_clip = core.std.Interleave([
    resample(label_clip, scale, linear_scale, d, upfilter) for d in down_lists
])
label_clip = core.std.Interleave([label_clip for d in down_lists])

w = data_clip.width
h = data_clip.height
nb_frame = data_clip.num_frames
assert w == label_clip.width
assert h == label_clip.height
assert nb_frame == label_clip.num_frames
Beispiel #24
0
def L0GradientProjection(clip,
                         alpha=0.08,
                         precision=255,
                         epsilon=0.0002,
                         maxiter=5000,
                         gamma=3,
                         eta=0.95,
                         color=True,
                         **depth_args):
    """L0 Gradient Projection in VapourSynth

    L0 gradient projection is a new edge-preserving filtering method based on the L0 gradient.
    In contrast to the L0 gradient minimization, L0 gradient projection framework is intuitive
    because one can directly impose a desired L0 gradient value on the output image.
    The constrained optimization problem is minimizing the quadratic data-fidelity subject to the hard constraint that
    the L0 gradient is less than a user-given parameter "alpha".
    The solution is based on alternating direction method of multipliers (ADMM), while the hard constraint is handled by
    projection onto the mixed L1,0 pseudo-norm ball with variable splitting, and the computational complexity is O(NlogN).

    However, current implementation here is extremely slow. In my experiment, the number of iteration of this algorithm is far more than L0Smooth.

    All the internal calculations are done at 32-bit float.

    Args:
        clip: Input clip with no chroma subsampling.

        alpha: (float) L0 gradient of output in percentage form, i.e. the range is [0, 1].
            It can be seen as the degree of flatness in the output.
            Default is 0.08.

        precision: (float) Precision of the calculation of L0 gradient. The larger the value, the more accurate the calculation.
            Default is 255.

        epsilon: (float) Stopping criterion in percentage form, i.e. the range is [0, 1].
            It determines the allowable error from alpha.
            Default is 0.0002.

        maxiter: (int) Maximum number of iterations.
            Default is 5000.

        gamma: (int) Step size of ADMM.
            Default is 3.

        eta: (int) Controling gamma for nonconvex optimization.
            It stabilizes ADMM for nonconvex optimization.
            According to recent convergence analyses of ADMM for nonconvex cases, under appropriate conditions,
            the sequence generated by ADMM converges to a stationary point with sufficiently small gamma.
            Default is 0.95.

        depth_args: (dict) Additional arguments passed to mvf.Depth() in the form of keyword arguments.
            Default is {}.

    Ref:
        [1] Ono, S. (2017). $ L_ {0} $ Gradient Projection. IEEE Transactions on Image Processing, 26(4), 1554-1564.
        [2] Ono, S. (2017, March). Edge-preserving filtering by projection onto L 0 gradient constraint. In Acoustics, Speech and Signal Processing (ICASSP), 2017 IEEE International Conference on (pp. 1492-1496). IEEE.
        [3] https://sites.google.com/site/thunsukeono/publications

    TODO: Optimize FFT using pyfftw library.

    """

    funcName = 'L0GradientProjection'

    core = vs.get_core()

    if not isinstance(clip, vs.VideoNode) or any(
        (clip.format.subsampling_w, clip.format.subsampling_h)):
        raise TypeError(
            funcName + ': \"clip\" must be a clip with no chroma subsampling!')

    # Internal parameters
    bits = clip.format.bits_per_sample
    sampleType = clip.format.sample_type
    per_plane = not color or clip.format.num_planes == 1

    # Convert to floating point
    clip = mvf.Depth(clip, depth=32, sample=vs.FLOAT, **depth_args)

    # Add padding for real Fast Fourier Transform
    if clip.width & 1:
        pad = True
        clip = core.std.AddBorders(clip, left=1)
    else:
        pad = False

    # Pre-calculate constant 2-D matrix
    size2D = (clip.height, clip.width)
    Lap = L0GradProj_generate_lap(size2D)

    # Process
    clip = numpy_process(clip,
                         functools.partial(L0GradProj_core,
                                           alpha=alpha,
                                           precision=precision,
                                           epsilon=epsilon,
                                           maxiter=maxiter,
                                           gamma=gamma,
                                           eta=eta,
                                           Lap=Lap,
                                           copy=True),
                         per_plane=per_plane)

    # Crop the padding
    if pad:
        clip = core.std.CropRel(clip, left=1)

    # Convert the bit depth and sample type of output to the same as input
    clip = mvf.Depth(clip, depth=bits, sample=sampleType, **depth_args)

    return clip
Beispiel #25
0
def GPA(clip, sigmaS=3, sigmaR=0.15, mode=0, iteration=0, eps=1e-3, **depth_args):
    """Fast and Accurate Bilateral Filtering using Gaussian-Polynomial Approximation

    This filter approximates the bilateral filter when the range kernel is Gaussian.
    The exponential function of the weight function of bilateral filter is approximated,
    and the bilateral is therefore decomposed into a series of spatial convolutions.

    The number of iteration depends on the value of "sigmaR", which increases as "sigmaR" decreases.
    A small value of "sigmaR" may lead to presicion problem.

    All the internal calculations are done at 32-bit float.

    Part of description of bilateral filter is copied from
    https://github.com/HomeOfVapourSynthEvolution/VapourSynth-Bilateral

    Args:
        clip: Input clip.

        sigmaS: (float) Sigma of Gaussian function to calculate spatial weight.
            The scale of this parameter is equivalent to pixel distance.
            Larger sigmaS results in larger filtering radius as well as stronger smoothing.
            Default is 3.

        sigmaR: (float) Sigma of Gaussian function to calculate range weight.
            The scale of this parameter is the same as pixel value ranging in [0,1].
            Smaller sigmaR preserves edges better, may also leads to weaker smoothing.
            It should be pointed out that a small "sigmaR" results in more iteration and higher error.
            Default is 0.15.

        mode: (0 or 1) 0: Guassian bilateral filter, 1: Box bilateral filter
            Default is 0.

        iteration: (int) Number of iteration or the order of approximation.
            If it is 0, it is calculated automatically according to "sigmaR" and "eps".
            Default is 0.

        eps: (float) Filtering Accuracy.
            Default is 1e-3.

        depth_args: (dict) Additional arguments passed to mvf.Depth().
            Default is {}.

    Ref:
        [1] Chaudhury, K. N., & Dabhade, S. D. (2016). Fast and provably accurate bilateral filtering. IEEE Transactions on Image Processing, 25(6), 2519-2528.
        [2] http://www.mathworks.com/matlabcentral/fileexchange/56158

    """

    def estimate_iteration(sigmaR, T, eps):
        if sigmaR > 70:
            return 10
        elif sigmaR < 5:
            return 800
        else:
            lam = (T / sigmaR) ** 2
            p = 1 + math.log(lam)
            q = -lam - math.log(eps)
            t = q / math.e / lam
            W = t - t ** 2 + 1.5 * t ** 3 - (8 / 3) * t ** 4
            N = min(max(q / W, 10), 300)

            if sigmaR < 30:
                for i in range(5):
                    N -= (N * math.log(N) - p * N - q) / (math.log(N) + 1 - p)

            return math.ceil(N)

    T = 0.5
    bits = clip.format.bits_per_sample
    sampleType = clip.format.sample_type

    if mode == 0: # Gaussian bilateral filter
        Filter = functools.partial(core.tcanny.TCanny, sigma=sigmaS, mode=-1)
    else: # Box bilateral filter
        Filter = functools.partial(muf.BoxFilter, radius=sigmaS + 1)

    if iteration == 0:
        iteration = estimate_iteration(sigmaR * 255, T, eps)

    clip = mvf.Depth(clip, depth=32, sample=vs.FLOAT, **depth_args)

    H = core.std.Expr(clip, f'x {T} - {sigmaR} /')
    F = core.std.Expr(H, '-0.5 x dup * * exp')
    G = core.std.BlankClip(clip, color=[1] * clip.format.num_planes)
    P = core.std.BlankClip(clip, color=[0] * clip.format.num_planes)
    Q = core.std.BlankClip(clip, color=[0] * clip.format.num_planes)
    Fbar = Filter(F)

    for i in range(1, iteration+1):
        sqrt_i = math.sqrt(i)
        inv_sqrt_i = 1 / sqrt_i 
        Q = core.std.Expr([Q, G, Fbar], 'x y z * +')
        F = core.std.Expr([H, F], f'x y * {inv_sqrt_i} *')
        Fbar = Filter(F)
        P = core.std.Expr([P, G, Fbar], f'x y z * {sqrt_i} * +')
        G = core.std.Expr([H, G], f'x y * {inv_sqrt_i} *')

    res = core.std.Expr([P, Q], f'x {sigmaR} * y 1e-5 + / {T} +')

    return mvf.Depth(res, depth=bits, sample=sampleType, **depth_args)
def nnedi3_dh(input,
              field=1,
              nsize=None,
              nns=None,
              qual=None,
              etype=None,
              pscrn=None,
              device=None,
              fast=None,
              flat_kernel=None,
              flat_a1=None,
              flat_a2=None,
              flat_taps=None):
    core = vs.core

    sFormat = input.format
    sSType = sFormat.sample_type
    sbitPS = sFormat.bits_per_sample
    sVSubS = 1 << sFormat.subsampling_h

    if fast is None:
        fast = False
    if flat_kernel is None:
        flat_kernel = "nnedi3"
    else:
        flat_kernel = flat_kernel.lower()

    if (field == 0 or field == 1) and ((fast and sbitPS > 8)):
        if flat_kernel == "nnedi3":
            flat_kernel = "bicubic"
        input8 = mvf.Depth(input, depth=8, sample=vs.INTEGER)
        nn = core.nnedi3cl.NNEDI3CL(input8,
                                    field=field,
                                    dh=True,
                                    nsize=nsize,
                                    nns=nns,
                                    qual=qual,
                                    etype=etype,
                                    pscrn=pscrn,
                                    device=device)
        lr = core.fmtc.resample(input,
                                sy=[-0.5, -0.5 * sVSubS] if field == 0 else 0,
                                scaleh=1,
                                scalev=2,
                                kernel=flat_kernel,
                                a1=flat_a1,
                                a2=flat_a2,
                                taps=flat_taps,
                                center=False)
        return mvf.LimitFilter(mvf.Depth(lr, depth=sbitPS, sample=sSType),
                               mvf.Depth(nn, depth=sbitPS, sample=sSType),
                               thr=1.0,
                               elast=2.0)
    elif flat_kernel == "nnedi3":
        return core.nnedi3cl.NNEDI3CL(input,
                                      field=field,
                                      dh=True,
                                      nsize=nsize,
                                      nns=nns,
                                      qual=qual,
                                      etype=etype,
                                      pscrn=pscrn,
                                      device=device)
    else:
        nn = core.nnedi3cl.NNEDI3CL(input,
                                    field=field,
                                    dh=True,
                                    nsize=nsize,
                                    nns=nns,
                                    qual=qual,
                                    etype=etype,
                                    pscrn=pscrn,
                                    device=device)
        lr = core.fmtc.resample(input,
                                sy=[-0.5, -0.5 * sVSubS] if field == 0 else 0,
                                scaleh=1,
                                scalev=2,
                                kernel=flat_kernel,
                                a1=flat_a1,
                                a2=flat_a2,
                                taps=flat_taps,
                                center=False)
        return mvf.LimitFilter(mvf.Depth(lr, depth=sbitPS, sample=sSType),
                               mvf.Depth(nn, depth=sbitPS, sample=sSType),
                               thr=1.0,
                               elast=2.0)
Beispiel #27
0
def mts(src):
    src8 = mvf.ToYUV(src, css='420')
    src16 = core.fmtc.bitdepth(src8,bits=16)

    # Denoise
    src_rgb = mvf.ToRGB(src16,depth=32)
    #nr16_rgb = core.pdn.BM3DBasic(src_rgb, sigma=[0.5, 0.2, 0.2],group_size=16, bm_range=8)
    nr16_rgb = core.pdn.BM3DBasic(src_rgb, sigma=[1.0, 0.5, 0.5])
    nr16 = mvf.ToYUV(nr16_rgb, css="420",depth=16)
    noise16 = core.std.MakeDiff(src16, nr16)

    # Mask
    pre16 = core.std.ShufflePlanes([nr16,src16],[0,1,2],vs.YUV)
    pre8 = mvf.Depth(pre16, depth=8, dither=5)

    eemask = core.tcanny.TCanny(pre8,sigma=0.6,op=2,gmmax=255,planes=[0,1,2],mode=1)
    eemask_u = core.std.ShufflePlanes(eemask, [1,1,1], vs.YUV).fmtc.resample(1920,1080,sx=0.25,css="420")
    eemask_v = core.std.ShufflePlanes(eemask, [2,2,2], vs.YUV).fmtc.resample(1920,1080,sx=0.25,css="420")
    weighted = core.std.Expr([eemask,eemask_u,eemask_v],["x 64 * y + z +",""],vs.YUV420P16)

    luma = core.std.ShufflePlanes(pre8, 0, vs.YUV).resize.Bilinear(format=vs.YUV420P8)
    eemask = core.std.Expr([eemask,luma],["x x * 20 * 255 y - dup * 0.2 * + 50000 min","x x * 30 * 255 y - dup * 0.3 * + 60000 min"],vs.YUV420P16)
    eemask = core.std.Maximum(eemask,planes=[0,1,2])
    eemask = core.rgvs.RemoveGrain(eemask, [20,11]).rgvs.RemoveGrain([20,11]).rgvs.RemoveGrain([20,11])

    aamask = core.std.Binarize(weighted, 12000, 0)

    nrmasks = core.std.Binarize(weighted, 4500, 0)

    dmaskb = core.std.Binarize(weighted, 3000, 0)
    dmaskm = core.std.Binarize(weighted, 3500, 0)
    dmasks = core.std.Binarize(weighted, 3800, 0)
    dmask_dark = core.misc.Hysteresis(dmaskm, dmaskb)
    dmask_bright = core.misc.Hysteresis(dmasks, dmaskm)
    dmask = core.std.Expr([src16, dmask_dark, dmask_bright], "x 24672 < y z ?")

    nrmaskg = core.tcanny.TCanny(pre8,sigma=1.5,t_l=8,t_h=15,op=2,planes=0)
    nrmaskb = core.tcanny.TCanny(pre8,sigma=1.2,t_l=8,t_h=11,op=2,planes=0)

    nrmask = core.std.Expr([nrmaskg,nrmaskb,nrmasks,pre8,dmask],["a 20 < 65535 a 64 < x 257 * b max a 160 < y 257 * z ? ? ?","",""],vs.YUV420P16)
    nrmask = core.std.Maximum(nrmask,0).std.Maximum(0).std.Minimum(0).std.Minimum(0)
    nrmask = core.rgvs.RemoveGrain(core.rgvs.RemoveGrain(nrmask,[20,0]),[20,0])


    Y = core.std.ShufflePlanes(src16, 0, vs.YUV).resize.Bicubic(1920, 1080, format=vs.YUV420P16, filter_param_a=0, filter_param_b=0.5)
    U = core.std.ShufflePlanes(src16, [1,1,1], vs.YUV).resize.Bicubic(1920, 1080, format=vs.YUV420P16, filter_param_a=0, filter_param_b=0.5)
    V = core.std.ShufflePlanes(src16, [2,2,2], vs.YUV).resize.Bicubic(1920, 1080, format=vs.YUV420P16, filter_param_a=0, filter_param_b=0.5)
    textmask0 = core.std.Expr([Y,U,V], ["x 60000 > y 32768 - abs 768 < and z 32768 - abs 768 < and 65535 0 ?","0"])
    #textmasks = core.std.Expr([Y,U,V], ["x 58000 > y 32768 - abs 512 < and z 32768 - abs 512 < and 65535 0 ?","0"])
    textmask1 = core.std.Minimum(textmask0, 0).std.Minimum(planes=0).std.Minimum(planes=0).std.Maximum(0).std.Maximum(0).std.Maximum(0)
    textmask2 = core.misc.Hysteresis(textmask1, textmask0, planes=0)
    textmask = core.std.Expr([textmask0, textmask2], "x y > x 0 ?")
    #textmask = core.misc.Hysteresis(textmasks, textmaskb, planes=0)
    textmask = core.std.Maximum(textmask,0).std.Maximum(0).std.Maximum(0)#.std.Maximum(0)#.std.Maximum(0)#.std.Maximum(0)#.std.Minimum(0)

    debd = core.f3kdb.Deband(nr16,8,48,32,32,0,0,output_depth=16)
    debd = core.f3kdb.Deband(debd,15,32,24,24,0,0,output_depth=16)
    debd = mvf.LimitFilter(debd,nr16,thr=0.7,thrc=0.5,elast=2.0)
    debd = core.std.MaskedMerge(debd, nr16, nrmask, first_plane=1)

    w  = 1920
    h  = 1080
    oaa_y = core.std.ShufflePlanes(nr16, 0, vs.GRAY)

    aa_y = core.eedi2.EEDI2(oaa_y,field=1,mthresh=10,lthresh=20,vthresh=20,maxd=24,nt=50).fmtc.resample(w,h,sy=-0.5, kernel='bicubic', a1=0, a2=0.5,).std.Transpose()
    aa_y = core.eedi2.EEDI2(aa_y,field=1,mthresh=10,lthresh=20,vthresh=20,maxd=24,nt=50).fmtc.resample(h,w,sy=-0.5, kernel='bicubic', a1=0, a2=0.5,).std.Transpose()

    aa_clip = core.std.ShufflePlanes([aa_y,nr16], [0,1,2], vs.YUV)
    aaed = core.std.MaskedMerge(debd, aa_clip, aamask, 0, True)
    aaed = core.std.MaskedMerge(aaed, debd, textmask, 0, False)

    dif = core.std.MakeDiff(aaed, core.rgvs.RemoveGrain(aaed,20))
    sharp = core.std.MergeDiff(aaed, dif)
    sharped = core.std.MaskedMerge(sharp, aaed, eemask, [0,1,2], False)

    noise16 = core.std.Expr(noise16,["x 32768 - 1.05 * 32768 +",""])
    nullclip = core.std.Expr(src16,["32768",""])
    nrweight = core.std.Expr(pre8, ["x 48 - 0 max dup * 5 * ",""], vs.YUV420P16)
    noise16 = core.std.MaskedMerge(noise16,nullclip,nrweight,0,True)
    res = core.std.MergeDiff(sharped,noise16,0)

    return res
Beispiel #28
0
## 2x.vpy

import vapoursynth as vs
import mvsfunc as mvf
 
sourceFile = r"*.mp4"
core = vs.get_core(threads = 12)
core.max_cache_size = 8000
src = core.ffms2.Source(source = sourceFile)
src = mvf.Depth(src, depth = 32)
block_w = src.width / 10
block_h = src.height / 10
src = core.caffe.Waifu2x(
	clip = src,
	noise = 3,
	scale = 2,
	block_w = block_w,
	block_h = block_h,
	model = 6,
	cudnn = True,
	tta = False,
	batch = 1)
src = mvf.ToYUV(src, full = False, depth = 8, css = "420", matrix = 1)
src.set_output()