形态学侵蚀 - Scipy ndimage与Scikit image的区别

4 投票
1 回答
3402 浏览
提问于 2025-04-18 14:44

在Scipy的ndimage和Scikit-image这两个库中,形态学操作符的表现是不同的。我猜测它们处理边界条件的方式也不一样:

import numpy as np
from scipy import ndimage
from skimage import morphology

scp = ndimage.binary_erosion(np.ones((10,10),dtype="uint8"),).astype("uint8")
sci = morphology.binary_erosion(np.ones((10,10),dtype="uint8"),morphology.disk(1))

在Scipy中,结果是我预期的,但在Scikit-image中却不是:

>>>> scp
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
   [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
   [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
   [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
   [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
   [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
   [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
   [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
   [0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
   [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)

>>>> sci
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
   [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8)

我该如何在Scikit-image的形态学操作中设置边界条件呢?

最好的问候

1 个回答

3

好的,这里不是在讨论“border_value”这个参数。

我在skimage/morphology/binary.py文件里发现了一些东西:

import numpy as np
from scipy import ndimage

def binary_erosion(image, selem, out=None):
    conv = ndimage.convolve(image > 0, selem, output=out,
                            mode='constant', cval=1) <---Here!
    if conv is not None:
        out = conv
    return np.equal(out, np.sum(selem), out=out)

根据Scipy的参考指南:

scipy.ndimage.filters.convolve(input, weights, output=None, mode='reflect', cval=0.0, origin=0):

mode : {‘reflect’,’constant’,’nearest’,’mirror’, ‘wrap’},这是可选的参数。

这个mode参数决定了数组边缘是怎么处理的。如果选择‘constant’模式,边缘之外的值会被设置为cval。默认是‘reflect’模式。cval : 这是一个数值,可选的参数。如果选择‘constant’模式,超出输入边缘的值会被填充为这个cval。默认值是0.0 <-----就在这里!

谜团解开了!

撰写回答