这里有一种向量化方法来创建这些边缘像素/元素的掩码,然后只需索引数组即可获取它们 -
def border_elems(a, W):
n = a.shape[0]
r = np.minimum(np.arange(n)[::-1], np.arange(n))
return a[np.minimum(r[:,None],r)<W]
再次强调,这不完全是为了性能而设计的,而是为了在需要变化边缘宽度或创建此类边缘元素的掩码时使用。该掩码将是:np.minimum(r[:,None],r)<W
,如上一步所创建。
示例运行 -
In [89]: a
Out[89]:
array([[49, 49, 12, 90, 42],
[91, 58, 92, 16, 78],
[97, 19, 58, 84, 84],
[86, 31, 80, 78, 69],
[29, 95, 38, 51, 92]])
In [90]: border_elems(a,1)
Out[90]: array([49, 49, 12, 90, 42, 91, 78, 97, 84, 86, 69, 29, 95, 38, 51, 92])
In [91]: border_elems(a,2) # Note this will select all but the center one : 58
Out[91]:
array([49, 49, 12, 90, 42, 91, 58, 92, 16, 78, 97, 19, 84, 84, 86, 31, 80,
78, 69, 29, 95, 38, 51, 92])
对于通用形状,我们可以这样扩展 -
def border_elems_generic(a, W):
n1 = a.shape[0]
r1 = np.minimum(np.arange(n1)[::-1], np.arange(n1))
n2 = a.shape[1]
r2 = np.minimum(np.arange(n2)[::-1], np.arange(n2))
return a[np.minimum(r1[:,None],r2)<W]
2D卷积
基于通用形状的解决方案
这是另一种使用2D卷积
来处理通用二维形状的解决方案 -
from scipy.signal import convolve2d
k = np.ones((3,3),dtype=int)
boundary_elements = a[convolve2d(np.ones(a.shape,dtype=int),k,'same')<9]
示例运行 -
In [36]: a
Out[36]:
array([[4, 3, 8, 3, 1],
[1, 5, 6, 6, 7],
[9, 5, 2, 5, 9],
[2, 2, 8, 4, 7]])
In [38]: k = np.ones((3,3),dtype=int)
In [39]: a[convolve2d(np.ones(a.shape,dtype=int),k,'same')<9]
Out[39]: array([4, 3, 8, 3, 1, 1, 7, 9, 9, 2, 2, 8, 4, 7])