Spaces:
Running
Running
File size: 2,189 Bytes
966ae59 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# -*- coding: utf-8 -*-
# Copyright (c) XiMing Xing. All rights reserved.
# Author: XiMing Xing
# Description:
import numpy as np
import cv2
from scipy import ndimage as ndi
from skimage import filters
class XDoG:
def __init__(self,
gamma=0.98,
phi=200,
eps=-0.1,
sigma=0.8,
k=10,
binarize: bool = True):
"""
XDoG algorithm.
Args:
gamma: Control the size of the Gaussian filter
phi: Control changes in edge strength
eps: Threshold for controlling edge strength
sigma: The standard deviation of the Gaussian filter controls the degree of smoothness
k: Control the size ratio of Gaussian filter, (k=10 or k=1.6)
binarize(bool): Whether to binarize the output
"""
super(XDoG, self).__init__()
self.gamma = gamma
assert 0 <= self.gamma <= 1
self.phi = phi
assert 0 <= self.phi <= 1500
self.eps = eps
assert -1 <= self.eps <= 1
self.sigma = sigma
assert 0.1 <= self.sigma <= 10
self.k = k
assert 1 <= self.k <= 100
self.binarize = binarize
def __call__(self, img):
# to gray if image is not already grayscale
if len(img.shape) == 3 and img.shape[2] == 3:
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
elif len(img.shape) == 3 and img.shape[2] == 4:
img = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
if np.isnan(img).any():
img[np.isnan(img)] = np.mean(img[~np.isnan(img)])
# gaussian filter
imf1 = ndi.gaussian_filter(img, self.sigma)
imf2 = ndi.gaussian_filter(img, self.sigma * self.k)
imdiff = imf1 - self.gamma * imf2
# XDoG
imdiff = (imdiff < self.eps) * 1.0 + (imdiff >= self.eps) * (1.0 + np.tanh(self.phi * imdiff))
# normalize
imdiff -= imdiff.min()
imdiff /= imdiff.max()
if self.binarize:
th = filters.threshold_otsu(imdiff)
imdiff = (imdiff >= th).astype('float32')
return imdiff
|