繁体   English   中英

numpy数组中每个元素的邻居的加权数组

[英]Weighted array of neighbors for each element in a numpy array

我有一个numpy array(A)和一个权重矩阵(例如m,这是一种过滤器)。 我想将此过滤器应用于A的每个元素,并获得A的每个元素的邻居数组乘以m。

例如,如果m是3x3内核,则得到:

对于每个(i,j),A [i,j]->数组([A [i-1,j-1] * m [0,0],A [i-1,j] * m [0 ,1],...,A [I + 1,J + 1] * M [2,2]])

因此,输出将比A大一维。对于边界情况,最好需要考虑部分过滤器(等效于零填充)。 有什么办法可以有效地做到这一点?

这是一种使用skimage's view_as_windows的方法,可为我们提供所需内核形状的滑动窗口-

from skimage.util import view_as_windows as viewW

# Pad with one layer of zeros around input array 
a1 = np.lib.pad(a, (1,1), 'constant', constant_values=0)

# Create 3x3 sliding windows for each elem and multiply with m.
# Reshape each window as a 9 elem list as per requirement.
out = (viewW(a1,[3,3])*m).reshape(a.shape + (9,))

样品运行:

1]输入数组-

In [64]: a            
Out[64]: 
array([[75, 46, 74, 72, 96],
       [44, 72, 41, 81, 50],
       [16, 70, 22, 19, 49],
       [87, 74, 78, 66, 49]])

2]填充输入数组-

In [65]: a1  
Out[65]: 
array([[ 0,  0,  0,  0,  0,  0,  0],
       [ 0, 75, 46, 74, 72, 96,  0],
       [ 0, 44, 72, 41, 81, 50,  0],
       [ 0, 16, 70, 22, 19, 49,  0],
       [ 0, 87, 74, 78, 66, 49,  0],
       [ 0,  0,  0,  0,  0,  0,  0]])

3] 3D输出阵列-

In [66]: out       
Out[66]: 
array([[[  0,   0,   0,   0, 450, 276,   0, 220, 504],
        [  0,   0,   0, 450, 276, 444, 352, 360, 287],
        [  0,   0,   0, 276, 444, 432, 576, 205, 567],
        [  0,   0,   0, 444, 432, 576, 328, 405, 350],
        [  0,   0,   0, 432, 576,   0, 648, 250,   0]],

       [[  0, 300, 276,   0, 264, 432,   0,  80, 490],
        [375, 184, 444, 264, 432, 246, 128, 350, 154],
        [230, 296, 432, 432, 246, 486, 560, 110, 133],
        [370, 288, 576, 246, 486, 300, 176,  95, 343],
        [360, 384,   0, 486, 300,   0, 152, 245,   0]],

       [[  0, 176, 432,   0,  96, 420,   0, 435, 518],
        [220, 288, 246,  96, 420, 132, 696, 370, 546],
        [360, 164, 486, 420, 132, 114, 592, 390, 462],
        [205, 324, 300, 132, 114, 294, 624, 330, 343],
        [405, 200,   0, 114, 294,   0, 528, 245,   0]],

       [[  0,  64, 420,   0, 522, 444,   0,   0,   0],
        [ 80, 280, 132, 522, 444, 468,   0,   0,   0],
        [350,  88, 114, 444, 468, 396,   0,   0,   0],
        [110,  76, 294, 468, 396, 294,   0,   0,   0],
        [ 95, 196,   0, 396, 294,   0,   0,   0,   0]]])

4]让我们验证结果。 未填充区域上的第一个滑动窗口将是a[:3,:3] 让我们将其乘以m 乘法后,应与out[1,1,:] -

In [67]: a[:3,:3]*m
Out[67]: 
array([[375, 184, 444],
       [264, 432, 246],
       [128, 350, 154]])

In [68]: out[1,1,:]
Out[68]: array([375, 184, 444, 264, 432, 246, 128, 350, 154])

在这里值得一提的是,滑动窗口的3D数组只是视图,因此在涉及这些内容的进一步操作中非常有效-

In [75]: np.may_share_memory(a1,viewW(a1,[3,3]))
Out[75]: True

您要描述的是卷积,卷积常用于图像处理(wiki: https : //zh.wikipedia.org/wiki/内核_(image_processing ; http://www.songho.ca/dsp/convolution/convolution2d_example。 html )。

可以通过scipy.signal.convolve2d(arr, filter)来获得所需的结果。 如上面链接中所述,卷积将过滤器或内核矩阵旋转180度,因此您可以利用numpy.rot90(array)实现所需的效果。

方法签名可能最终看起来像:

scipy.signal.convolve2d(arr, np.rot90(np.rot90(filter)))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM