
import cv2
import numpy as np

def DoG(image, size, sigma, k=1.6, gamma=1.):
    g1 = cv2.GaussianBlur(image, (size, size), sigma)
    g2 = cv2.GaussianBlur(image, (size, size), sigma*k)
    return g1 - gamma * g2

def XDoG(image, size, sigma, eps, phi, k=1.6, gamma=1.):
    eps /= 255
    d = DoG(image, size, sigma, k, gamma)
    d /= d.max()
    e = 1 + np.tanh(phi * (d - eps))
    e[e >= 1] = 1
    return e * 255

# This config is found by the author
# modify if not the desired output
XDoG_config = dict(
    size=0,
    sigma=0.6,
    eps=-15,
    phi=10e8,
    k=2.5,
    gamma=0.97
)

def gen_xdog_image(src, dst):
    gray = cv2.imread(src, cv2.IMREAD_GRAYSCALE)
    # I wanted the gamma between [0.97, 0.98]
    # but it depends on the image so I made it move randomly
    # comment out if this is not needed
    XDoG_config['gamma'] += 0.01 * np.random.rand(1)
    dogged = XDoG(gray, **XDoG_config)
    cv2.imwrite(dst, dogged)

if __name__ == "__main__":
    gen_xdog_image('sample.jpg', 'dog.jpg')
[((6, 9, 6, 53), 'cv2.GaussianBlur', 'cv2.GaussianBlur', ({(6, 26, 6, 31): 'image', (6, 33, 6, 45): '(size, size)', (6, 47, 6, 52): 'sigma'}, {}), '(image, (size, size), sigma)', False, 'import cv2\n'), ((7, 9, 7, 55), 'cv2.GaussianBlur', 'cv2.GaussianBlur', ({(7, 26, 7, 31): 'image', (7, 33, 7, 45): '(size, size)', (7, 47, 7, 54): 'sigma * k'}, {}), '(image, (size, size), sigma * k)', False, 'import cv2\n'), ((30, 11, 30, 48), 'cv2.imread', 'cv2.imread', ({(30, 22, 30, 25): 'src', (30, 27, 30, 47): 'cv2.IMREAD_GRAYSCALE'}, {}), '(src, cv2.IMREAD_GRAYSCALE)', False, 'import cv2\n'), ((36, 4, 36, 28), 'cv2.imwrite', 'cv2.imwrite', ({(36, 16, 36, 19): 'dst', (36, 21, 36, 27): 'dogged'}, {}), '(dst, dogged)', False, 'import cv2\n'), ((14, 12, 14, 36), 'numpy.tanh', 'np.tanh', ({(14, 20, 14, 35): '(phi * (d - eps))'}, {}), '(phi * (d - eps))', True, 'import numpy as np\n'), ((34, 35, 34, 52), 'numpy.random.rand', 'np.random.rand', ({(34, 50, 34, 51): '(1)'}, {}), '(1)', True, 'import numpy as np\n')]