示例#1
0
def XDoG(clip, sigma=1.0, k=1.6, p=20, epsilon=0.7, lamda=0.01):
    """XDoG - An eXtended difference-of-Gaussian filter

    Args:
        clip: Input clip.

        sigma: (float) Strength of gaussian filter.
            Default is 1.

        k: (float) Amplifier of "sigma" for second gaussian filtering.
            Default is 1.6.

        p: (float) Amplifier of difference of gaussian.
            Default is 20.

        epsilon: (float, 0~1) Threshold of DoG response. Scaled automatically.
            Default is 0.7.

        lamda: (float) Multiplier in the thresholding function.
            Default is 0.01.

    Ref:
        [1] Winnemöller, H., Kyprianidis, J. E., & Olsen, S. C. (2012). XDoG: an extended difference-of-Gaussians compendium including advanced image stylization. Computers & Graphics, 36(6), 740-753.

    """

    bits = clip.format.bits_per_sample
    peak =  (1 << bits) - 1
    epsilon = muf.scale(epsilon, bits)

    f1 = core.tcanny.TCanny(clip, sigma=sigma, mode=-1)
    f2 = core.tcanny.TCanny(clip, sigma=sigma * k, mode=-1)

    return core.std.Expr([f1, f2], f'x y - {p} * x + {epsilon} >= 1 2 2 2 x y - {p} * x + {epsilon} - {lamda} * * exp 1 + / - ? {peak} *')
示例#2
0
def tv(I, iter=5, dt=None, ep=1, lam=0, I0=None, C=0):
    """Total Variation Denoising

    Args:
        I: Input. Recommended to input floating type clip.

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

        dt: (float) Time step. Default is ep/5.

        ep: (float) Epsilon (of gradient regularization). Default is 1.

        lam: (float) Fidelity term lambda. Default is 0.

        I0: (clip) Input (noisy) image. Default is "I".


    Ref:
        [1] Rudin, L. I., Osher, S., & Fatemi, E. (1992). Nonlinear total variation based noise removal algorithms. Physica D: Nonlinear Phenomena, 60(1-4), 259-268.
        [2] Total Variation Denoising : http://visl.technion.ac.il/~gilboa/PDE-filt/tv_denoising.html

    """

    core = vs.get_core()

    if dt is None:
        dt = ep / 5

    if I0 is None:
        I0 = I

    ep2 = ep * ep

    isFloat = I.format.sample_type == vs.FLOAT
    neutral = 0 if isFloat else muf.scale(128, I.format.bits_per_sample)

    for i in range(iter):
        I_x = core.std.Convolution(I, [-1, 0, 1], divisor=2, bias=neutral, mode='h') # correct
        I_y = core.std.Convolution(I, [-1, 0, 1], divisor=2, bias=neutral, mode='v') # correct
        I_xx = core.std.Convolution(I, [1, -2, 1], divisor=1 if isFloat else 4, bias=neutral, mode='h') # x4
        I_yy = core.std.Convolution(I, [1, -2, 1], divisor=1 if isFloat else 4, bias=neutral, mode='v') # x4
        Dp = core.std.Convolution(I, [1, 0, 0, 0, 0, 0, 0, 0, 1], divisor=2)
        Dm = core.std.Convolution(I, [0, 0, 1, 0, 0, 0, 1, 0, 0], divisor=2)
        I_xy = core.std.Expr([Dp, Dm], ['x y - 2 / {} +'.format(neutral)]) # correct

        if isFloat:
            expr = 'x {dt} a {ep2} z dup * + * 2 y * z * b * - c {ep2} y dup * + * + {ep2} y dup * + z dup * + 1.5 pow / {lam} d x - {C} + * + * +'.format(dt=dt, ep2=ep2, lam=lam, C=C)
        else: # isInteger
            expr = 'x {dt} a {neutral} - 4 * {ep2} z {neutral} - dup * + * 2 y {neutral} - * z {neutral} - * b {neutral} - * - c {neutral} - 4 * {ep2} y {neutral} - dup * + * + {ep2} y {neutral} - dup * + z {neutral} - dup * + 1.5 pow / {lam} d x - {C} + * + * +'.format(dt=dt, neutral=neutral, ep2=ep2, lam=lam, C=C)

        I = core.std.Expr([I, I_x, I_y, I_xx, I_xy, I_yy, I0], [expr])

    return I