skimage.filters.laplace 函数在 Python 中如何工作?

How does the skimage.filters.laplace function work in Python?

我正在尝试找出 skimage.filters 的 laplace 函数中使用的内核。我知道拉普拉斯滤波器基于矩阵卷积,但我似乎无法理解 skimage.filters 的拉普拉斯函数产生的值。

这是一个例子:

>>> import numpy as np
>>> import skimage
>>> from skimage.filters import laplace
>>> x = [[2,3,2],[5,3,6],[3,7,3]]
>>> x = np.array(x)
>>> x
array([[2, 3, 2],
       [5, 3, 6],
       [3, 7, 3]])
>>> laplace(x, ksize=3)
array([[ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
       [ 0.00000000e+00, -9.75781955e-19,  0.00000000e+00],
       [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00]])

如果skimage.filters的拉普拉斯函数使用kernel/operator的

[[ 0,  1, 0],
 [ 1, -4, 1],
 [ 0,  1, 0]]

那么根据矩阵卷积,应该会产生

的输出
[[ 0,  5, -1],
 [12, -9, 16],
 [ 0, 19, -1]]

而不是

[[ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00],
 [ 0.00000000e+00, -9.75781955e-19,  0.00000000e+00],
 [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00]]

我对 kernel/operator skimage.filters 的拉普拉斯函数使用什么让几乎每个输出值都如此接近零感到非常困惑,例如 -9.75781955e-19。老实说,我不认为任何合理的 kernel/operator 可以产生这个输出,所以也许我只是不明白 Python 的 skimage.filters 的拉普拉斯函数是如何工作的...

对这个问题的任何 help/comments/suggestions/insights 将不胜感激。谢谢。

欢迎来到 Stack Overflow 的 scikit-image 线程!这种奇怪行为的原因是 xdtypeint64,而 scikit-image laplace 函数调用 img_as_float 来进行计算在浮点数中,但在转换 dtype 时,它​​还会将数组除以原始 dtype 的最大值(此处为 2^63 - 1),因此值非常小。如果你想避免这个问题,你可以在将图像传递给 laplace 之前将图像转换为浮动:

>>> x = x.astype(np.float)                                                
>>> filters.laplace(x)                                                    
array([[-4.,  2., -5.],
       [ 7., -9., 10.],
       [-6., 12., -7.]])

(该函数使用scipy.ndimage.convolve的默认边界条件模式,即'reflect')。

请注意,这种行为(除以 dtype 的最大值)可能会随着 scikit-image 1.0 发生变化,正是因为我们注意到它可能会像您的情况一样让用户感到困惑。