cucim
cucim copied to clipboard
[FEA] Add an interface equivalent to OpenCV's Sobel
We have a sobel
filter, but it is only for the common case of first order 3x3 kernels. I had a request to provide an equivalent to OpenCV's Sobel which also supports larger kernel sizes (as well as order > 1).
We already have the underlying CUDA convolution kernels, so we mainly just need an interface to generate the appropriate kernels and call our existing convolution functions.
The following python function should generate the equivalent kernels to the ones provided in OpenCV (reference)
def get_sobel_kernel(ksize, order):
# Note: OpenCV docs refer to a max size of 7 but any
# odd size seems to work in practice.
if ksize % 2 ~= 1:
raise ValueError("ksize must be odd")
if ksize <= 0:
# docs say ksize = -1 for this CV_Scharr case, but in
# practice any nonpositive ksize gives the Scharr kernel
if order == 0:
k = np.array([3, 10, 3])
elif order == 1:
k = np.array([-1, 0, 1])
else:
raise ValueError("order must be < ksize")
if ksize == 1:
# Case without any smoothing
if order == 0:
k = np.array([1])
elif order == 1:
k = np.array([-1, 0, 1])
else:
raise ValueError("order must be < ksize")
elif order >= ksize:
raise ValueError("order must be < ksize")
elif ksize == 3:
if order == 0:
k = np.array([1, 2, 1])
elif order == 1:
k = np.array([-1, 0, 1])
else:
k = np.array([1, -2, 1])
else:
k = np.zeros(ksize + 1)
k[0] = 1
for i in range(ksize - order - 1):
oldval = k[0]
for j in range(1, ksize + 1):
newval = k[j] + k[j - 1]
k[j - 1] = oldval
oldval = newval
for i in range(order):
oldval = -k[0]
for j in range(1, ksize + 1):
newval = k[j - 1] - k[j]
k[j - 1] = oldval
oldval = newval
k = k[:-1]
return k