是否有一个功能与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(对角线不计为邻居)。
答案 0 :(得分:2)
您可以使用单元格创建一个遮罩以进行检查,并使用test
进行2d卷积,以识别与它们相邻的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
。
现在将test
与mask
进行二维卷积。这会将两个矩阵的值相乘并相加。使用此掩码,将具有返回每个单元格所有相邻值之和的作用。
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
。
最后使用此输出和and
进行元素明智的test
操作,以找到所需的单元格:
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.]])