在Numpy数组中创建缓冲区

在Numpy数组中创建缓冲区,numpy,scipy,scikit-image,Numpy,Scipy,Scikit Image,我有一个二进制图像,如下所示: data = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0], [0, 0 , 0 , 0 , 0 , 0 , 0 , 0], [0, 0 , 1 , 1 , 1 , 1 , 0 , 0], [0, 0 , 1 , 1 , 1 , 1 , 0 , 0], [0, 0 , 1 , 1 , 1 , 1

我有一个二进制图像,如下所示:

data = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0]])
对于具有1s值的像素,我想使缓冲区由两个像素组成,每四个方向包围一个值为1s的像素。预期结果将是:

result=np.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和0,那么可以使用2D卷积来完成,这很简单,也很有效

from scipy.signal import convolve2d

data = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0]])

# the kernel doesn't need to be ones, it just needs to be positive and
# non-zero.
kernel = np.ones((5, 5))

result = np.int64(convolve2d(data, kernel, mode='same') > 0)
这将为您提供所需的输出。您需要定义要在边缘发生什么-在这个版本中,输出数组与输入数组的大小相同

如果你有一个稀疏数组,你可能会做得更快

如果数组中的值不是1和0,则需要更多的考虑。

您也可以使用运算符(在本例中,它扩展了
值)


注意,在这种情况下,
square(5)
相当于
np.one((5,5))
。膨胀操作符通过将元素作为第二个参数传递(在本例中,每个像素的中心是一个
5x5
正方形)来膨胀
True
1
像素。

它是一个仅由1和0组成的数组,还是有其他值?是的,它只有1s和0s为什么需要“正非零内核”?我看不出任何原因,文档也没有提到这一点()。您不需要使用
convalve2d
,但需要使用该方法(特别是
>0
)。@HenryGomersall感谢您的回答。你能解释一下为什么使用(5,5)的内核吗?它创建了一个5x5的数组。你熟悉卷积运算吗?在注释中解释可能有点费事,但本质上,5x5形状是您在输入中单个
1
的输出所需的形状。值得一提的是,2D内核是可分离的,因此您可以在每个维度上使用一对1D内核来实现这一点,如果这是一个问题,那么速度会更快。
from skimage.morphology import square, dilation
data = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
                 [0, 0 , 0 , 0 , 0 , 0 , 0 , 0]])
result = dilation(data, square(5))