def nnedi3_resample_kernel_vertical(input, target_height=None, src_top=None, src_height=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, taps=None, a1=None, a2=None, invks=False, invkstaps=3):
    core = vs.get_core()
    
    # Parameters of scaling
    if target_height is None:
        target_height = input.height
    if src_top is None:
        src_top = 0
    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
    
    scale = target_height / src_height # Total scaling ratio
    eTimes = math.ceil(math.log(scale / scale_thr, 2)) if scale > scale_thr else 0 # Iterative times of nnedi3
    eScale = 1 << eTimes # Scaling ratio of nnedi3
    pScale = scale / eScale # Scaling ratio of fmtc.resample
    
    # 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:
        kernel = 'spline36'
    else:
        kernel = kernel.lower()
    
    # Skip scaling if not needed
    if scale == 1 and src_top == 0 and src_height == input.height:
        return input
    
    # Scaling with nnedi3
    last = nnedi3_rpow2_vertical(input, eTimes, 1, nsize, nns, qual, etype, pscrn, opt, int16_prescreener, int16_predictor, exp)
    
    # Center shift calculation
    vShift = 0.5 if eTimes >= 1 else 0
    
    # Scaling with fmtc.resample as well as correct center shift
    w = last.width
    h = target_height
    sx = 0
    sy = src_top * eScale - vShift
    sw = last.width
    sh = src_height * eScale
    
    if h != last.height or sy != 0 or sh != last.height:
        if h < last.height and invks is True:
            last = core.fmtc.resample(last, w, h, sx, sy, sw, sh, kernel=kernel, taps=taps, a1=a1, a2=a2, invks=True, invkstaps=invkstaps)
        else:
            last = core.fmtc.resample(last, w, h, sx, sy, sw, sh, kernel=kernel, taps=taps, a1=a1, a2=a2)
    
    # Output
    return last
예제 #2
0
def clamp16 (src, bright_limit, dark_limit, overshoot=0, undershoot=0):
    core = vs.get_core ()
    os   = overshoot * 256
    us   = undershoot * 256

    clip = core.std.Expr ([src, bright_limit, dark_limit], ["x y {os} + > y {os} + x ? z {us} - < z {us} - x ?".format (os=os, us=us)])
    return clip
    def setUp(self):
        self.core = vs.get_core()
        self.frame = self.core.std.BlankClip().get_frame(0)
        self.props = self.frame.props

        self.frame_copy = self.frame.copy()
        self.props_rw = self.frame_copy.props
예제 #4
0
def Baa(c, aa = "sangnom2", ss = None, mask=True, mthr = 30, blur=5, expand = 1, chroma = False):

    core = vs.get_core() 
    
    aac = 48 if chroma == True else 0
	
    if not isinstance(c, vs.VideoNode):
        raise ValueError('ediaaclip: This is not a clip')
        
    edibits=c.format.bits_per_sample

    if edibits > 8:
        a8 = core.fmtc.bitdepth(c, bits=8)
         
    else :
        a8 = c
        
    if mask == True:
        mask = core.generic.Prewitt(a8, mthr, mthr)
        mask = BlurLoop(ExpandLoop(mask, expand), blur)
        
    if ss == None:
        ss = 2 if aa == "sangnom2" else 1.1
         
    if ss != 1:
        a8 = Resize(a8, m16(c.width * ss), m16(c.height * ss))
         
    if aa == "nnedi3":
        a8 = Resize(core.nnedi3.nnedi3(a8, field=1,dh=True).std.Transpose().nnedi3.nnedi3(field=1,dh=True).std.Transpose(), a8.width, a8.height, -0.5,-0.5,2*a8.width+.001,2*a8.height+.001)
            
    elif aa == "eedi3":
        a8 = Resize(core.eedi3.eedi3(a8, field=1,dh=True).std.Transpose().eedi3.eedi3(field=1,dh=True).std.Transpose(), a8.width, a8.height, -0.5,-0.5,2*a8.width+.001,2*a8.height+.001)
            
    elif aa == "eedi2":
        a8 = Resize(core.eedi2.EEDI2(a8, field=1,dh=True).std.Transpose().eedi2.EEDI2(field=1,dh=True).std.Transpose(), a8.width, a8.height, -0.5,-0.5,2*a8.width+.001,2*a8.height+.001)
        
        #To-Do rewrite eedix+sangnom2 combo to not throw away good field
    elif aa == "eedi2+sangnom2":
        a8 = Resize(core.std.Transpose(core.sangnom.SangNomMod(core.std.Transpose(core.sangnom.SangNomMod(core.std.Transpose(core.eedi2.EEDI2(core.std.Transpose(core.eedi2.EEDI2(a8, field=1,dh=True)), field=1,dh=True)),aac=aac)),aac=aac)), a8.width, a8.height, -0.5,-0.5,2*a8.width+.001,2*a8.height+.001)
        
    elif aa == "eedi3+sangnom2":
        a8 = Resize(core.std.Transpose(core.sangnom.SangNomMod(core.std.Transpose(core.sangnom.SangNomMod(core.std.Transpose(core.eedi3.eedi3(core.std.Transpose(core.eedi3.eedi3(a8, field=1,dh=True)), field=1,dh=True)),aac=aac)),aac=aac)), a8.width, a8.height, -0.5,-0.5,2*a8.width+.001,2*a8.height+.001)
        
    else:
        a8 = core.sangnom.SangNomMod(a8,aac=aac).std.Transpose().sangnom.SangNomMod(aac=aac).std.Transpose()
  
    if ss != 1:
        a8 = Resize(a8, c.width, c.height)

    if edibits > 8:
        a8 = core.fmtc.bitdepth(a8,bits=edibits)
        if isinstance(mask, vs.VideoNode):
            mask = core.fmtc.bitdepth(mask,bits=edibits)


    if isinstance(mask, vs.VideoNode):
        return core.std.MaskedMerge(c,a8,mask)
        
		 
    return a8
예제 #5
0
def interpolate(config, recalcconfig=None):
    core = vs.get_core()
    clip = video_in

    # Interpolating to fps higher than 60 is too CPU-expensive
    # Use interpolation from opengl video output
    dst_fps = display_fps
    while (dst_fps > 60):
        dst_fps /= 2

    src_fps_num = int(container_fps * 1e8)
    src_fps_den = int(1e8)
    dst_fps_num = int(dst_fps * 1e4)
    dst_fps_den = int(1e4)

    # Needed because clip FPS is missing
    clip = core.std.AssumeFPS(clip, fpsnum = src_fps_num, fpsden = src_fps_den)
    print("Reflowing from ",src_fps_num/src_fps_den," fps to ",dst_fps_num/dst_fps_den," fps.")

    pad = config.get('blksize',  8)
    sup  = core.mv.Super(clip, pel=1, hpad=pad, vpad=pad)
    bvec, fvec = analyse(sup, config)
    if recalcconfig:
        bvec, fvec = recalculate(sup, bvec, fvec, recalcconfig)
    clip = core.mv.FlowFPS(clip, sup, bvec, fvec, num=dst_fps_num, den=dst_fps_den, thscd2=90)

    clip.set_output()
예제 #6
0
def BlurLoop(c, x, planes=[0]):
    
    if c.format.color_family != vs.GRAY:
        rg = [0,0,0]
        if 0 in planes:
            rg[0] = 12
        else:
            rg[0] = 0
            
        if 1 in planes:
            rg[1] = 12
        else:
            rg[1] = 0
            
        if 2 in planes:
            rg[2] = 12
        else:
            rg[2] = 0
    else:
        rg = [12]
        
        
    core = vs.get_core()
    
    for y in range(0, x):
        c = core.rgvs.RemoveGrain(c, rg)
        
    return c
def LinearAndGamma(src, l2g_flag, fulls, fulld, curve, planes, gcor, sigmoid, thr, cont):
    core = vs.get_core()
    
    if curve == 'srgb':
        c_num = 0
    elif curve in ['709', '601', '170']:
        c_num = 1
    elif curve == '240':
        c_num = 2
    elif curve == '2020':
        c_num = 3
    else:
        raise ValueError('LinearAndGamma: wrong curve value')
    
    if src.format.color_family == vs.GRAY:
        planes = [0]
    
    #                 BT-709/601
    #        sRGB     SMPTE 170M   SMPTE 240M   BT-2020
    k0    = [0.04045, 0.081,       0.0912,      0.08145][c_num]
    phi   = [12.92,   4.5,         4.0,         4.5][c_num]
    alpha = [0.055,   0.099,       0.1115,      0.0993][c_num]
    gamma = [2.4,     2.22222,     2.22222,     2.22222][c_num]
    
    def g2l(x):
        expr = x / 65536 if fulls else (x - 4096) / 56064
        if expr <= k0:
            expr /= phi
        else:
            expr = ((expr + alpha) / (1 + alpha)) ** gamma
        if gcor != 1 and expr >= 0:
            expr **= gcor
        if sigmoid:
            x0 = 1 / (1 + math.exp(cont * thr))
            x1 = 1 / (1 + math.exp(cont * (thr - 1)))
            expr = thr - math.log(max(1 / max(expr * (x1 - x0) + x0, 0.000001) - 1, 0.000001)) / cont
        if fulld:
            return min(max(round(expr * 65536), 0), 65535)
        else:
            return min(max(round(expr * 56064 + 4096), 0), 65535)
    
    # E' = (E <= k0 / phi)   ?   E * phi   :   (E ^ (1 / gamma)) * (alpha + 1) - alpha
    def l2g(x):
        expr = x / 65536 if fulls else (x - 4096) / 56064
        if sigmoid:
            x0 = 1 / (1 + math.exp(cont * thr))
            x1 = 1 / (1 + math.exp(cont * (thr - 1)))
            expr = (1 / (1 + math.exp(cont * (thr - expr))) - x0) / (x1 - x0)
        if gcor != 1 and expr >= 0:
            expr **= gcor
        if expr <= k0 / phi:
            expr *= phi
        else:
            expr = expr ** (1 / gamma) * (alpha + 1) - alpha
        if fulld:
            return min(max(round(expr * 65536), 0), 65535)
        else:
            return min(max(round(expr * 56064 + 4096), 0), 65535)
    
    return core.std.Lut(src, planes=planes, function=l2g if l2g_flag else g2l)
def fulltonative (src, a=32, h=6.4, lowpass=6, mode=0):
    core            = vs.get_core ()
    NLMeans         = core.knlm.KNLMeansCL
    resample        = core.fmtc.resample
    Expr            = core.std.Expr
    MakeDiff        = core.std.MakeDiff
    MergeDiff       = core.std.MergeDiff
    ShufflePlanes   = core.std.ShufflePlanes
    Crop            = core.std.CropRel
    def gauss_h (src, p=30):
        upsmp       = resample (src, src.width * 2, src.height, kernel="gauss", a1=100, **fmtc_args)
        clip        = resample (upsmp, src.width, src.height, kernel="gauss", a1=p, **fmtc_args)
        return clip
    pad             = padding (src, a, a, a, a)
    srcy            = ShufflePlanes (pad, 0, vs.GRAY)
    srcu            = ShufflePlanes (pad, 1, vs.GRAY)
    srcv            = ShufflePlanes (pad, 2, vs.GRAY)
    u4x             = genpelclip (pad, pel=4)
    luma            = ShufflePlanes (u4x, 0, vs.GRAY)
    u               = Expr (ShufflePlanes (u4x, 1, vs.GRAY), "x 0.5 +")
    v               = Expr (ShufflePlanes (u4x, 2, vs.GRAY), "x 0.5 +")
    unew            = resizenr (NLMeans (u, d=0, a=a, s=0, h=h, wref=1.0, rclip=luma), pad.width, pad.height, sx=-1.5, sy=-1.5, kernel="spline", taps=6)
    vnew            = resizenr (NLMeans (v, d=0, a=a, s=0, h=h, wref=1.0, rclip=luma), pad.width, pad.height, sx=-1.5, sy=-1.5, kernel="spline", taps=6)
    uhi             = MakeDiff (unew, gauss_h (unew, p=lowpass)) if mode else MakeDiff (unew, gauss (unew, p=lowpass))
    vhi             = MakeDiff (vnew, gauss_h (vnew, p=lowpass)) if mode else MakeDiff (vnew, gauss (vnew, p=lowpass))
    ufinal          = Expr (MergeDiff (Expr (srcu, "x 0.5 +"), uhi), "x 0.5 -")
    vfinal          = Expr (MergeDiff (Expr (srcv, "x 0.5 +"), vhi), "x 0.5 -")
    merge           = ShufflePlanes ([srcy, ufinal, vfinal], [0, 0, 0], vs.YUV)
    clip            = Crop (merge, a, a, a, a)
    return clip
예제 #9
0
def delete_range(src, start, end=None):
    """ Deletes a range of frames from a clip.
    If no end frame is given, it will only delete the start frame.
    """
    core = vs.get_core()

    if end is None:
        end = start

    if start < 0 or start > src.num_frames - 1:
        raise ValueError('start frame out of bounds: {}.'.format(start))
    if end < start or end > src.num_frames - 1:
        raise ValueError('end frame out of bounds: {}.'.format(end))

    if start != 0:
        final = src[:start]
        if end < src.num_frames - 1:
            final = final + src[end + 1:]
    else:
        final = src[end + 1:]

    if src.num_frames != final.num_frames + (end - start + 1):
        raise ValueError('output expected framecount missmatch.')

    return final
예제 #10
0
def hipass (src, sharp, p=16):
    core            = vs.get_core ()
    MakeDiff        = core.std.MakeDiff
    MergeDiff       = core.std.MergeDiff
    hif             = MakeDiff (sharp, gauss (sharp, p=p))
    clip            = MergeDiff (gauss (src, p=p), hif)
    return clip
예제 #11
0
def detailsharpen(clip, sstr=1.01, estr=10, ethr=5, repair=False, rmode=12):
    core = vs.get_core()

    bd = clip.format.bits_per_sample
    max_ = 2 ** bd - 1
    mid = (max_ + 1) // 2
    scl = (max_ + 1) // 256

    src = clip
    clip = vsh.get_luma(clip)
    blur = core.rgvs.RemoveGrain(clip, 20)

    # "x y == x x x y - abs 0.25 ^ 4.24 * x y - 2 ^ x y - 2 ^ 2 + / * x y - x y - abs / * 1 x y - abs 16 / 4 ^ + / + ?"
    # "x x y - abs 0.25 ^ 4.24 * x y - x y - abs 2 + / * +"
    # 'x x y - abs 4 / 1 4 / ^ 4 * 1.5 * x y - x y - abs 2 + / * +'
    # 'x x y - abs 1 4 / ^ 2.83 * 1.5 * x y - x y - abs 2 + / * +'
    # expr = 'x x y - 1 x y - 16 / 4 ^ + / +'
    expr = '{x} {x} {y} - abs 4 / log 0.25 * exp 4 * {st} * {x} {y} - {x} {y} - abs 1.001 + / * + {sc}'.format(
           x='x {} /'.format(scl) if bd != 8 else 'x',
           y='y {} /'.format(scl) if bd != 8 else 'y',
           sc='{} *'.format(scl) if bd != 8 else '',
           st=sstr)

    clip = core.std.Expr([clip, blur], [expr])

    if estr > 0:
        tmp = clip
        clip = core.msmoosh.MSharpen(clip, threshold=ethr, strength=estr)
        if repair is True:
            clip = core.rgvs.Repair(clip=clip, repairclip=tmp, mode=rmode)

    clip = vsh.merge_chroma(clip, src)

    return clip
예제 #12
0
def add16 (src1, src2, dif=True):
    core = vs.get_core ()
    if dif:
       clip = core.std.MergeDiff (src1, src2)
    else:
       clip = core.std.Expr ([src1, src2], ["x y +"])
    return clip
예제 #13
0
def StoreVect (vectors, log):
    core         = vs.get_core ()
    w            = vectors.get_frame (0).width
    with open (log, "w") as f:
         print (w, file=f)
    vectors      = core.std.CropAbs (vectors, width=w, height=1)
    return vectors
예제 #14
0
def sub16 (src1, src2, dif=True):
    core = vs.get_core ()
    if dif:
       clip = core.std.MakeDiff (src1, src2)
    else:
       clip = core.std.Expr ([src1, src2], ["x y -"])
    return clip
예제 #15
0
def fit(clipa, clipb):
    core = vs.get_core()

    bd = clipb.format.bits_per_sample
    max_ = 2 ** bd - 1
    mid = (max_ + 1) // 2

    if clipb.format.num_planes > 1:
        if clipb.format.color_family == vs.RGB:
            color = [max_, max_, max_]
        else:
            color = [max_, mid, mid]
    else:
        color = [max_]

    if clipa.width > clipb.width:
        clipb = core.std.AddBorders(clip=clipb, left=0, right=clipa.width - clipb.width, color=color)
    elif clipa.width < clipb.width:
        clipb = core.std.CropRel(clip=clipb, left=0, right=clipb.width - clipa.width)

    if clipa.height > clipb.height:
        clipb = core.std.AddBorders(clip=clipb, top=0, bottom=clipa.height - clipb.height, color=color)
    elif clipa.height < clipb.height:
        clipb = core.std.CropRel(clip=clipb, top=0, bottom=clipb.height - clipa.height)

    return clipb
예제 #16
0
def sharpfinal (soft, dif, limit, vmulti, peldif=None, pellimit=None, pel=4, tr=6, thsad=400, thscd1=10000, thscd2=255, str=1.00, lowpass=8, a=32, h=6.4, thr=0.00390625, elast=None):
    core            = vs.get_core ()
    Repair          = core.rgsf.Repair
    Maximum         = core.flt.Maximum
    Minimum         = core.flt.Minimum
    Expr            = core.std.Expr
    MakeDiff        = core.std.MakeDiff
    MergeDiff       = core.std.MergeDiff
    MSuper          = core.mvsf.Super
    MDegrainN       = mvmulti.DegrainN
    MCompensate     = mvmulti.Compensate
    expression      = ["{x} {y} {x} - abs 4 / 1 4 / pow 4 * 1.6 * {str} * {y} {x} - {y} {x} - abs 1.001 + / * + 256 /".format (str=str, x="x 256 *", y="y 256 *")]
    blankd          = Expr ([dif], ["0.5"])
    superdif        = MSuper (dif, pelclip=peldif, rfilter=2, pel=pel, **msuper_args)
    supercmp        = MSuper (limit, pelclip=pellimit, rfilter=2, pel=pel, **msuper_args)
    coarse          = MDegrainN (blankd, superdif, vmulti, tr=tr, thsad=10000, thscd1=thscd1, thscd2=thscd2, **mdegrain_args)
    fine            = MDegrainN (blankd, superdif, vmulti, tr=tr, thsad=thsad, thscd1=thscd1, thscd2=thscd2, **mdegrain_args)
    newdif          = Expr ([dif, coarse, blankd, fine], ["y z - abs x z - abs > a y ?"])
    averaged        = MergeDiff (soft, newdif)
    comp            = MCompensate (soft, supercmp, vmulti, tr=tr, thsad=thsad, thscd1=thscd1, thscd2=thscd2)
    bright          = Expr ([maxmulti (comp, tr=tr), Maximum (limit)], "x y min")
    dark            = Expr ([minmulti (comp, tr=tr), Minimum (limit)], "x y max")
    clamped         = clamp (averaged, bright, dark, overshoot=0.0, undershoot=0.0)
    amplified       = Expr ([soft, clamped], expression)
    clip            = hipass (soft, Repair (amplified, halonr (amplified, a, h, thr, elast, lowpass), 16), lowpass)
    return clip
예제 #17
0
def move(clips, x, y):
    core = vs.get_core()

    moved = None

    for clip in clips:
        if clip.format.num_planes == 1:
            color = [(2 ** clip.format.bits_per_sample) - 1]
        else:
            color = None

        if x != 0 or y != 0:
            if x >= 0:
                right = 0
                left = x
            else:
                right = abs(x)
                left = 0
            if y >= 0:
                top = 0
                bottom = y
            else:
                top = abs(y)
                bottom = 0

            clip = core.std.AddBorders(clip=clip, left=left, right=right, top=top, bottom=bottom, color=color)
            clip = core.std.CropRel(clip=clip, left=right, right=left, top=bottom, bottom=top)

        if clip is isinstance(list()):
            moved.append(clip)
        else:
            moved = clip

    return moved
예제 #18
0
def subtract(c1, c2, luma=126, planes=[0]):
    core = vs.get_core()

    expr = ('{luma} x + y -').format(luma=luma)
    expr = [(i in planes) * expr for i in range(c1.format.num_planes)]

    return core.std.Expr([c1, c2], expr)
예제 #19
0
def soothe(clip, src, keep=24):
    core = vs.get_core()
    clip_bits = clip.format.bits_per_sample
    src_bits = src.format.bits_per_sample
    if clip_bits != src_bits:
        raise ValueError(MODULE_NAME + ': temporal_stabilize: bits depth of clip and src mismatch.')

    neutral = 1 << (clip_bits - 1)
    ceil = (1 << clip_bits) - 1
    multiple = ceil // 255
    const = 100 * multiple
    kp = keep * multiple

    diff = core.std.MakeDiff(src, clip)
    try:
        diff_soften = core.misc.AverageFrame(diff, weights=[1, 1, 1], scenechange=32)
    except AttributeError:
        diff_soften = core.focus.TemporalSoften(diff, radius=1, luma_threshold=255,
                                                chroma_threshold=255, scenechange=32, mode=2)
    diff_soothed_expr = "x {neutral} - y {neutral} - * 0 < x {neutral} - {const} / {kp} * {neutral} + " \
                        "x {neutral} - abs y {neutral} - abs > " \
                        "x {kp} * y {const} {kp} - * + {const} / x ? ?".format(neutral=neutral, const=const, kp=kp)
    diff_soothed = core.std.Expr([diff, diff_soften], diff_soothed_expr)
    clip_soothed = core.std.MakeDiff(src, diff_soothed)
    return clip_soothed
예제 #20
0
def temporal_stabilize(clip, src, delta=3, pel=1, retain=0.6):
    core = vs.get_core()
    clip_bits = clip.format.bits_per_sample
    src_bits = src.format.bits_per_sample
    if clip_bits != src_bits:
        raise ValueError(MODULE_NAME + ': temporal_stabilize: bits depth of clip and src mismatch.')
    if delta not in [1, 2, 3]:
        raise ValueError(MODULE_NAME + ': temporal_stabilize: delta (1~3) invalid.')

    diff = core.std.MakeDiff(src, clip)
    clip_super = core.mv.Super(clip, pel=pel)
    diff_super = core.mv.Super(diff, pel=pel, levels=1)

    backward_vectors = [core.mv.Analyse(clip_super, isb=True, delta=i+1, overlap=8, blksize=16) for i in range(delta)]
    forward_vectors = [core.mv.Analyse(clip_super, isb=False, delta=i+1, overlap=8, blksize=16) for i in range(delta)]
    vectors = [vector for vector_group in zip(backward_vectors, forward_vectors) for vector in vector_group]

    stabilize_func = {
        1: core.mv.Degrain1,
        2: core.mv.Degrain2,
        3: core.mv.Degrain3
    }
    diff_stabilized = stabilize_func[delta](diff, diff_super, *vectors)

    neutral = 1 << (clip_bits - 1)
    expr = 'x {neutral} - abs y {neutral} - abs < x y ?'.format(neutral=neutral)
    diff_stabilized_limited = core.std.Expr([diff, diff_stabilized], expr)
    diff_stabilized = core.std.Merge(diff_stabilized_limited, diff_stabilized, retain)
    clip_stabilized = core.std.MakeDiff(src, diff_stabilized)
    return clip_stabilized
예제 #21
0
def daa(clip, mode=-1, opencl=False):
    core = vs.get_core()
    if opencl is True:
        try:
            daa_nnedi3 = core.nnedi3cl.NNEDI3CL
        except AttributeError:
            daa_nnedi3 = core.nnedi3.nnedi3
    else:
        try:
            daa_nnedi3 = core.znedi3.nnedi3
        except AttributeError:
            daa_nnedi3 = core.nnedi3.nnedi3
    if mode == -1:
        nn = daa_nnedi3(clip, field=3)
        nnt = daa_nnedi3(core.std.Transpose(clip), field=3).std.Transpose()
        clph = core.std.Merge(core.std.SelectEvery(nn, cycle=2, offsets=0),
                              core.std.SelectEvery(nn, cycle=2, offsets=1))
        clpv = core.std.Merge(core.std.SelectEvery(nnt, cycle=2, offsets=0),
                              core.std.SelectEvery(nnt, cycle=2, offsets=1))
        clp = core.std.Merge(clph, clpv)
    elif mode == 1:
        nn = daa_nnedi3(clip, field=3)
        clp = core.std.Merge(core.std.SelectEvery(nn, cycle=2, offsets=0),
                             core.std.SelectEvery(nn, cycle=2, offsets=1))
    elif mode == 2:
        nnt = daa_nnedi3(core.std.Transpose(clip), field=3).std.Transpose()
        clp = core.std.Merge(core.std.SelectEvery(nnt, cycle=2, offsets=0),
                             core.std.SelectEvery(nnt, cycle=2, offsets=1))
    else:
        raise ValueError(MODULE_NAME + ': daa: at least one direction should be processed.')
    return clp
예제 #22
0
def padding (src, left=0, right=0, top=0, bottom=0):
    core            = vs.get_core ()
    resample        = core.fmtc.resample
    w               = src.width
    h               = src.height
    clip            = resample (src, w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom, kernel="point", **fmtc_args)
    return clip
예제 #23
0
def Resize16nr (src, w=None, h=None, sx=0, sy=0, sw=0, sh=0, kernel="spline36", kernelh=None, kernelv=None, fh=1, fv=1, taps=4, a1=None, a2=None, a3=None, kovrspl=1, cnorm=True, center=True, fulls=None, fulld=None, cplace="mpeg2", invks=False, invkstaps=4, noring=True):
    core    = vs.get_core ()
    w       = src.width if w is None else w
    h       = src.height if h is None else h
    kernelh = kernel if kernelh is None else kernelh
    kernelv = kernel if kernelv is None else kernelv
    sr_h    = float (w / src.width)
    sr_v    = float (h / src.height)
    sr_up   = max (sr_h, sr_v)
    sr_dw   = 1.0 / min (sr_h, sr_v)
    sr      = max (sr_up, sr_dw)

    thr   = 2.5
    nrb   = (sr > thr)
    nrf   = (sr < thr + 1.0 and noring)
    nrr   = min (sr - thr, 1.0) if nrb else 1.0
    nrv   = [round ((1.0 - nrr) * 65535), round ((1.0 - nrr) * 65535), round ((1.0 - nrr) * 65535)] if nrb else [0, 0, 0]
    nrm   = core.std.BlankClip (clip=src, width=w, height=h, color=nrv) if nrb and nrf else 0

    main  = core.fmtc.resample (src, w=w, h=h, sx=sx, sy=sy, sw=sw, sh=sh, kernel=kernel, kernelh=kernelh, kernelv=kernelv, fh=fh, fv=fv, taps=taps, a1=a1, a2=a2, a3=a3, kovrspl=kovrspl, cnorm=cnorm, center=center, fulls=fulls, fulld=fulld, cplace=cplace, invks=invks, invkstaps=invkstaps)
    nrng  = core.fmtc.resample (src, w=w, h=h, sx=sx, sy=sy, sw=sw, sh=sh, kernel="gauss", a1=100, center=center, fulls=fulls, fulld=fulld, cplace=cplace) if nrf else main

    clip  = core.rgvs.Repair (main, nrng, 1) if nrf else main
    clip  = core.std.MaskedMerge (main, clip, nrm) if nrf and nrb else clip
    return clip
예제 #24
0
def deconvolution (src, loop=2, lowpass=8, a=32, h=12.8, thr=0.00390625, elast=None):
    core            = vs.get_core ()
    Deconv          = core.vcfreq.Sharp
    dcv             = Deconv (src, **deconv_args)
    clip            = hipass (src, dcv, p=lowpass)
    loop            = loop - 1
    return halonr (clip, a, h, thr, elast, lowpass) if loop == 0 else deconvolution (clip, loop, lowpass, a, h, thr, elast)
예제 #25
0
    def dec_txt60mc (src,frame_ref, srcbob=False,draft=False,tff=None):

	core = vs.get_core()

	field_ref = frame_ref if srcbob else frame_ref * 2
	field_ref =      field_ref  % 5
	invpos    = (5 - field_ref) % 5
	pel       = 1 if draft else 2
 
	if srcbob:
		last = src
	elif draft:
		last = haf.Bob(src,tff=tff)  
	else:
		last = haf.QTGMC(src,SourceMatch=3, Lossless=2, TR0=1, TR1=1, TR2=1,TFF=tff)  

     	
	if invpos > 3:
		clean  = core.std.AssumeFPS(core.std.Trim(last, 0, 0)+core.std.SelectEvery(last,5, 8 - invpos), fpsnum=12000, fpsden=1001)
	else:
		clean = core.std.SelectEvery(last,5, 4 - invpos)
	if invpos > 1:
		jitter = core.std.AssumeFPS(core.std.Trim(last, 0, 0)+core.std.SelectEvery(last,5, [6 - invpos, 5 - invpos]), fpsnum=24000, fpsden=1001)
	else:
		jitter = core.std.SelectEvery(last,5, [1 - invpos, 2 - invpos])
		
	jsup   = core.mv.Super(jitter,pel=pel)
	vect_f = core.mv.Analyse (jsup,isb=False, delta=1, overlap=4)
	vect_b = core.mv.Analyse (jsup,isb=True,  delta=1, overlap=4)
	comp   = core.mv.FlowInter (jitter,jsup, vect_b, vect_f, time=50, thscd1=400)
	fixed  = core.std.SelectEvery (comp,2, 0)
	last   = core.std.Interleave ([fixed, clean])
	return last[invpos // 3:]
예제 #26
0
def subtofull (src, cplace="mpeg2"):
    core            = vs.get_core ()
    resample        = core.fmtc.resample
    Expr            = core.std.Expr
    ShufflePlanes   = core.std.ShufflePlanes
    factor_w        = src.format.subsampling_w
    factor_h        = src.format.subsampling_h
    def inline_pel_422 (src):
        NNEDI       = core.nnedi3.nnedi3
        Transpose   = core.std.Transpose
        clip        = Transpose (NNEDI (Transpose (src), **nnedi_args))
        return clip
    srcy            = ShufflePlanes (src, 0, vs.GRAY)
    srcu            = Expr (ShufflePlanes (src, 1, vs.GRAY), "x 0.5 +")
    srcv            = Expr (ShufflePlanes (src, 2, vs.GRAY), "x 0.5 +")
    if factor_w == 1 and factor_h == 1:
       unew         = genpelclip (srcu, pel=2)
       vnew         = genpelclip (srcv, pel=2)
       if cplace == "mpeg2":
          ushift    = resample (unew, sx=0, sy=-0.5, kernel="spline", taps=6, **fmtc_args)
          vshift    = resample (vnew, sx=0, sy=-0.5, kernel="spline", taps=6, **fmtc_args)
       elif cplace == "mpeg1":
          ushift    = resample (unew, sx=-0.5, sy=-0.5, kernel="spline", taps=6, **fmtc_args)
          vshift    = resample (vnew, sx=-0.5, sy=-0.5, kernel="spline", taps=6, **fmtc_args)
       else:
          raise ValueError ("wtf?")
    if factor_w == 1 and factor_h == 0:
       unew         = inline_pel_422 (srcu)
       vnew         = inline_pel_422 (srcv)
       ushift       = resample (unew, sx=1, sy=0, kernel="spline", taps=6, **fmtc_args)
       vshift       = resample (vnew, sx=1, sy=0, kernel="spline", taps=6, **fmtc_args)
    ufinal          = Expr (ushift, "x 0.5 -")
    vfinal          = Expr (vshift, "x 0.5 -")
    clip            = ShufflePlanes ([srcy, ufinal, vfinal], [0, 0, 0], vs.YUV)
    return clip
예제 #27
0
def naa(c, ss=2, chroma=False):
    """
    naa - antialiasing function using nnedi3 +++++++++++++++++++++++++++++++++
        ss: supersampling value, must be even.
        cp: if false chroma will not be altered.
    """
    core = vs.get_core()

    if ss % 2 != 0:
        raise ValueError('ss must be an even number.')

    src = c

    if chroma is False:
        c = vsh.get_luma(c)

    if c.format.bits_per_sample > 8:
        fapprox = 12
    else:
        fapprox = 7

    ret = core.nnedi3.nnedi3_rpow2(clip=c, rfactor=ss, correct_shift=1, qual=2, fapprox=fapprox, nsize=6)
    ret = core.nnedi3.nnedi3(clip=ret, field=0, nns=2, fapprox=fapprox, nsize=6)
    ret = core.std.Transpose(ret)
    ret = core.nnedi3.nnedi3(clip=ret, field=0, nns=2, fapprox=fapprox, nsize=6)
    ret = core.std.Transpose(ret)
    ret = core.fmtc.resample(ret, c.width, c.height)

    if ret.format.bits_per_sample != c.format.bits_per_sample:
        ret = core.fmtc.bitdepth(ret, bits=c.format.bits_per_sample)

    if chroma is False:
        ret = vsh.merge_chroma(ret, src)

    return ret
예제 #28
0
 def __init__(self):
     self.core            = vs.get_core()
     self.MSuper          = self.core.mvsf.Super
     self.MAnalyze        = mvmulti.Analyze
     self.MRecalculate    = mvmulti.Recalculate
     self.MDegrainN       = mvmulti.DegrainN
     self.RGB2OPP         = self.core.bm3d.RGB2OPP
     self.OPP2RGB         = self.core.bm3d.OPP2RGB
     self.BMBasic         = self.core.bm3d.VBasic
     self.BMFinal         = self.core.bm3d.VFinal
     self.Aggregate       = self.core.bm3d.VAggregate
     self.DFTTest         = self.core.dfttest.DFTTest
     self.KNLMeansCL      = self.core.knlm.KNLMeansCL
     self.NNEDI           = self.core.nnedi3.nnedi3
     self.Resample        = self.core.fmtc.resample
     self.Expr            = self.core.std.Expr
     self.MakeDiff        = self.core.std.MakeDiff
     self.MergeDiff       = self.core.std.MergeDiff
     self.Crop            = self.core.std.CropRel
     self.CropAbs         = self.core.std.CropAbs
     self.Transpose       = self.core.std.Transpose
     self.BlankClip       = self.core.std.BlankClip
     self.AddBorders      = self.core.std.AddBorders
     self.StackHorizontal = self.core.std.StackHorizontal
     self.StackVertical   = self.core.std.StackVertical
     self.MaskedMerge     = self.core.std.MaskedMerge
     self.ShufflePlanes   = self.core.std.ShufflePlanes
     self.SetFieldBased   = self.core.std.SetFieldBased
예제 #29
0
def replace_range(clip1, clip2, start, end=None):
    """ Replaces a range of frames of a clip with the same range of
    frames from another clip.
    If no end frame is given, it will only replace the start frame.
    """
    core = vs.get_core()

    if end is None:
        end = start

    if start < 0 or start > clip1.num_frames - 1:
        raise ValueError('start frame out of bounds: {}.'.format(start))
    if end < start or end > clip1.num_frames - 1:
        raise ValueError('end frame out of bounds: {}.'.format(end))

    if start > 0:
        temp = 'core.std.Trim(clip1, 0, start - 1) + '
    else:
        temp = ''
    temp += 'core.std.Trim(clip2, start, end)'
    if end < clip1.num_frames - 1:
        temp += '+ core.std.Trim(clip1, end + 1)'

    final = eval(temp)

    if clip1.num_frames != final.num_frames:
        raise ValueError('input / output framecount missmatch (got: {}; expected: {}).'
                         .format(final.num_frames, clip1.num_frames))

    return final
예제 #30
0
def RestoreDepth(LowDepth, HighDepth, diffmask=None, dmode=None, planes=[0, 1, 2]):
    
    core = vs.get_core() 
    
    lowbits = LowDepth.format.bits_per_sample
    highbits = HighDepth.format.bits_per_sample
    
    DownscaledDepth = core.fmtc.bitdepth(HighDepth,bits=lowbits,dmode=dmode)
    
    Yexpr = ("x y - abs 0 > " + str(pow(2,lowbits)-1) + " 0 ?") if 0 in planes else ""
    Uexpr = ("x y - abs 0 > " + str(pow(2,lowbits)-1) + " 0 ?") if 1 in planes else ""
    Vexpr = ("x y - abs 0 > " + str(pow(2,lowbits)-1) + " 0 ?") if 2 in planes else ""
    
    if isinstance(diffmask, vs.VideoNode) == False:
        diffmask = core.std.Expr(clips=[LowDepth, DownscaledDepth], expr=[Yexpr, Uexpr, Vexpr])
    
    UpscaledDepth = core.fmtc.bitdepth(LowDepth,bits=highbits)
    UpscaledMask = core.fmtc.bitdepth(diffmask,bits=highbits)
    
    return core.std.MaskedMerge(HighDepth, UpscaledDepth, UpscaledMask,planes=planes)
    
	# original script by Torchlight and Firesledge(?)
	# port by BakaProxy
	# bob and qtgmc from HavsFunc is used 
    # what is this used for again?    

    def dec_txt60mc (src,frame_ref, srcbob=False,draft=False,tff=None):

	core = vs.get_core()

	field_ref = frame_ref if srcbob else frame_ref * 2
	field_ref =      field_ref  % 5
	invpos    = (5 - field_ref) % 5
	pel       = 1 if draft else 2
 
	if srcbob:
		last = src
	elif draft:
		last = haf.Bob(src,tff=tff)  
	else:
		last = haf.QTGMC(src,SourceMatch=3, Lossless=2, TR0=1, TR1=1, TR2=1,TFF=tff)  

     	
	if invpos > 3:
		clean  = core.std.AssumeFPS(core.std.Trim(last, 0, 0)+core.std.SelectEvery(last,5, 8 - invpos), fpsnum=12000, fpsden=1001)
	else:
		clean = core.std.SelectEvery(last,5, 4 - invpos)
	if invpos > 1:
		jitter = core.std.AssumeFPS(core.std.Trim(last, 0, 0)+core.std.SelectEvery(last,5, [6 - invpos, 5 - invpos]), fpsnum=24000, fpsden=1001)
	else:
		jitter = core.std.SelectEvery(last,5, [1 - invpos, 2 - invpos])
		
	jsup   = core.mv.Super(jitter,pel=pel)
	vect_f = core.mv.Analyse (jsup,isb=False, delta=1, overlap=4)
	vect_b = core.mv.Analyse (jsup,isb=True,  delta=1, overlap=4)
	comp   = core.mv.FlowInter (jitter,jsup, vect_b, vect_f, time=50, thscd1=400)
	fixed  = core.std.SelectEvery (comp,2, 0)
	last   = core.std.Interleave ([fixed, clean])
	return last[invpos // 3:]
예제 #31
0
def nnedi3_dh(input,
              field=1,
              nsize=None,
              nns=None,
              qual=None,
              etype=None,
              pscrn=None,
              opt=None,
              int16_prescreener=None,
              int16_predictor=None,
              exp=None):
    core = vs.get_core()
    return core.nnedi3.nnedi3(input,
                              field=field,
                              dh=True,
                              nsize=nsize,
                              nns=nns,
                              qual=qual,
                              etype=etype,
                              pscrn=pscrn,
                              opt=opt,
                              int16_prescreener=int16_prescreener,
                              int16_predictor=int16_predictor,
                              exp=exp)
예제 #32
0
    def select_best_chunking_method(self):
        """
        Selecting best chunking method based on available methods
        """
        if not find_executable('vspipe'):
            self.chunk_method = 'hybrid'
            log('Set Chunking Method: Hybrid')
        else:
            try:
                import vapoursynth
                plugins = vapoursynth.get_core().get_plugins()

                if 'systems.innocent.lsmas' in plugins:
                    log('Set Chunking Method: L-SMASH\n')
                    self.chunk_method = 'vs_lsmash'

                elif 'com.vapoursynth.ffms2' in plugins:
                    log('Set Chunking Method: FFMS2\n')
                    self.chunk_method = 'vs_ffms2'

            except:
                log('Vapoursynth not installed but vspipe reachable\n' +
                    'Fallback to Hybrid\n')
                self.chunk_method = 'hybrid'
예제 #33
0
def blank_it(src, start, end=None, color='black'):
    """ Blanks a range of frames in a clip, by default to pure balck.
    If no endframe is provided start frame will be used.
    """
    core = vs.get_core()

    if end is None:
        end = start

    e = core.std.BlankClip(src, color=color)

    if start != 0:
        z = src[:start] + e[start:end + 1]
    else:
        z = e[start:end + 1]
    if end < src.num_frames - 1:
        z = z + src[end + 1:]

    if src.num_frames != z.num_frames:
        raise ValueError(
            'input / output framecount missmatch (got: {}; expected: {}).'.
            format(z.num_frames, src.num_frames))

    return z
예제 #34
0
def assrenderwrapper(clip,
                     data,
                     charset=None,
                     debuglevel=None,
                     fontdir=None,
                     linespacing=None,
                     margins=None,
                     sar=None,
                     scale=None):
    core = vs.get_core()

    subs = core.assvapour.AssRender(clip=clip,
                                    data=data,
                                    charset=charset,
                                    debuglevel=debuglevel,
                                    fontdir=fontdir,
                                    linespacing=linespacing,
                                    margins=margins,
                                    sar=sar,
                                    scale=scale)
    subs[0] = core.resize.Bicubic(subs[0], format=clip.format.id)
    subs[1] = core.resize.Bicubic(subs[1], format=clip.format.id)

    return core.std.MaskedMerge(clipa=clip, clipb=subs[0], mask=subs[1])
예제 #35
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.')
예제 #36
0
def get_lsb(src):
    core = vs.get_core()
    clip = core.fmtc.nativetostack16(src)
    return core.std.CropRel(clip, 0, 0, (clip.height // 2), 0)
예제 #37
0
def linear_and_gamma(src,
                     l2g_flag=True,
                     fulls=True,
                     fulld=None,
                     curve="srgb",
                     gcor=1.0,
                     sigmoid=False,
                     thr=0.5,
                     cont=6.5):
    core = vs.get_core()
    if curve == "srgb":
        k0 = "0.04045"
        phi = "12.92"
        alpha = "0.055"
        gamma = "2.4"
    elif curve == "709":
        k0 = "0.081"
        phi = "4.5"
        alpha = "0.099"
        gamma = "2.22222"
    elif curve == "240":
        k0 = "0.0912"
        phi = "4.0"
        alpha = "0.1115"
        gamma = "2.22222"
    elif curve == "2020":
        k0 = "0.08145"
        phi = "4.5"
        alpha = "0.0993"
        gamma = "2.22222"
    else:
        k0 = "0.04045"
        phi = "12.92"
        alpha = "0.055"
        gamma = "2.4"

    fulld = fulls if fulld is None else fulld

    if fulls == False:
        expr = "x 4096 - 56064 /"
    else:
        expr = "x 65536 /"

    g2l = "{expr} {k0} <= {expr} {phi} / {expr} {alpha} + 1 {alpha} + / log {gamma} * exp ?".format(
        expr=expr, k0=k0, phi=phi, alpha=alpha, gamma=gamma)

    if gcor != 1.0:
        g2l = "{g2l} 0 >= {g2l} log {gcor} * exp {g2l} ?".format(g2l=g2l,
                                                                 gcor=gcor)

    if sigmoid:
        g2l = build_sigmoid_expr(g2l, True, thr, cont)
        l2g = build_sigmoid_expr(expr, False, thr, cont)
    else:
        l2g = expr

    if gcor != 1.0:
        l2g = "{l2g} 0 >= {l2g} log {gcor} * exp {l2g} ?".format(l2g=l2g,
                                                                 gcor=gcor)

    l2g = "{l2g} {k0} {phi} / <= {l2g} {phi} * {l2g} log 1 {gamma} / * exp {alpha} 1 + * {alpha} - ?".format(
        l2g=l2g, k0=k0, phi=phi, alpha=alpha, gamma=gamma)

    if l2g_flag:
        expr = l2g
    else:
        expr = g2l

    if fulld == False:
        expr = expr + " 56064 * 4096 +"
    else:
        expr = expr + " 65536 *"

    clip = core.std.Expr([src], [expr])
    return clip
예제 #38
0
def merge16_8(src1, src2, mask):
    core = vs.get_core()
    mask16 = core.fmtc.bitdepth(mask, bits=16, fulls=True, fulld=True)
    clip = core.std.MaskedMerge(src1, src2, mask16)
    return clip
예제 #39
0
def sigmoid_inverse(src, thr=0.5, cont=6.5):
    core = vs.get_core()
    expr = build_sigmoid_expr("x 65536 /", True, thr, cont)
    clip = core.std.Expr([src], [expr + " 65536 *"])
    return clip
예제 #40
0
 def setUp(self):
     self.core = vs.get_core()
     self.Lut = self.core.std.Lut
     self.Lut2 = self.core.std.Lut2
     self.BlankClip = self.core.std.BlankClip
     self.mask = lambda val, bits: val & ((1 << bits) - 1)
예제 #41
0
def BalanceBorders(c, cTop, cBottom, cLeft, cRight, thresh=128, blur=999):
    funcname = "BalanceBorders"

    if not isinstance(c, vs.VideoNode):
        raise TypeError(funcname + ': This is not a clip.')

    if c.format.color_family != vs.YUV:
        raise TypeError(funcname + ': Clip must be YUV family.')

    if c.format.sample_type != vs.INTEGER:
        raise TypeError(funcname + ': Clip must be integer format.')

    if thresh < 0 or thresh > 128:
        raise ValueError(funcname + ': \"thresh\" must between 0 and 128.')

    if blur < 0:
        raise ValueError(funcname + ': \"blur\" must greater than 0.')

    del funcname
    core = vs.get_core()

    def BalanceTopBorder(c, cTop, thresh, blur):
        cWidth = c.width
        cHeight = c.height
        cTop = min(cTop, cHeight - 1)
        BlurWidth = max(4, math.floor(cWidth / blur))

        C2 = core.resize.Point(c, cWidth << 1, cHeight << 1)

        C3 = core.std.CropRel(
            C2, 0, 0, cTop << 1,
            (cHeight - cTop - 1) << 1)  #(cHeight * 2 - cTop * 2) - 2
        C3 = core.resize.Point(C3, cWidth << 1, cTop << 1)
        C3 = core.resize.Bilinear(C3, BlurWidth << 1, cTop << 1)
        C3 = core.std.Convolution(C3,
                                  matrix=[0, 0, 0, 1, 1, 1, 0, 0, 0],
                                  planes=[0, 1, 2])
        ReferenceBlur = core.resize.Bilinear(C3, cWidth << 1, cTop << 1)

        Original = core.std.CropRel(
            C2, 0, 0, 0, (cHeight - cTop) << 1)  #cHeight * 2 - 0 - cTop * 2

        C3 = core.resize.Bilinear(Original, BlurWidth << 1, cTop << 1)
        C3 = core.std.Convolution(C3,
                                  matrix=[0, 0, 0, 1, 1, 1, 0, 0, 0],
                                  planes=[0, 1, 2])
        OriginalBlur = core.resize.Bilinear(C3, cWidth << 1, cTop << 1)
        del C3

        Balanced = core.std.Expr(clips=[Original, OriginalBlur, ReferenceBlur],
                                 expr=["z y - x +", "z y - x +", "z y - x +"])
        del OriginalBlur
        del ReferenceBlur
        Difference = core.std.MakeDiff(Balanced, Original, planes=[0, 1, 2])
        del Balanced

        Tp = (128 + thresh) * (
            (1 << c.format.bits_per_sample) - 1) * 0.004  # 1 / 255 = 0.004
        Tm = (128 - thresh) * ((1 << c.format.bits_per_sample) - 1) * 0.004

        expr = 'x {0} > {0} x ?'.format(Tp)
        Difference = core.std.Expr(clips=Difference, expr=[expr, expr, expr])
        expr = 'x {0} < {0} x ?'.format(Tm)
        Difference = core.std.Expr(clips=Difference, expr=[expr, expr, expr])
        del expr
        del Tp
        del Tm

        res = core.std.MergeDiff(Original, Difference, planes=[0, 1, 2])
        del Difference

        res = core.std.StackVertical(
            clips=[res, core.std.CropRel(C2, 0, 0, cTop * 2, 0)])
        #cHeight * 2 - cTop * 2 - (cHeight - cTop) * 2 = 0
        return core.resize.Point(res, cWidth, cHeight)

    res = BalanceTopBorder(
        c, cTop, thresh, blur).std.Transpose().std.FlipHorizontal(
        ) if cTop > 0 else core.std.Transpose(c).std.FlipHorizontal()
    res = BalanceTopBorder(
        res, cLeft, thresh, blur).std.Transpose().std.FlipHorizontal(
        ) if cLeft > 0 else core.std.Transpose(res).std.FlipHorizontal()
    res = BalanceTopBorder(
        res, cBottom, thresh, blur).std.Transpose().std.FlipHorizontal(
        ) if cBottom > 0 else core.std.Transpose(res).std.FlipHorizontal()
    res = BalanceTopBorder(
        res, cRight, thresh, blur).std.Transpose().std.FlipHorizontal(
        ) if cRight > 0 else core.std.Transpose(res).std.FlipHorizontal()

    return res
예제 #42
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
예제 #43
0
def inputs(config, files, is_training=False, is_testing=False):
    # parameters
    channels = config.in_channels
    threads = config.threads
    threads_py = config.threads_py
    scaling = config.scaling
    if is_training: num_epochs = config.num_epochs
    data_format = config.data_format
    patch_height = config.patch_height
    patch_width = config.patch_width
    batch_size = config.batch_size
    if is_training: buffer_size = config.buffer_size
    epoch_size = len(files)

    # dataset mapping function
    def parse1_func(filename):
        # read data
        dtype = tf.float32
        image = tf.read_file(filename)
        image = tf.image.decode_image(image, channels=channels)
        shape = tf.shape(image)
        height = shape[-3]
        width = shape[-2]
        # pre down-scale for high resolution image
        dscale = 1
        if is_training and config.pre_down:
            '''
            if (width >= 3072 and height >= 1536) or (width >= 1536 and height >= 3072):
                dscale = 3
            elif (width >= 1024 and height >= 512) or (width >= 512 and height >= 1024):
                dscale = 2
            '''
            def c_t(const1, const2, true_fn, false_fn):
                return tf.cond(tf.logical_or(
                    tf.logical_and(
                        tf.greater_equal(width, const1), tf.greater_equal(height, const2)
                    ),
                    tf.logical_and(
                        tf.greater_equal(width, const2), tf.greater_equal(height, const1)
                    )
                ), true_fn, false_fn)
            dscale = c_t(3072, 1536, lambda: 3,
                lambda: c_t(1024, 512, lambda: 2, lambda: 1)
            )
        elif is_testing and config.pre_down:
            '''
            if (width >= 3072 and height >= 3072):
                dscale = 4
            elif (width >= 2048 and height >= 2048):
                dscale = 3
            elif (width >= 1024 and height >= 1024):
                dscale = 2
            '''
            def c_t(const1, true_fn, false_fn):
                return tf.cond(tf.logical_and(
                    tf.greater_equal(width, const1), tf.greater_equal(height, const1)
                ), true_fn, false_fn)
            dscale = c_t(3072, lambda: 4,
                lambda: c_t(2048, lambda: 3,
                    lambda: c_t(1024, lambda: 2, lambda: 1)
                )
            )
        # padding
        cropped_height = patch_height * dscale
        cropped_width = patch_width * dscale
        '''
        if cropped_height > height or cropped_width > width:
            pad_height = cropped_height - height
            pad_width = cropped_width - width
            if pad_height > 0:
                pad_height = [pad_height // 2, pad_height - pad_height // 2]
                height = cropped_height
            else:
                pad_height = [0, 0]
            if pad_width > 0:
                pad_width = [pad_width // 2, pad_width - pad_width // 2]
                width = cropped_width
            else:
                pad_width = [0, 0]
            block = tf.pad(image, [pad_height, pad_width, [0, 0]], mode='REFLECT')
        else:
            block = image
        '''
        cond_height = tf.greater(cropped_height, height)
        cond_width = tf.greater(cropped_width, width)
        def c_f1():
            def _1():
                ph = cropped_height - height
                return [ph // 2, ph - ph // 2]
            pad_height = tf.cond(cond_height, _1, lambda: [0, 0])
            def _2():
                pw = cropped_width - width
                return [pw // 2, pw - pw // 2]
            pad_width = tf.cond(cond_width, _2, lambda: [0, 0])
            return tf.pad(image, [pad_height, pad_width, [0, 0]], mode='REFLECT')
        block = tf.cond(tf.logical_or(cond_height, cond_width), c_f1, lambda: image)
        height = tf.maximum(cropped_height, height)
        width = tf.maximum(cropped_width, width)
        # cropping
        if is_training:
            block = tf.random_crop(block, [cropped_height, cropped_width, channels])
            block = tf.image.random_flip_up_down(block)
            block = tf.image.random_flip_left_right(block)
        elif is_testing:
            offset_height = (height - cropped_height) // 2
            offset_width = (width - cropped_width) // 2
            block = tf.image.crop_to_bounding_box(block, offset_height, offset_width,
                                                  cropped_height, cropped_width)
        # convert dtype
        block = tf.image.convert_image_dtype(block, dtype, saturate=False)
        # random color augmentation
        if is_training and config.color_augmentation > 0:
            block = tf.image.random_saturation(block, 1 - config.color_augmentation, 1 + config.color_augmentation)
            block = tf.image.random_brightness(block, config.color_augmentation)
            block = tf.image.random_contrast(block, 1 - config.color_augmentation, 1 + config.color_augmentation)
        # data format conversion
        block.set_shape([None, None, channels])
        if data_format == 'NCHW':
            block = tf.transpose(block, (2, 0, 1))
        # return
        return block
    
    # tf.py_func processing using vapoursynth, numpy, etc.
    import threading
    import vapoursynth as vs
    from scipy import ndimage
    
    def eval_random_select(n, clips):
        rand_idx = np.random.randint(0, len(clips))
        return clips[rand_idx]
    
    def SigmoidInverse(clip, thr=0.5, cont=6.5, epsilon=1e-6):
        assert clip.format.sample_type == vs.FLOAT
        x0 = 1 / (1 + np.exp(cont * thr))
        x1 = 1 / (1 + np.exp(cont * (thr - 1)))
        # thr - log(max(1 / max(x * (x1 - x0) + x0, epsilon) - 1, epsilon)) / cont
        expr = '{thr} 1 x {x1_x0} * {x0} + {epsilon} max / 1 - {epsilon} max log {cont_rec} * -'.format(thr=thr, cont_rec=1 / cont, epsilon=epsilon, x0=x0, x1_x0=x1 - x0)
        return clip.std.Expr(expr)
    
    def SigmoidDirect(clip, thr=0.5, cont=6.5):
        assert clip.format.sample_type == vs.FLOAT
        x0 = 1 / (1 + np.exp(cont * thr))
        x1 = 1 / (1 + np.exp(cont * (thr - 1)))
        # (1 / (1 + exp(cont * (thr - x))) - x0) / (x1 - x0)
        expr = '1 1 {cont} {thr} x - * exp + / {x0} - {x1_x0_rec} *'.format(thr=thr, cont=cont, x0=x0, x1_x0_rec=1 / (x1 - x0))
        return clip.std.Expr(expr)
    
    _lock = threading.Lock()
    _index_ref = [0]
    _src_ref = [None for _ in range(epoch_size)]
    core = vs.get_core(threads=1 if is_testing else threads_py)
    core.max_cache_size = 8000
    _dscales = list(range(1, 5)) if config.pre_down else [1]
    _src_blk = [core.std.BlankClip(None, patch_width * s, patch_height * s,
                                   format=vs.RGBS, length=epoch_size)
                for s in _dscales]
    _dst_blk = core.std.BlankClip(None, patch_width // scaling, patch_height // scaling,
                                 format=vs.RGBS, length=epoch_size)
    
    def src_frame_func(n, f):
        f_out = f.copy()
        planes = f_out.format.num_planes
        # output
        for p in range(planes):
            f_arr = np.array(f_out.get_write_array(p), copy=False)
            np.copyto(f_arr, _src_ref[n][p, :, :] if data_format == 'NCHW' else _src_ref[n][:, :, p])
        # set frame properties
        f_out.props['_Primaries'] = 1 # BT.709
        f_out.props['_Transfer'] = 1 # BT.709
        return f_out
    _srcs = [s.std.ModifyFrame(s, src_frame_func) for s in _src_blk]
    _srcs_linear = [s.resize.Bicubic(transfer_s='linear') for s in _srcs]
    
    def src_down_func(clip):
        dw = patch_width
        dh = patch_height
        if clip.width != dw or clip.height != dh:
            clip = SigmoidInverse(clip)
            clip = clip.resize.Bicubic(dw, dh, filter_param_a=0, filter_param_b=0.5)
            clip = SigmoidDirect(clip)
        return clip
    if config.pre_down:
        _srcs_linear = [src_down_func(s) for s in _srcs_linear]
        _srcs = _srcs[0:1] + [s.resize.Bicubic(transfer_s='709')
                                   for s in _srcs_linear[1:]]
    
    def src_select_eval(n):
        # select source
        shape = _src_ref[n].shape
        sh = shape[-2 if data_format == 'NCHW' else -3]
        dscale = sh // patch_height
        # downscale if needed
        clip = _srcs[dscale - 1]
        return clip
    if config.pre_down:
        _src = _src_blk[0].std.FrameEval(src_select_eval)
    else:
        _src = _srcs[0]
    
    def resize_set_func(clip, convert_linear=False):
        # disable resize set when scaling=1
        if scaling == 1:
            return clip
        # parameters
        dw = int(patch_width / scaling + 0.5)
        dh = int(patch_height / scaling + 0.5)
        rets = {}
        # resizers
        rets['bilinear'] = clip.resize.Bilinear(dw, dh)
        rets['spline16'] = clip.resize.Spline16(dw, dh)
        rets['spline36'] = clip.resize.Spline36(dw, dh)
        for taps in range(2, 12):
            rets['lanczos{}'.format(taps)] = clip.resize.Lanczos(dw, dh, filter_param_a=taps)
        # linear to gamma
        if convert_linear:
            for key in rets:
                rets[key] = rets[key].resize.Bicubic(transfer_s='709', transfer_in_s='linear')
        return rets
    
    def resize_eval(n, src, src_linear, resizes, linear_resizes, dscale=None):
        # select source
        if dscale is True:
            shape = _src_ref[n].shape
            sh = shape[-2 if data_format == 'NCHW' else -3]
            dscale = max(1, sh // patch_height)
        if dscale:
            src = src[dscale - 1]
            src_linear = src_linear[dscale - 1]
            resizes = resizes[dscale - 1]
            linear_resizes = linear_resizes[dscale - 1]
        # initialize
        clip = src
        # multiple stages
        max_iter = config.multistage_resize * 2
        if scaling != 1: max_iter += 1
        for _ in range(max_iter):
            downscale = _ % 2 == 0
            # randomly skip multistage resize
            scaling_match = _ % 2 == 0 if scaling == 1 else _ % 2 == 1 # whether the last scaling matches output size
            if _ > 0 and scaling_match and np.random.uniform(0, 1) < 0.7:
                break
            # scaling size
            if scaling == 1:
                scaling1 = 1
                while scaling1 < 4 / 3: # [4 / 3, ~2)
                    scaling1 = 2 ** np.random.normal(0.6, 0.2)
            else:
                scaling1 = scaling
            dw = int(patch_width / scaling1 + 0.5) if downscale else patch_width
            dh = int(patch_height / scaling1 + 0.5) if downscale else patch_height
            use_resize_set = scaling != 1 and _ == 0
            # random number generator
            rand_val = np.random.uniform(-1, 1) if config.random_resizer == 0 else config.random_resizer
            abs_rand = np.abs(rand_val)
            # random gamma-to-linear
            if _ == 0:
                clip = src_linear if rand_val < 0 else src
                resizes = linear_resizes if rand_val < 0 else resizes
            # random resizers
            if abs_rand < (0.05 if downscale else 0.05):
                clip = resizes['bilinear'] if use_resize_set else clip.resize.Bilinear(dw, dh)
            elif abs_rand < (0.10 if downscale else 0.10):
                clip = resizes['spline16'] if use_resize_set else clip.resize.Spline16(dw, dh)
            elif abs_rand < (0.15 if downscale else 0.15):
                clip = resizes['spline36'] if use_resize_set else clip.resize.Spline36(dw, dh)
            elif abs_rand < (0.25 if downscale else 0.40): # Lanczos taps=[2, 12)
                taps = int(np.clip(np.random.exponential(2) + 2, 2, 11))
                clip = resizes['lanczos{}'.format(taps)] if use_resize_set else clip.resize.Lanczos(dw, dh, filter_param_a=taps)
            elif abs_rand < (0.50 if downscale else 0.50): # Catmull-Rom
                b = 0 if config.random_resizer == 0.4 else np.random.normal(0, 1/6)
                c = (1 - b) * 0.5
                clip = clip.resize.Bicubic(dw, dh, filter_param_a=b, filter_param_b=c)
            elif abs_rand < (0.60 if downscale else 0.60): # Mitchell-Netravali (standard Bicubic)
                b = 1/3 if config.random_resizer == 0.6 else np.random.normal(1/3, 1/6)
                c = (1 - b) * 0.5
                clip = clip.resize.Bicubic(dw, dh, filter_param_a=b, filter_param_b=c)
            elif abs_rand < (0.80 if downscale else 0.70): # sharp Bicubic
                b = -0.5 if config.random_resizer == 0.7 else np.random.normal(-0.5, 0.25)
                c = b * -0.5
                clip = clip.resize.Bicubic(dw, dh, filter_param_a=b, filter_param_b=c)
            elif abs_rand < (0.85 if downscale else 0.80): # soft Bicubic
                b = 0.75 if config.random_resizer == 0.8 else np.random.normal(0.75, 0.25)
                c = 1 - b
                clip = clip.resize.Bicubic(dw, dh, filter_param_a=b, filter_param_b=c)
            elif abs_rand < (1.00 if downscale else 0.90): # arbitrary Bicubic
                b = np.random.normal(0, 0.5)
                c = np.random.normal(0.25, 0.25)
                clip = clip.resize.Bicubic(dw, dh, filter_param_a=b, filter_param_b=c)
            elif abs_rand < (1.00 if downscale else 1.00): # Bicubic with haloing & aliasing
                b = np.random.normal(0, 1) # amount of haloing
                c = -1 # when c is around b * 0.8, aliasing is minimum
                if b >= 0: # with aliasing
                    b = 1 + b
                    while c < 0 or c > b * 1.2:
                        c = np.random.normal(b * 0.4, b * 0.2)
                else: # without aliasing
                    b = 1 - b
                    while c < 0 or c > b * 1.2:
                        c = np.random.normal(b * 0.8, b * 0.2)
                b = -b
                clip = clip.resize.Bicubic(dw, dh, filter_param_a=b, filter_param_b=c)
        # return
        return clip
    
    _resizes = [resize_set_func(s, convert_linear=False) for s in _srcs]
    _linear_resizes = [resize_set_func(s, convert_linear=config.multistage_resize == 0) for s in _srcs_linear]
    _dst = _dst_blk.std.FrameEval(lambda n: resize_eval(n, _srcs, _srcs_linear, _resizes, _linear_resizes, dscale=True))
    _dst = _dst.resize.Bicubic(transfer_s='709') # convert to BT.709 transfer
    
    # chroma subsampling
    def chroma_subsampling(src):
        YUV420PS = core.register_format(vs.YUV, vs.FLOAT, 32, 1, 1)
        src420 = src.resize.Bicubic(format=YUV420PS, matrix_s='709', filter_param_a=0, filter_param_b=0.5)
        clips = [src420.resize.Bilinear(format=vs.RGBS, matrix_in_s='709'),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=1.0, filter_param_b=0.0),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=0.5, filter_param_b=0.5),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=1 / 3, filter_param_b=1 / 3),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=0, filter_param_b=0.5),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=-0.5, filter_param_b=0.25),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=-1, filter_param_b=0.3),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=-1, filter_param_b=0.8),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=-2, filter_param_b=0.6),
                src420.resize.Bicubic(format=vs.RGBS, matrix_in_s='709', filter_param_a=-2, filter_param_b=1.6)]
        clips += [src] * 6
        clip = src.std.FrameEval(lambda n: eval_random_select(n, clips))
        return clip
    _dst = chroma_subsampling(_dst)

    # parser
    def parse2_pyfunc(label):
        channel_index = -3 if data_format == 'NCHW' else -1
        dscale = label.shape[-2 if data_format == 'NCHW' else -3] // patch_height
        # safely acquire and increase shared index
        _lock.acquire()
        index = _index_ref[0]
        _index_ref[0] = (index + 1) % epoch_size
        _lock.release()
        # processing using vs
        _src_ref[index] = label
        if config.pre_down and dscale > 1: f_src = _src.get_frame(index)
        f_dst = _dst.get_frame(index)
        _src_ref[index] = None
        # vs.VideoFrame to np.ndarray
        if config.pre_down and dscale > 1:
            label = []
            planes = f_src.format.num_planes
            for p in range(planes):
                f_arr = np.array(f_src.get_read_array(p), copy=False)
                label.append(f_arr)
            label = np.stack(label, axis=channel_index)
        data = []
        planes = f_dst.format.num_planes
        for p in range(planes):
            f_arr = np.array(f_dst.get_read_array(p), copy=False)
            data.append(f_arr)
        data = np.stack(data, axis=channel_index)
        # add Gaussian noise of random scale and random spatial correlation
        def _add_noise(data, noise_scale, noise_corr):
            # noise spatial correlation
            def noise_correlation(noise, corr):
                if corr > 0:
                    sigma = np.random.normal(corr, corr)
                    if sigma > 0.25:
                        sigma = [0, sigma, sigma] if data_format == 'NCHW' else [sigma, sigma, 0]
                        noise = ndimage.gaussian_filter(noise, sigma, truncate=2.0)
                return noise
            if noise_scale <= 0:
                return data
            rand_val = np.random.uniform(0, 1)
            scale = np.random.exponential(noise_scale)
            if rand_val < 0.2 or scale < 0.002: # won't add noise
                return data
            noise_shape = list(data.shape)
            if rand_val < 0.35: # RGB noise
                noise = np.random.normal(0.0, scale, noise_shape).astype(np.float32)
                noise = noise_correlation(noise, noise_corr)
            else: # Y/YUV noise
                noise_shape[channel_index] = 1
                noise_y = np.random.normal(0.0, scale, noise_shape).astype(np.float32)
                noise_y = noise_correlation(noise_y, noise_corr)
                scale_uv = np.random.exponential(noise_scale / 2)
                if rand_val < 0.55 and scale_uv > 0.002: # YUV noise
                    noise_u = np.random.normal(0.0, scale_uv, noise_shape).astype(np.float32)
                    noise_u = noise_correlation(noise_u, noise_corr * 1.5)
                    noise_v = np.random.normal(0.0, scale_uv, noise_shape).astype(np.float32)
                    noise_v = noise_correlation(noise_v, noise_corr * 1.5)
                    rand_val2 = np.random.uniform(0, 1)
                    if rand_val2 < 0.3: # Rec.601
                        Kr = 0.299
                        Kg = 0.587
                        Kb = 0.114
                    elif rand_val2 < 0.9: # Rec.709
                        Kr = 0.2126
                        Kg = 0.7152
                        Kb = 0.0722
                    else: # Rec.2020
                        Kr = 0.2627
                        Kg = 0.6780
                        Kb = 0.0593
                    noise_r = noise_y + ((1 - Kr) / 2) * noise_v
                    noise_b = noise_y + ((1 - Kb) / 2) * noise_u
                    noise_g = (1 / Kg) * noise_y - (Kr / Kg) * noise_r - (Kb / Kg) * noise_b
                    noise = [noise_r, noise_g, noise_b]
                else:
                    noise = [noise_y, noise_y, noise_y]
                noise = np.concatenate(noise, axis=channel_index)
            # adding noise
            return data + noise
        data = _add_noise(data, config.noise_scale, config.noise_corr)
        # return
        return data, label
    
    def parse3_func(data, label):
        # final process
        data = tf.clip_by_value(data, 0.0, 1.0)
        label = tf.clip_by_value(label, 0.0, 1.0)
        # JPEG encoding
        def _jpeg_coding(data, quality_step, random_seed=None):
            if quality_step <= 0:
                return data
            steps = 16
            prob_step = 0.02
            rand_val = tf.random_uniform([], -1, 1, seed=random_seed)
            abs_rand = tf.abs(rand_val)
            def c_f1(data):
                if data_format == 'NCHW':
                    data = tf.transpose(data, (1, 2, 0))
                data = tf.image.convert_image_dtype(data, tf.uint8, saturate=True)
                def _f1(quality, chroma_ds):
                    quality = int(quality + 0.5)
                    return tf.image.encode_jpeg(data, quality=quality, chroma_downsampling=chroma_ds)
                def _cond_recur(abs_rand, count=15, chroma_ds=False, prob=0.0, quality=100.0):
                    prob += prob_step
                    if count <= 0:
                        return _f1(quality, chroma_ds)
                    else:
                        return tf.cond(abs_rand < prob, lambda: _f1(quality, chroma_ds),
                            lambda: _cond_recur(abs_rand, count - 1, chroma_ds, prob, quality - config.jpeg_coding))
                data = tf.cond(rand_val < 0, lambda: _cond_recur(abs_rand, steps - 1, True),
                    lambda: _cond_recur(abs_rand, steps - 1, False))
                data = tf.image.decode_jpeg(data)
                data = tf.image.convert_image_dtype(data, tf.float32, saturate=False)
                if data_format == 'NCHW':
                    data = tf.transpose(data, (2, 0, 1))
                return data
            return tf.cond(rand_val < prob_step * steps, lambda: c_f1(data), lambda: data)
        data = _jpeg_coding(data, config.jpeg_coding, config.random_seed if is_testing else None)
        # return
        return data, label
    
    # Dataset API
    dataset = tf.data.Dataset.from_tensor_slices((files))
    if is_training and buffer_size > 0: dataset = dataset.shuffle(buffer_size)
    dataset = dataset.map(parse1_func, num_parallel_calls=1 if is_testing else threads)
    dataset = dataset.map(lambda label: tuple(tf.py_func(parse2_pyfunc,
                              [label], [tf.float32, tf.float32])),
                          num_parallel_calls=1 if is_testing else threads_py)
    dataset = dataset.map(parse3_func, num_parallel_calls=1 if is_testing else threads)
    dataset = dataset.batch(batch_size)
    dataset = dataset.repeat(num_epochs if is_training else None)
    dataset = dataset.prefetch(64)
    
    # return iterator
    iterator = dataset.make_one_shot_iterator()
    next_data, next_label = iterator.get_next()
    
    # data shape declaration
    data_shape = [None] * 4
    data_shape[-3 if data_format == 'NCHW' else -1] = channels
    next_data.set_shape(data_shape)
    next_label.set_shape(data_shape)
    
    return next_data, next_label
예제 #44
0
def sharpen(clip, mode=1, sstr=2.0, cstr=None, xstr=0.19, lstr=1.49, pstr=1.272, ldmp=None, use_lut=True):
    """Small and relatively fast realtime-sharpening function, for 1080p,
    or after scaling 720p -> 1080p during playback
    (to make 720p look more like being 1080p)
    It's a generic sharpener. Only for good quality sources!
    (If the source is crap, FineSharp will happily sharpen the crap.) ;)
    Noise/grain will be enhanced, too. The method is GENERIC.

    Modus operandi: A basic nonlinear sharpening method is performed,
    then the *blurred* sharp-difference gets subtracted again.

    Args:
        clip (clip): vs.YUV or vs.GRAY video.
        mode (int): 1 to 3, weakest to strongest. When negative -1 to -3,
                a broader kernel for equalisation is used.
        sstr (float): strength of sharpening, 0.0 up to ??
        cstr (float): strength of equalisation, 0.0 to ? 2.0 ?
                (recomm. 0.5 to 1.25, default AUTO)
        xstr (float): strength of XSharpen-style final sharpening, 0.0 to 1.0
                (but, better don't go beyond 0.249 ...)
        lstr (float): modifier for non-linear sharpening
        pstr (float): exponent for non-linear sharpening
        ldmp (float): "low damp", to not overenhance very small differences
                (noise coming out of flat areas, default sstr+1)

    Example:

    .. code-block:: python

            ...
            import finesharp
            ...
            clip = finesharp.sharpen(clip)
            ...
    """
    core = vs.get_core()

    bd = clip.format.bits_per_sample
    max_ = 2 ** bd - 1
    mid = (max_ + 1) // 2
    scl = (max_ + 1) // 256
    x = 'x {} /'.format(scl)
    y = 'y {} /'.format(scl)

    src = clip

    if core.version_number() < 33:
        raise EnvironmentError('VapourSynth version should be 33 or greater.')

    if src.format.color_family != vs.YUV and src.format.color_family != vs.GRAY:
        raise ValueError('clip must be YUV or GRAY color family.')

    if bd < 8 or bd > 16:
        raise ValueError('clip must be 8..16 bits.')

    mode = int(mode)
    if abs(mode) > 3 or mode == 0:
        raise ValueError('mode must be 1, 2, 3, -1, -2 or -3.')

    sstr = float(sstr)
    if sstr < 0.0:
        raise ValueError('sstr must be larger than zero.')

    if src.format.color_family != vs.GRAY:
        clip = core.std.ShufflePlanes(clips=clip, planes=0, colorfamily=vs.GRAY)

    if cstr is None:
        cstr = spline(sstr, {0: 0, 0.5: 0.1, 1: 0.6, 2: 0.9, 2.5: 1, 3: 1.09,
                             3.5: 1.15, 4: 1.19, 8: 1.249, 255: 1.5})
        if mode > 0:
            cstr **= 0.8
    cstr = float(cstr)

    xstr = float(xstr)
    if xstr < 0.0:
        raise ValueError('xstr must be larger than zero.')

    lstr = float(lstr)

    pstr = float(pstr)

    if ldmp is None:
        ldmp = sstr + 0.1
    ldmp = float(ldmp)

    rg = 20 - (mode > 0) * 9

    if sstr < 0.01 and cstr < 0.01 and xstr < 0.01:
        return src

    if abs(mode) == 1:
        c2 = core.std.Convolution(clip, matrix=[1, 2, 1, 2, 4, 2, 1, 2, 1]).std.Median()
    else:
        c2 = core.std.Median(clip).std.Convolution(matrix=[1, 2, 1, 2, 4, 2, 1, 2, 1])
    if abs(mode) == 3:
        c2 = core.std.Median(clip)

    if bd in [8, 9, 10] and use_lut is True:
        def expr(x, y):
            d = x - y
            absd = abs(d)
            e0 = ((absd / lstr) ** (1 / pstr)) * sstr
            e1 = d / (absd + 0.001)
            e2 = (d * d) / (d * d + ldmp)
            return clamp(e0 * e1 * e2 + mid, max_)

        diff = core.std.Lut2(clipa=clip, clipb=c2, function=expr)
    else:
        expr = '{x} {y} - abs {lstr} / log 1 {pstr} / * exp ' \
            '{sstr} * {x} {y} - {x} {y} - abs 0.001 + / * {x} {y} - log 2 * exp ' \
            '{x} {y} - log 2 * exp {ldmp} + / * 128 + {scl} *'
        expr = expr.format(x=x, y=y, lstr=lstr, pstr=pstr, sstr=sstr, ldmp=ldmp, scl=scl)
        diff = core.std.Expr(clips=[clip, c2], expr=expr)

    shrp = clip
    if sstr >= 0.01:
        shrp = core.std.MergeDiff(clipa=shrp, clipb=diff)

    if cstr >= 0.01:
        expr = 'x {mid} - {cstr} * {mid} +'.format(mid=mid, cstr=cstr)
        diff = core.std.Expr(clips=diff, expr=expr)
        diff = core.rgvs.RemoveGrain(clip=diff, mode=[rg])
        shrp = core.std.MakeDiff(clipa=shrp, clipb=diff)

    if xstr >= 0.01:
        expr = 'x x y - 9.9 * +'
        xyshrp = core.std.Expr(clips=[shrp, core.std.Convolution(shrp, matrix=[1, 1, 1, 1, 1, 1, 1, 1, 1])], expr=expr)
        rpshrp = core.rgvs.Repair(clip=xyshrp, repairclip=shrp, mode=[12])
        shrp = core.std.Merge(clipa=rpshrp, clipb=shrp, weight=[1 - xstr])

    if src.format.color_family != vs.GRAY:
        shrp = core.std.ShufflePlanes(clips=[shrp, src], planes=[0, 1, 2], colorfamily=src.format.color_family)

    return shrp
예제 #45
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
예제 #46
0
 def setUp(self):
     self.core = vs.get_core()
예제 #47
0
	def __init__(self):
		self.core = vs.get_core() 
예제 #48
0
def correct_edi_shift(clip, rfactor, plugin):
    import vapoursynth as vs
    core = vs.get_core()

    if clip.format.subsampling_w == 1:
        hshift = -rfactor / 2 + 0.5  # hshift(steps+1)=2*hshift(steps)-0.5
    else:
        hshift = -0.5

    if plugin == "zimg":
        if clip.format.subsampling_h == 0:
            clip = core.resize.Spline36(clip=clip,
                                        width=clip.width,
                                        height=clip.height,
                                        src_left=hshift,
                                        src_top=-0.5)
        else:
            Y = core.std.ShufflePlanes(clips=clip,
                                       planes=0,
                                       colorfamily=vs.GRAY)
            U = core.std.ShufflePlanes(clips=clip,
                                       planes=1,
                                       colorfamily=vs.GRAY)
            V = core.std.ShufflePlanes(clips=clip,
                                       planes=2,
                                       colorfamily=vs.GRAY)
            Y = core.resize.Spline36(clip=Y,
                                     width=clip.width,
                                     height=clip.height,
                                     src_left=hshift,
                                     src_top=-0.5)
            U = core.resize.Spline36(clip=U,
                                     width=clip.width,
                                     height=clip.height,
                                     src_left=hshift / 2,
                                     src_top=-0.5)
            V = core.resize.Spline36(clip=V,
                                     width=clip.width,
                                     height=clip.height,
                                     src_left=hshift / 2,
                                     src_top=-0.5)
            clip = core.std.ShufflePlanes(clips=[Y, U, V],
                                          planes=[0, 0, 0],
                                          colorfamily=vs.YUV)

    if plugin == "fmtconv":
        bits = clip.format.bits_per_sample
        if clip.format.subsampling_h == 0:
            clip = core.fmtc.resample(clip=clip, sx=hshift, sy=-0.5)
        else:
            clip = core.fmtc.resample(clip=clip,
                                      sx=hshift,
                                      sy=-0.5,
                                      planes=[3, 2, 2])
            clip = core.fmtc.resample(clip=clip,
                                      sx=hshift,
                                      sy=-1,
                                      planes=[2, 3, 3])
        if bits != 16:
            clip = core.fmtc.bitdepth(clip=clip, bits=bits)

    return clip
예제 #49
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
예제 #50
0
def Resize16nr(src,
               w=None,
               h=None,
               sx=0,
               sy=0,
               sw=0,
               sh=0,
               kernel="spline36",
               kernelh=None,
               kernelv=None,
               fh=1,
               fv=1,
               taps=4,
               a1=None,
               a2=None,
               a3=None,
               kovrspl=1,
               cnorm=True,
               center=True,
               fulls=None,
               fulld=None,
               cplace="mpeg2",
               invks=False,
               invkstaps=4,
               noring=True):
    core = vs.get_core()
    w = src.width if w is None else w
    h = src.height if h is None else h
    kernelh = kernel if kernelh is None else kernelh
    kernelv = kernel if kernelv is None else kernelv
    sr_h = float(w / src.width)
    sr_v = float(h / src.height)
    sr_up = max(sr_h, sr_v)
    sr_dw = 1.0 / min(sr_h, sr_v)
    sr = max(sr_up, sr_dw)

    thr = 2.5
    nrb = (sr > thr)
    nrf = (sr < thr + 1.0 and noring)
    nrr = min(sr - thr, 1.0) if nrb else 1.0
    nrv = [
        round((1.0 - nrr) * 65535),
        round((1.0 - nrr) * 65535),
        round((1.0 - nrr) * 65535)
    ] if nrb else [0, 0, 0]
    nrm = core.std.BlankClip(clip=src, width=w, height=h,
                             color=nrv) if nrb and nrf else 0

    main = core.fmtc.resample(src,
                              w=w,
                              h=h,
                              sx=sx,
                              sy=sy,
                              sw=sw,
                              sh=sh,
                              kernel=kernel,
                              kernelh=kernelh,
                              kernelv=kernelv,
                              fh=fh,
                              fv=fv,
                              taps=taps,
                              a1=a1,
                              a2=a2,
                              a3=a3,
                              kovrspl=kovrspl,
                              cnorm=cnorm,
                              center=center,
                              fulls=fulls,
                              fulld=fulld,
                              cplace=cplace,
                              invks=invks,
                              invkstaps=invkstaps)
    nrng = core.fmtc.resample(src,
                              w=w,
                              h=h,
                              sx=sx,
                              sy=sy,
                              sw=sw,
                              sh=sh,
                              kernel="gauss",
                              a1=100,
                              center=center,
                              fulls=fulls,
                              fulld=fulld,
                              cplace=cplace) if nrf else main

    clip = core.rgvs.Repair(main, nrng, 1) if nrf else main
    clip = core.std.MaskedMerge(main, clip, nrm) if nrf and nrb else clip
    return clip
예제 #51
0
def Denoise2(src,
             denoise=400,
             blur=None,
             lsb=True,
             truemotion=True,
             chroma=True,
             fast=False,
             blksize=None,
             prefix=None,
             recalculate=None,
             thSAD=None):
    core = vs.get_core()

    if fast:
        if blksize is None:
            blksize = 32

        overlap = int(blksize / 4)
    else:
        if blksize is None:
            blksize = 8

        overlap = int(blksize / 2)

    if recalculate is None:
        recalculate = blksize

    if thSAD is None:
        thSAD = int(denoise * 1.25)

    pad = blksize + overlap

    src = core.fmtc.resample(src,
                             src.width + pad,
                             src.height + pad,
                             sw=src.width + pad,
                             sh=src.height + pad,
                             kernel="point")

    src16 = Up16(src, lsb)

    super = core.mv.Super(src16, chroma=chroma)

    if prefix is not None:
        exist = os.path.exists(prefix + ".vec") and os.path.exists(prefix +
                                                                   ".len")
        create = not exist
    else:
        exist = False
        create = False

    if not exist or (blksize > recalculate):
        if blur is not None:
            blurred = core.generic.GBlur(src, blur)
            blurred = Up16(blurred, lsb)
        else:
            blurred = src16

        rep = has.DitherLumaRebuild(blurred, s0=1, chroma=chroma)
        superRep = core.mv.Super(rep, chroma=chroma)

    if not exist:
        bvec2 = core.mv.Analyse(superRep,
                                isb=True,
                                delta=2,
                                blksize=blksize,
                                overlap=overlap,
                                truemotion=truemotion,
                                chroma=chroma)
        bvec1 = core.mv.Analyse(superRep,
                                isb=True,
                                delta=1,
                                blksize=blksize,
                                overlap=overlap,
                                truemotion=truemotion,
                                chroma=chroma)
        fvec1 = core.mv.Analyse(superRep,
                                isb=False,
                                delta=1,
                                blksize=blksize,
                                overlap=overlap,
                                truemotion=truemotion,
                                chroma=chroma)
        fvec2 = core.mv.Analyse(superRep,
                                isb=False,
                                delta=2,
                                blksize=blksize,
                                overlap=overlap,
                                truemotion=truemotion,
                                chroma=chroma)
        if create:
            return WriteVecs([bvec1, bvec2, fvec1, fvec2], prefix)
    else:
        bvec1 = ReadVecs(0, prefix, 4)
        bvec2 = ReadVecs(1, prefix, 4)
        fvec1 = ReadVecs(2, prefix, 4)
        fvec2 = ReadVecs(3, prefix, 4)

    if blksize > recalculate and exist:
        bvec1 = core.std.Splice(
            [core.std.BlankClip(bvec1, width=1, length=1), bvec1],
            mismatch=True).std.Trim(1)
        bvec2 = core.std.Splice(
            [core.std.BlankClip(bvec2, width=1, length=1), bvec2],
            mismatch=True).std.Trim(1)
        fvec1 = core.std.Splice(
            [core.std.BlankClip(fvec1, width=1, length=1), fvec1],
            mismatch=True).std.Trim(1)
        fvec2 = core.std.Splice(
            [core.std.BlankClip(fvec2, width=1, length=1), fvec2],
            mismatch=True).std.Trim(1)

    while blksize > recalculate:
        blksize = int(blksize / 2)
        if fast:
            overlap = int(overlap / 4)
        else:
            overlap = int(overlap / 2)

        bvec1 = core.mv.Recalculate(superRep,
                                    bvec1,
                                    thSAD,
                                    blksize=blksize,
                                    chroma=chroma,
                                    truemotion=truemotion,
                                    overlap=overlap)
        bvec2 = core.mv.Recalculate(superRep,
                                    bvec2,
                                    thSAD,
                                    blksize=blksize,
                                    chroma=chroma,
                                    truemotion=truemotion,
                                    overlap=overlap)
        fvec1 = core.mv.Recalculate(superRep,
                                    fvec1,
                                    thSAD,
                                    blksize=blksize,
                                    chroma=chroma,
                                    truemotion=truemotion,
                                    overlap=overlap)
        fvec2 = core.mv.Recalculate(superRep,
                                    fvec2,
                                    thSAD,
                                    blksize=blksize,
                                    chroma=chroma,
                                    truemotion=truemotion,
                                    overlap=overlap)

    fin = core.mv.Degrain2(src16,
                           super,
                           bvec1,
                           fvec1,
                           bvec2,
                           fvec2,
                           denoise,
                           plane=4 if chroma else 0)

    fin = core.std.CropRel(fin, 0, pad, 0, pad)

    return fin
예제 #52
0
def min_dif16(src1, src2, ref):
    core = vs.get_core()
    clip = core.std.Expr([src1, src2, ref], ["x z - abs y z - abs > y x ?"])
    return clip
예제 #53
0
def mask_msharpen(mthr, **kwargs):
    core = vs.get_core()
    mthr /= 5
    return lambda clip: core.msmoosh.MSharpen(
        clip, threshold=mthr, strength=0, mask=True)
예제 #54
0
파일: svp.py 프로젝트: Baa14453/BaaTorrent
import vapoursynth as vs
import os
import sys

core = vs.get_core(threads=15)

core.std.LoadPlugin(ffms2)
core.std.LoadPlugin(svpflow1)
core.std.LoadPlugin(svpflow2)

clip = core.ffms2.Source(source=file)
clip = clip.resize.Bicubic(format=vs.YUV420P8)

if gpu == '1':
    super_params = "{scale:{up:0},gpu:1,pel:1,full:false}"
else:
    super_params = "{scale:{up:0},gpu:0,pel:1,full:false}"
analyse_params = "{block:{w:32,h:32},main:{search:{coarse:{type:2,distance:-5,bad:{range:0}},type:3,distance:-3},penalty:{pnbour:65},levels:4},refine:[{search:{distance:1}}]}"
smoothfps_params = "{rate:{num:5,den:2},algo:23,mask:{cover:80},scene:{mode:0,limits:{scene:3000,blocks:40}}}"

super = core.svp1.Super(clip, super_params)
vectors = core.svp1.Analyse(super["clip"], super["data"], clip, analyse_params)
smooth = core.svp2.SmoothFps(clip, super["clip"], super["data"],
                             vectors["clip"], vectors["data"],
                             smoothfps_params)
smooth = core.std.AssumeFPS(smooth,
                            fpsnum=smooth.fps_num,
                            fpsden=smooth.fps_den)

smooth.set_output()
예제 #55
0
def TAAmbk(clip,
           aatype=1,
           aatypeu=None,
           aatypev=None,
           preaa=0,
           strength=0.0,
           cycle=0,
           mtype=None,
           mclip=None,
           mthr=None,
           mlthresh=None,
           mpand=(0, 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=-1,
           **kwargs):
    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, opencl,
                                             opencl_device)
    edge_enhanced_clip = (
        thin != 0 and core.warp.AWarpSharp2(preaa_clip, depth=int(thin))
        or preaa_clip)
    edge_enhanced_clip = (dark != 0
                          and haf.Toon(edge_enhanced_clip, str=float(dark))
                          or edge_enhanced_clip)

    aa_kernel = {
        0:
        lambda clip, *args, **kwargs: type('', (), {'out': lambda: clip}),
        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,
        'Unknown':
        lambda clip, *args, **kwargs: type(
            '', (), {
                'out':
                lambda: exec(
                    'raise ValueError(MODULE_NAME + ": unknown aatype, aatypeu or aatypev")'
                )
            }),
        'Custom':
        kwargs.get(
            'aakernel', lambda clip, *args, **kwargs: type(
                '', (), {
                    'out':
                    lambda: exec(
                        'raise RuntimeError(MODULE_NAME + ": custom aatype: aakernel must be set.")'
                    )
                })),
    }

    if clip.format.color_family is vs.YUV:
        yuv = [
            core.std.ShufflePlanes(edge_enhanced_clip, i, vs.GRAY)
            for i in range(clip.format.num_planes)
        ]
        aatypes = [aatype, aatypeu, aatypev]
        aa_classes = [
            aa_kernel.get(aatype, aa_kernel['Unknown']) for aatype in aatypes
        ]
        aa_clips = [
            aa_cycle(plane,
                     aa_class,
                     cycle,
                     strength if yuv.index(plane) == 0 else 0,
                     down8,
                     opencl=opencl,
                     opencl_device=opencl_device,
                     **kwargs) for plane, aa_class in zip(yuv, aa_classes)
        ]
        aaed_clip = core.std.ShufflePlanes(aa_clips, [0, 0, 0], vs.YUV)
    elif clip.format.color_family is vs.GRAY:
        gray = edge_enhanced_clip
        aa_class = aa_kernel.get(aatype, aa_kernel['Unknown'])
        aaed_clip = aa_cycle(gray, aa_class, cycle, strength, down8, **kwargs)
    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 = (
        (aarepair > 0 and core.rgvs.Repair(src, postaa_clip, aarepair))
        or (aarepair < 0 and core.rgvs.Repair(postaa_clip, src, -aarepair))
        or postaa_clip)
    stabilized_clip = repaired_clip if stabilize == 0 else temporal_stabilize(
        repaired_clip, src, stabilize)

    if mclip is not None:
        try:
            masked_clip = core.std.MaskedMerge(src,
                                               stabilized_clip,
                                               mclip,
                                               first_plane=True)
            masker = type('', (), {
                '__call__': lambda *args, **kwargs: mclip
            })()
        except vs.Error:
            raise RuntimeError(
                MODULE_NAME +
                ': Something wrong with your mclip. Maybe format, resolution or bit_depth mismatch.'
            )
    else:
        # Use lambda for lazy evaluation
        mask_kernel = {
            0:
            lambda: lambda a, b, *args, **kwargs: b,
            1:
            lambda: mask_lthresh(clip,
                                 mthr,
                                 mlthresh,
                                 mask_sobel,
                                 mpand,
                                 opencl=opencl,
                                 opencl_device=opencl_device,
                                 **kwargs),
            2:
            lambda: mask_lthresh(clip, mthr, mlthresh, mask_robert, mpand, **
                                 kwargs),
            3:
            lambda: mask_lthresh(clip, mthr, mlthresh, mask_prewitt, mpand, **
                                 kwargs),
            4:
            lambda: mask_lthresh(clip, mthr, mlthresh, mask_tedge, mpand, **
                                 kwargs),
            5:
            lambda: mask_lthresh(clip,
                                 mthr,
                                 mlthresh,
                                 mask_canny_continuous,
                                 mpand,
                                 opencl=opencl,
                                 opencl_device=opencl_device,
                                 **kwargs),
            6:
            lambda: mask_lthresh(clip, mthr, mlthresh, mask_msharpen, mpand, **
                                 kwargs),
            'Sobel':
            lambda: mask_lthresh(clip,
                                 mthr,
                                 mlthresh,
                                 mask_sobel,
                                 mpand,
                                 opencl=opencl,
                                 opencl_device=opencl_device,
                                 **kwargs),
            'Canny':
            lambda: mask_lthresh(clip,
                                 mthr,
                                 mlthresh,
                                 mask_canny_binarized,
                                 mpand,
                                 opencl=opencl,
                                 opencl_device=opencl_device,
                                 **kwargs),
            'Prewitt':
            lambda: mask_lthresh(clip, mthr, mlthresh, mask_prewitt, mpand, **
                                 kwargs),
            'Robert':
            lambda: mask_lthresh(clip, mthr, mlthresh, mask_robert, mpand, **
                                 kwargs),
            'TEdge':
            lambda: mask_lthresh(clip, mthr, mlthresh, mask_tedge, mpand, **
                                 kwargs),
            'Canny_Old':
            lambda: mask_lthresh(clip,
                                 mthr,
                                 mlthresh,
                                 mask_canny_continuous,
                                 mpand,
                                 opencl=opencl,
                                 opencl_device=opencl_device,
                                 **kwargs),
            'MSharpen':
            lambda: mask_lthresh(clip, mthr, mlthresh, mask_msharpen, mpand, **
                                 kwargs),
            'Unknown':
            lambda: exec('raise ValueError(MODULE_NAME + ": unknown mtype")')
        }
        mtype = 5 if mtype is None else mtype
        mthr = (24, ) if mthr is None else mthr
        masker = mask_kernel.get(mtype, mask_kernel['Unknown'])()
        masked_clip = masker(src, stabilized_clip)

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

    final_output = (
        (showmask == -1 and text_mask)
        or (showmask == 1 and masker(None, src, show=True))
        or (showmask == 2 and core.std.StackVertical([
            core.std.ShufflePlanes(
                [masker(None, src, show=True),
                 core.std.BlankClip(src)], [0, 1, 2], vs.YUV), src
        ])) or (showmask == 3 and core.std.Interleave([
            core.std.ShufflePlanes(
                [masker(None, src, show=True),
                 core.std.BlankClip(src)], [0, 1, 2], vs.YUV), src
        ])) or txt_protected_clip)
    return final_output
예제 #56
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
예제 #57
0
def inputs(files, is_training=False, is_testing=False):
    # parameters
    channels = FLAGS.image_channels
    threads = FLAGS.threads
    threads_py = FLAGS.threads_py
    scaling = FLAGS.scaling
    if is_training: num_epochs = FLAGS.num_epochs
    data_format = FLAGS.data_format
    patch_height = FLAGS.patch_height
    patch_width = FLAGS.patch_width
    batch_size = FLAGS.batch_size
    if is_training: buffer_size = FLAGS.buffer_size
    epoch_size = len(files)

    # dataset mapping function
    def parse1_func(filename):
        # read data
        dtype = tf.float32
        image = tf.read_file(filename)
        image = tf.image.decode_image(image, channels=channels)
        shape = tf.shape(image)
        height = shape[-3]
        width = shape[-2]
        # pre down-scale for high resolution image
        dscale = 1
        if is_training and FLAGS.pre_down:
            '''
            if (width >= 3072 and height >= 1536) or (width >= 1536 and height >= 3072):
                dscale = 3
            elif (width >= 1024 and height >= 512) or (width >= 512 and height >= 1024):
                dscale = 2
            '''
            def c_t(const1, const2, true_fn, false_fn):
                return tf.cond(
                    tf.logical_or(
                        tf.logical_and(tf.greater_equal(width, const1),
                                       tf.greater_equal(height, const2)),
                        tf.logical_and(tf.greater_equal(width, const2),
                                       tf.greater_equal(height, const1))),
                    true_fn, false_fn)

            dscale = c_t(3072, 1536, lambda: 3,
                         lambda: c_t(1024, 512, lambda: 2, lambda: 1))
        elif is_testing and FLAGS.pre_down:
            '''
            if (width >= 3072 and height >= 3072):
                dscale = 4
            elif (width >= 2048 and height >= 2048):
                dscale = 3
            elif (width >= 1024 and height >= 1024):
                dscale = 2
            '''
            def c_t(const1, true_fn, false_fn):
                return tf.cond(
                    tf.logical_and(tf.greater_equal(width, const1),
                                   tf.greater_equal(height, const1)), true_fn,
                    false_fn)

            dscale = c_t(
                3072, lambda: 4, lambda: c_t(
                    2048, lambda: 3, lambda: c_t(1024, lambda: 2, lambda: 1)))
        # padding
        cropped_height = patch_height * dscale
        cropped_width = patch_width * dscale
        '''
        if cropped_height > height or cropped_width > width:
            pad_height = cropped_height - height
            pad_width = cropped_width - width
            if pad_height > 0:
                pad_height = [pad_height // 2, pad_height - pad_height // 2]
                height = cropped_height
            else:
                pad_height = [0, 0]
            if pad_width > 0:
                pad_width = [pad_width // 2, pad_width - pad_width // 2]
                width = cropped_width
            else:
                pad_width = [0, 0]
            block = tf.pad(image, [pad_height, pad_width, [0, 0]], mode='REFLECT')
        else:
            block = image
        '''
        cond_height = tf.greater(cropped_height, height)
        cond_width = tf.greater(cropped_width, width)

        def c_f1():
            def _1():
                ph = cropped_height - height
                return [ph // 2, ph - ph // 2]

            pad_height = tf.cond(cond_height, _1, lambda: [0, 0])

            def _2():
                pw = cropped_width - width
                return [pw // 2, pw - pw // 2]

            pad_width = tf.cond(cond_width, _2, lambda: [0, 0])
            return tf.pad(image, [pad_height, pad_width, [0, 0]],
                          mode='REFLECT')

        block = tf.cond(tf.logical_or(cond_height, cond_width), c_f1,
                        lambda: image)
        height = tf.maximum(cropped_height, height)
        width = tf.maximum(cropped_width, width)
        # cropping
        if is_training:
            block = tf.random_crop(block,
                                   [cropped_height, cropped_width, channels])
            block = tf.image.random_flip_up_down(block)
            block = tf.image.random_flip_left_right(block)
        elif is_testing:
            offset_height = (height - cropped_height) // 2
            offset_width = (width - cropped_width) // 2
            block = tf.image.crop_to_bounding_box(block, offset_height,
                                                  offset_width, cropped_height,
                                                  cropped_width)
        # convert dtype
        block = tf.image.convert_image_dtype(block, dtype, saturate=False)
        # random color augmentation
        if is_training and FLAGS.color_augmentation > 0:
            block = tf.image.random_saturation(block,
                                               1 - FLAGS.color_augmentation,
                                               1 + FLAGS.color_augmentation)
            block = tf.image.random_brightness(block, FLAGS.color_augmentation)
            block = tf.image.random_contrast(block,
                                             1 - FLAGS.color_augmentation,
                                             1 + FLAGS.color_augmentation)
        # data format conversion
        block.set_shape([None, None, channels])
        if data_format == 'NCHW':
            block = tf.transpose(block, (2, 0, 1))
        # return
        return block

    # tf.py_func processing using vapoursynth, numpy, etc.
    import threading
    import vapoursynth as vs
    from scipy import ndimage

    def SigmoidInverse(clip, thr=0.5, cont=6.5, epsilon=1e-6):
        assert clip.format.sample_type == vs.FLOAT
        x0 = 1 / (1 + np.exp(cont * thr))
        x1 = 1 / (1 + np.exp(cont * (thr - 1)))
        # thr - log(max(1 / max(x * (x1 - x0) + x0, epsilon) - 1, epsilon)) / cont
        expr = '{thr} 1 x {x1_x0} * {x0} + {epsilon} max / 1 - {epsilon} max log {cont_rec} * -'.format(
            thr=thr, cont_rec=1 / cont, epsilon=epsilon, x0=x0, x1_x0=x1 - x0)
        return clip.std.Expr(expr)

    def SigmoidDirect(clip, thr=0.5, cont=6.5):
        assert clip.format.sample_type == vs.FLOAT
        x0 = 1 / (1 + np.exp(cont * thr))
        x1 = 1 / (1 + np.exp(cont * (thr - 1)))
        # (1 / (1 + exp(cont * (thr - x))) - x0) / (x1 - x0)
        expr = '1 1 {cont} {thr} x - * exp + / {x0} - {x1_x0_rec} *'.format(
            thr=thr, cont=cont, x0=x0, x1_x0_rec=1 / (x1 - x0))
        return clip.std.Expr(expr)

    _lock = threading.Lock()
    _index_ref = [0]
    _src_ref = [None for _ in range(epoch_size)]
    core = vs.get_core(threads=threads_py)
    _dscales = list(range(1, 5)) if FLAGS.pre_down else [1]
    _src_blk = [
        core.std.BlankClip(None,
                           patch_width * s,
                           patch_height * s,
                           format=vs.RGBS,
                           length=epoch_size) for s in _dscales
    ]
    _dst_blk = core.std.BlankClip(None,
                                  patch_width // scaling,
                                  patch_height // scaling,
                                  format=vs.RGBS,
                                  length=epoch_size)

    def src_frame_func(n, f):
        f_out = f.copy()
        planes = f_out.format.num_planes
        # output
        for p in range(planes):
            f_arr = np.array(f_out.get_write_array(p), copy=False)
            np.copyto(
                f_arr, _src_ref[n][p, :, :]
                if data_format == 'NCHW' else _src_ref[n][:, :, p])
        return f_out

    _srcs = [s.std.ModifyFrame(s, src_frame_func) for s in _src_blk]
    _srcs_linear = [
        s.resize.Bicubic(transfer_s='linear', transfer_in_s='709')
        for s in _srcs
    ]

    def src_down_func(clip):
        dw = patch_width
        dh = patch_height
        #clip = clip.resize.Bicubic(transfer_s='linear', transfer_in_s='709')
        clip = SigmoidInverse(clip)
        clip = clip.resize.Bicubic(dw,
                                   dh,
                                   filter_param_a=0,
                                   filter_param_b=0.5)
        clip = SigmoidDirect(clip)
        clip = clip.resize.Bicubic(transfer_s='709', transfer_in_s='linear')
        return clip

    if FLAGS.pre_down:
        _srcs_down = [src_down_func(s) for s in _srcs_linear]

    def src_select_eval(n):
        # select source
        shape = _src_ref[n].shape
        sh = shape[-2 if data_format == 'NCHW' else -3]
        dscale = sh // patch_height
        # downscale if needed
        if dscale > 1:
            clip = _srcs_down[dscale - 1]
        else:
            clip = _srcs[dscale - 1]
        return clip

    if FLAGS.pre_down:
        _src = _src_blk[0].std.FrameEval(src_select_eval)
    else:
        _src = _srcs[0]

    def resize_set_func(clip, linear=False):
        # parameters
        dw = patch_width // scaling
        dh = patch_height // scaling
        rets = {}
        # resizers
        rets['bilinear'] = clip.resize.Bilinear(dw, dh)
        rets['spline16'] = clip.resize.Spline16(dw, dh)
        rets['spline36'] = clip.resize.Spline36(dw, dh)
        for taps in range(2, 12):
            rets['lanczos{}'.format(taps)] = clip.resize.Lanczos(
                dw, dh, filter_param_a=taps)
        # linear to gamma
        if linear:
            for key in rets:
                rets[key] = rets[key].resize.Bicubic(transfer_s='709',
                                                     transfer_in_s='linear')
        return rets

    _resizes = [resize_set_func(s, linear=False) for s in _srcs]
    _linear_resizes = [resize_set_func(s, linear=True) for s in _srcs_linear]

    def resize_eval(n):
        # parameters
        dw = patch_width // scaling
        dh = patch_height // scaling
        rand_val = np.random.uniform(-1, 1)
        abs_rand = np.abs(rand_val)
        # select source
        shape = _src_ref[n].shape
        sh = shape[-2 if data_format == 'NCHW' else -3]
        dscale = sh // patch_height
        # random gamma-to-linear
        if rand_val < 0:
            clip = _srcs_linear[dscale - 1]
            resizes = _linear_resizes[dscale - 1]
        else:
            clip = _srcs[dscale - 1]
            resizes = _resizes[dscale - 1]
        # random resizers
        if abs_rand < 0.05:
            clip = resizes['bilinear']
        elif abs_rand < 0.1:
            clip = resizes['spline16']
        elif abs_rand < 0.15:
            clip = resizes['spline36']
        elif abs_rand < 0.4:  # Lanczos taps=[2, 12)
            taps = int(np.clip(np.random.exponential(2) + 2, 2, 11))
            clip = resizes['lanczos{}'.format(taps)]
        elif abs_rand < 0.6:  # Catmull-Rom
            b = np.random.normal(0, 1 / 6)
            c = (1 - b) * 0.5
            clip = clip.resize.Bicubic(dw,
                                       dh,
                                       filter_param_a=b,
                                       filter_param_b=c)
        elif abs_rand < 0.7:  # Mitchell-Netravali (standard Bicubic)
            b = np.random.normal(1 / 3, 1 / 6)
            c = (1 - b) * 0.5
            clip = clip.resize.Bicubic(dw,
                                       dh,
                                       filter_param_a=b,
                                       filter_param_b=c)
        elif abs_rand < 0.8:  # sharp Bicubic
            b = np.random.normal(-0.5, 0.25)
            c = b * -0.5
            clip = clip.resize.Bicubic(dw,
                                       dh,
                                       filter_param_a=b,
                                       filter_param_b=c)
        elif abs_rand < 0.9:  # soft Bicubic
            b = np.random.normal(0.75, 0.25)
            c = 1 - b
            clip = clip.resize.Bicubic(dw,
                                       dh,
                                       filter_param_a=b,
                                       filter_param_b=c)
        else:  # arbitrary Bicubic
            b = np.random.normal(0, 0.5)
            c = np.random.normal(0.25, 0.25)
            clip = clip.resize.Bicubic(dw,
                                       dh,
                                       filter_param_a=b,
                                       filter_param_b=c)
        # random linear-to-gamma
        if rand_val < 0 and abs_rand >= 0.4:
            clip = clip.resize.Bicubic(transfer_s='709',
                                       transfer_in_s='linear')
        # return
        return clip

    _dst = _dst_blk.std.FrameEval(resize_eval)

    def parse2_pyfunc(label):
        channel_index = -3 if data_format == 'NCHW' else -1
        dscale = label.shape[-2 if data_format ==
                             'NCHW' else -3] // patch_height
        # safely acquire and increase shared index
        _lock.acquire()
        index = _index_ref[0]
        _index_ref[0] = (index + 1) % epoch_size
        _lock.release()
        # processing using vs
        _src_ref[index] = label
        if FLAGS.pre_down and dscale > 1: f_src = _src.get_frame(index)
        f_dst = _dst.get_frame(index)
        _src_ref[index] = None
        # vs.VideoFrame to np.ndarray
        if FLAGS.pre_down and dscale > 1:
            label = []
            planes = f_src.format.num_planes
            for p in range(planes):
                f_arr = np.array(f_src.get_read_array(p), copy=False)
                label.append(f_arr)
            label = np.stack(label, axis=channel_index)
        data = []
        planes = f_dst.format.num_planes
        for p in range(planes):
            f_arr = np.array(f_dst.get_read_array(p), copy=False)
            data.append(f_arr)
        data = np.stack(data, axis=channel_index)

        # noise spatial correlation
        def noise_correlation(noise, corr):
            if corr > 0:
                sigma = np.random.normal(corr, corr)
                if sigma > 0.25:
                    sigma = [0, sigma, sigma
                             ] if data_format == 'NCHW' else [sigma, sigma, 0]
                    noise = ndimage.gaussian_filter(noise, sigma, truncate=2.0)
            return noise

        # add Gaussian noise of random scale and random spatial correlation
        if FLAGS.noise_scale > 0:
            rand_val = np.random.uniform(0, 1)
            scale = np.random.exponential(FLAGS.noise_scale)
            if rand_val >= 0.2 and scale > 0.002:  # add noise
                noise_shape = list(data.shape)
                if rand_val < 0.35:  # RGB noise
                    noise = np.random.normal(0.0, scale,
                                             noise_shape).astype(np.float32)
                    noise = noise_correlation(noise, FLAGS.noise_corr)
                else:  # Y/YUV noise
                    noise_shape[channel_index] = 1
                    noise_y = np.random.normal(0.0, scale,
                                               noise_shape).astype(np.float32)
                    noise_y = noise_correlation(noise_y, FLAGS.noise_corr)
                    scale_uv = np.random.exponential(FLAGS.noise_scale / 2)
                    if rand_val < 0.55 and scale_uv > 0.002:  # YUV noise
                        noise_u = np.random.normal(
                            0.0, scale_uv, noise_shape).astype(np.float32)
                        noise_u = noise_correlation(noise_u,
                                                    FLAGS.noise_corr * 1.5)
                        noise_v = np.random.normal(
                            0.0, scale_uv, noise_shape).astype(np.float32)
                        noise_v = noise_correlation(noise_v,
                                                    FLAGS.noise_corr * 1.5)
                        rand_val2 = np.random.uniform(0, 1)
                        if rand_val2 < 0.3:  # Rec.601
                            Kr = 0.299
                            Kg = 0.587
                            Kb = 0.114
                        elif rand_val2 < 0.9:  # Rec.709
                            Kr = 0.2126
                            Kg = 0.7152
                            Kb = 0.0722
                        else:  # Rec.2020
                            Kr = 0.2627
                            Kg = 0.6780
                            Kb = 0.0593
                        noise_r = noise_y + ((1 - Kr) / 2) * noise_v
                        noise_b = noise_y + ((1 - Kb) / 2) * noise_u
                        noise_g = (1 / Kg) * noise_y - (Kr / Kg) * noise_r - (
                            Kb / Kg) * noise_b
                        noise = [noise_r, noise_g, noise_b]
                    else:
                        noise = [noise_y, noise_y, noise_y]
                    noise = np.concatenate(noise, axis=channel_index)
                # adding noise
                data += noise
        # return
        return data, label

    def parse3_func(data, label):
        # final process
        data = tf.clip_by_value(data, 0.0, 1.0)
        label = tf.clip_by_value(label, 0.0, 1.0)
        # JPEG encoding
        if FLAGS.jpeg_coding:
            rand_val = tf.random_uniform([], 0, 1)

            def c_f1(data):
                if data_format == 'NCHW':
                    data = tf.transpose(data, (1, 2, 0))
                data = tf.image.convert_image_dtype(data,
                                                    tf.uint8,
                                                    saturate=True)

                def _f1():
                    return tf.image.encode_jpeg(data,
                                                quality=98,
                                                chroma_downsampling=False)

                def _f2():
                    return tf.image.encode_jpeg(data,
                                                quality=96,
                                                chroma_downsampling=False)

                def _f3():
                    return tf.image.encode_jpeg(data,
                                                quality=95,
                                                chroma_downsampling=False)

                def _f4():
                    return tf.image.encode_jpeg(data,
                                                quality=92,
                                                chroma_downsampling=False)

                def _f5():
                    return tf.image.encode_jpeg(data,
                                                quality=90,
                                                chroma_downsampling=False)

                def _f6():
                    return tf.image.encode_jpeg(data,
                                                quality=88,
                                                chroma_downsampling=False)

                def _f7():
                    return tf.image.encode_jpeg(data,
                                                quality=85,
                                                chroma_downsampling=False)

                def _f8():
                    return tf.image.encode_jpeg(data,
                                                quality=84,
                                                chroma_downsampling=False)

                def _f9():
                    return tf.image.encode_jpeg(data,
                                                quality=82,
                                                chroma_downsampling=False)

                def _f10():
                    return tf.image.encode_jpeg(data,
                                                quality=80,
                                                chroma_downsampling=False)

                data = tf.cond(
                    tf.less(rand_val, 0.03), _f1, lambda: tf.cond(
                        tf.less(rand_val, 0.06), _f2, lambda: tf.cond(
                            tf.less(rand_val, 0.09), _f3, lambda: tf.cond(
                                tf.less(rand_val, 0.12), _f4, lambda: tf.cond(
                                    tf.less(rand_val, 0.15), _f5, lambda: tf.
                                    cond(
                                        tf.less(rand_val, 0.18), _f6, lambda:
                                        tf.cond(
                                            tf.less(rand_val, 0.21), _f7,
                                            lambda: tf.cond(
                                                tf.less(rand_val, 0.24), _f8,
                                                lambda: tf.cond(
                                                    tf.less(rand_val, 0.27),
                                                    _f9, _f10)))))))))
                data = tf.image.decode_jpeg(data)
                data = tf.image.convert_image_dtype(data,
                                                    tf.float32,
                                                    saturate=False)
                if data_format == 'NCHW':
                    data = tf.transpose(data, (2, 0, 1))
                return data

            data = tf.cond(tf.less(rand_val, 0.3), lambda: c_f1(data),
                           lambda: data)
        # return
        return data, label

    # Dataset API
    dataset = tf.contrib.data.Dataset.from_tensor_slices((files))
    dataset = dataset.map(parse1_func,
                          num_threads=threads,
                          output_buffer_size=threads * 64)
    dataset = dataset.map(lambda label: tuple(
        tf.py_func(parse2_pyfunc, [label], [tf.float32, tf.float32])),
                          num_threads=threads_py,
                          output_buffer_size=threads_py * 64)
    dataset = dataset.map(parse3_func,
                          num_threads=threads,
                          output_buffer_size=threads * 64)
    if is_training and FLAGS.buffer_size > 0:
        dataset = dataset.shuffle(buffer_size)
    dataset = dataset.batch(batch_size)
    if is_training: dataset = dataset.repeat(num_epochs)

    # return iterator
    iterator = dataset.make_one_shot_iterator()
    next_data, next_label = iterator.get_next()

    # data shape declaration
    if data_format == 'NCHW':
        next_data.set_shape([None, channels, None, None])
        next_label.set_shape([None, channels, None, None])
        #next_data.set_shape([None, channels, patch_height // scaling, patch_width // scaling])
        #next_label.set_shape([None, channels, patch_height, patch_width])
    else:
        next_data.set_shape([None, None, None, channels])
        next_label.set_shape([None, None, None, channels])
        #next_data.set_shape([None, patch_height // scaling, patch_width // scaling, channels])
        #next_label.set_shape([None, patch_height, patch_width, channels])

    return next_data, next_label
예제 #58
0
def LinearAndGamma(src, l2g_flag, fulls, fulld, curve, planes, gcor, sigmoid,
                   thr, cont):
    core = vs.get_core()

    if curve == 'srgb':
        c_num = 0
    elif curve in ['709', '601', '170']:
        c_num = 1
    elif curve == '240':
        c_num = 2
    elif curve == '2020':
        c_num = 3
    else:
        raise ValueError('LinearAndGamma: wrong curve value')

    if src.format.color_family == vs.GRAY:
        planes = [0]

    #                 BT-709/601
    #        sRGB     SMPTE 170M   SMPTE 240M   BT-2020
    k0 = [0.04045, 0.081, 0.0912, 0.08145][c_num]
    phi = [12.92, 4.5, 4.0, 4.5][c_num]
    alpha = [0.055, 0.099, 0.1115, 0.0993][c_num]
    gamma = [2.4, 2.22222, 2.22222, 2.22222][c_num]

    def g2l(x):
        expr = x / 65536 if fulls else (x - 4096) / 56064
        if expr <= k0:
            expr /= phi
        else:
            expr = ((expr + alpha) / (1 + alpha))**gamma
        if gcor != 1 and expr >= 0:
            expr **= gcor
        if sigmoid:
            x0 = 1 / (1 + math.exp(cont * thr))
            x1 = 1 / (1 + math.exp(cont * (thr - 1)))
            expr = thr - math.log(
                max(1 / max(expr *
                            (x1 - x0) + x0, 0.000001) - 1, 0.000001)) / cont
        if fulld:
            return min(max(round(expr * 65536), 0), 65535)
        else:
            return min(max(round(expr * 56064 + 4096), 0), 65535)

    # E' = (E <= k0 / phi)   ?   E * phi   :   (E ^ (1 / gamma)) * (alpha + 1) - alpha
    def l2g(x):
        expr = x / 65536 if fulls else (x - 4096) / 56064
        if sigmoid:
            x0 = 1 / (1 + math.exp(cont * thr))
            x1 = 1 / (1 + math.exp(cont * (thr - 1)))
            expr = (1 / (1 + math.exp(cont * (thr - expr))) - x0) / (x1 - x0)
        if gcor != 1 and expr >= 0:
            expr **= gcor
        if expr <= k0 / phi:
            expr *= phi
        else:
            expr = expr**(1 / gamma) * (alpha + 1) - alpha
        if fulld:
            return min(max(round(expr * 65536), 0), 65535)
        else:
            return min(max(round(expr * 56064 + 4096), 0), 65535)

    return core.std.Lut(src, planes=planes, function=l2g if l2g_flag else g2l)
예제 #59
0
import vapoursynth as vs

core = vs.get_core()

colorfamilies = (vs.GRAY, vs.YUV, vs.RGB, vs.YCOCG)
intbitdepths = (8, 9, 10, 11, 12, 13, 14, 15, 16)
floatbitdepths = (16, 32)
yuvss = (0, 1, 2)

formatids = []

for cfs in colorfamilies:
    for bps in intbitdepths:
        if cfs in (vs.YUV, vs.YCOCG):
            for wss in yuvss:
                for hss in yuvss:
                    formatids.append(
                        core.register_format(cfs, vs.INTEGER, bps, wss,
                                             hss).id)
        else:
            formatids.append(
                core.register_format(cfs, vs.INTEGER, bps, 0, 0).id)

for cfs in colorfamilies:
    for bps in floatbitdepths:
        if cfs in (vs.YUV, vs.YCOCG):
            for wss in yuvss:
                for hss in yuvss:
                    formatids.append(
                        core.register_format(cfs, vs.FLOAT, bps, wss, hss).id)
        else:
예제 #60
0
def TextSub16(clip,
              file,
              mod=False,
              charset=None,
              fps=None,
              vfr=None,
              swapuv=None):
    core = vs.get_core()
    funcName = 'TextSub16'
    if clip.format.color_family != vs.YUV:
        raise TypeError(funcName + ': only planar YUV input is supported.')
    sw = clip.width
    sh = clip.height
    if clip.format.bits_per_sample != 16:
        src16 = core.fmtc.bitdepth(clip=clip, bits=16)
    else:
        src16 = clip
    src8 = core.fmtc.bitdepth(clip=clip, bits=8)
    yuv444 = src16.format.id == vs.YUV444P16
    yuv422 = src16.format.id == vs.YUV422P16
    yuv420 = src16.format.id == vs.YUV420P16
    if mod:
        src8sub = core.VSFmod.VobSubMod(clip=src8, file=file, swapuv=swapuv)
    else:
        src8sub = core.xyvsf.TextSub(clip=src8,
                                     file=file,
                                     charset=charset,
                                     fps=fps,
                                     vfr=vfr,
                                     swapuv=swapuv)
    src16sub = core.fmtc.bitdepth(clip=src8sub, bits=16)
    submask = core.std.Expr([src8, src8sub], expr=["x y = 0 255 ?"])
    submaskY = core.std.ShufflePlanes(clips=submask,
                                      planes=0,
                                      colorfamily=vs.GRAY)
    submaskY = core.fmtc.bitdepth(clip=submaskY, bits=16)
    submaskU = core.std.ShufflePlanes(clips=submask,
                                      planes=1,
                                      colorfamily=vs.GRAY).fmtc.resample(
                                          w=sw,
                                          h=sh,
                                          sx=0.25,
                                          kernel="bilinear")
    submaskV = core.std.ShufflePlanes(clips=submask,
                                      planes=2,
                                      colorfamily=vs.GRAY).fmtc.resample(
                                          w=sw,
                                          h=sh,
                                          sx=0.25,
                                          kernel="bilinear")
    submask = core.std.Expr([submaskY, submaskU, submaskV],
                            expr=["x y max z max"])
    if yuv444:
        submaskC = submask
    if yuv422:
        submaskC = core.fmtc.resample(submask,
                                      w=sw // 2,
                                      h=sh,
                                      sx=-0.5,
                                      kernel="bilinear")
    if yuv420:
        submaskC = core.fmtc.resample(submask,
                                      w=sw // 2,
                                      h=sh // 2,
                                      sx=-0.5,
                                      kernel="bilinear")
    submask = core.std.ShufflePlanes(clips=[submask, submaskC, submaskC],
                                     planes=[0, 0, 0],
                                     colorfamily=vs.YUV)
    res = core.std.MaskedMerge(clipa=src16,
                               clipb=src16sub,
                               mask=submask,
                               planes=[0, 1, 2])
    return res