1

我正在尝试实现与此问题类似的目标。目标是计算至少有两个直接邻居(上、下、左、右)的 1 的数量,与我的版本的唯一区别是序列中必须至少有一个十字或角。

例如,

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

星号 *1 不算,因为它的邻居没有形成角或十字。右上角 1 也没有,因为它没有两个邻居。答案是 2(右下和左下)。

这是我尝试过的:

import numpy as np
a = np.zeros((6,6), dtype=np.int)
a[0,5] = 1
a[1,1] = a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1
a[3,0] = a[4,0] = a[5,0] = a[4,1] = 1

from scipy import ndimage
kernel = ndimage.generate_binary_structure(2, 1)
kernel[1, 1] = 0

b = convolve(a, kernel, mode="constant")
c = b[a>0]

# At least 2 neighbours
return len(c[c >= 2])

但它仍然从第二行计算星号 *1(返回 3 而不是 2)!

谢谢你的帮助!

4

2 回答 2

2

您的标准可以重述为“至少一个水平邻居和至少一个垂直邻居”。所以做任何邻居检测,你最终会选择不是在 2D 中,而是在 1D 中选择两次,一次是水平的,一次是垂直的:

例如,使用scipy.ndimagewhich 提供convolve1d

import scipy.ndimage as sn

(sn.convolve1d(in_,(1,3,1),axis=0,mode="constant")>>2) & (sn.convolve1d(in_,(1,3,1),axis=1,mode="constant")>>2)
# array([[0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [0, 0, 0, 0, 0, 0],
#        [1, 0, 0, 0, 1, 0],
#        [0, 0, 0, 0, 0, 0]])

in_是 OP 中的示例数组。)

于 2020-12-18T18:20:42.150 回答
1

您正在尝试二维卷积。您可能想尝试一个“十字形”内核,这将导致相关单元格为 3 或更多(=1+2,1 来自中心的 1,2 来自邻居)。signal.convolve2dfromscipy完成此操作,如下所示:

import numpy as np
from scipy import ndimage
from scipy import signal

a = np.zeros((6,6), dtype=np.int)
a[0,5] = 1
a[1,1] = a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1
a[3,0] = a[4,0] = a[5,0] = a[4,1] = 1

print(a)

#kernel = ndimage.generate_binary_structure(2, 1)
#kernel[1, 1] = 0
kernel = np.array([[0,1,0], [1,1,1], [0,1,0]])

#b = np.convolve(a, kernel, mode="constant")
#c = b[a>0]
b = signal.convolve2d(a, kernel, mode='same')

# At least 2 neighbours
#return len(c[c >= 2])
print(b)
print(np.where(b > 2, b, 0))

这会产生(我已经用 过滤了结果np.where):

[[0 0 0 0 0 1]
 [0 1 1 1 0 0]
 [0 0 0 0 0 0]
 [1 0 0 0 0 0]
 [1 1 0 1 1 0]
 [1 0 0 0 1 0]]
[[0 1 1 1 1 1]
 [1 2 3 2 1 1]
 [1 1 1 1 0 0]
 [2 2 0 1 1 0]
 [4 2 2 2 3 1]
 [2 2 0 2 2 1]]
[[0 0 0 0 0 0]
 [0 0 3 0 0 0]
 [0 0 0 0 0 0]
 [0 0 0 0 0 0]
 [4 0 0 0 3 0]
 [0 0 0 0 0 0]]

1 的位置已正确识别(3 或 4)。

于 2020-12-18T14:53:26.683 回答