二元扩张的对立面

2024-06-16 10:17:55 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有一个函数与binary_dilation相反?我希望从0和1的数组中删除“孤岛”。也就是说,如果2D数组中的值1没有至少1个相邻的邻居也为1,则其值将设置为0(而不是像binary_dilation中那样将其邻居的值设置为1)。例如:

test = np.zeros((5,5))
test[1,1] = test[1,2] = test[3,3] = test[4,3] = test[0,3] = test[3,1] = 1

test
array([[0., 0., 0., 1., 0.],
       [0., 1., 1., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 1., 0., 1., 0.],
       [0., 0., 0., 1., 0.]])

我要寻找的函数将返回:

array([[0., 0., 0., 0., 0.],
       [0., 1., 1., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 1., 0.]])

请注意,位置[0,3]和[3,1]中的值从1更改为0,因为它们没有值等于1的相邻值(对角线不算作相邻值)。你知道吗


Tags: 函数testnpzeros数组arraybinary对角线
1条回答
网友
1楼 · 发布于 2024-06-16 10:17:55

您可以创建一个包含单元格的掩码来检查,并使用test进行二维卷积,以识别与其相邻的1单元格。卷积和test的逻辑与应该产生所需的输出。你知道吗

首先定义你的面具。由于只查找上/下和左/右邻接,因此需要以下内容:

mask = np.ones((3, 3))
mask[1,1] = mask[0, 0] = mask[0, 2] = mask[2, 0] = mask[2, 2] = 0
print(mask)
#array([[0., 1., 0.],
#       [1., 0., 1.],
#       [0., 1., 0.]])

如果您想包含对角线元素,只需更新mask以在角点中包含1。你知道吗

现在应用testmask的二维卷积。这将两个矩阵的值相乘和相加。使用此掩码,将返回每个单元格的所有相邻值之和。你知道吗

from scipy.signal import convolve2d
print(convolve2d(test, mask, mode='same'))
#array([[0., 1., 2., 0., 1.],
#       [1., 1., 1., 2., 0.],
#       [0., 2., 1., 1., 0.],
#       [1., 0., 2., 1., 1.],
#       [0., 1., 1., 1., 1.]])

必须指定mode='same',以便结果与第一个输入(test)的大小相同。请注意,要从test中删除的两个单元格在卷积输出中是0。你知道吗

最后,使用此输出和test执行按元素的and操作以查找所需的单元格:

res = np.logical_and(convolve2d(test, mask, mode='same'), test).astype(int)
print(res)
#array([[0, 0, 0, 0, 0],
#       [0, 1, 1, 0, 0],
#       [0, 0, 0, 0, 0],
#       [0, 0, 0, 1, 0],
#       [0, 0, 0, 1, 0]])

更新

在最后一步中,您还可以clip将0和1之间的卷积中的值进行逐元素乘法。你知道吗

res = convolve2d(test, mask, mode='same').clip(0, 1)*test
#array([[0., 0., 0., 0., 0.],
#       [0., 1., 1., 0., 0.],
#       [0., 0., 0., 0., 0.],
#       [0., 0., 0., 1., 0.],
#       [0., 0., 0., 1., 0.]])

相关问题 更多 >