
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, 'cv2.GaussianBlur', 'cv2.GaussianBlur', False, 'import cv2\n'), (7, 'cv2.GaussianBlur', 'cv2.GaussianBlur', False, 'import cv2\n'), (30, 'cv2.imread', 'cv2.imread', False, 'import cv2\n'), (36, 'cv2.imwrite', 'cv2.imwrite', False, 'import cv2\n'), (14, 'numpy.tanh', 'np.tanh', True, 'import numpy as np\n'), (34, 'numpy.random.rand', 'np.random.rand', True, 'import numpy as np\n')]