如何在Numpy中获得图像的8邻居值作为第三维

时间:2017-03-06 16:07:43

标签: opencv numpy

给定2d图像数据,对于每个像素P1,如何从中获取以下3d数组?

P9  P2  P3
P8  P1  P4
P7  P6  P5

img [x,y,:] = [P2,P3,P4,P5,P6,P7,P8,P9,P2]

不使用forloop,只是numpy操作(因为性能问题)

1 个答案:

答案 0 :(得分:1)

这是一种使用zeros填充边界元素并使用NumPy strides和内置scikit-image's view_as_windows进行有效滑动窗口提取的方法 -

from skimage.util import view_as_windows as viewW

def patches(a, patch_shape):     
    side_size = patch_shape
    ext_size = (side_size[0]-1)//2, (side_size[1]-1)//2
    img = np.pad(a, ([ext_size[0]],[ext_size[1]]), 'constant', constant_values=(0))
    return viewW(img, patch_shape)

示例运行 -

In [98]: a = np.random.randint(0,255,(5,6))

In [99]: a
Out[99]: 
array([[139, 176, 141, 172, 192,  81],
       [163, 115,   7, 234,  72, 156],
       [ 75,  60,   9,  81, 132,  12],
       [106, 202, 158, 199, 128, 238],
       [161,  33, 211, 233, 151,  52]])

In [100]: out = patches(a, [3,3]) # window size = [3,3]

In [101]: out.shape
Out[101]: (5, 6, 3, 3)

In [102]: out[0,0]
Out[102]: 
array([[  0,   0,   0],
       [  0, 139, 176],
       [  0, 163, 115]])

In [103]: out[0,1]
Out[103]: 
array([[  0,   0,   0],
       [139, 176, 141],
       [163, 115,   7]])

In [104]: out[-1,-1]
Out[104]: 
array([[128, 238,   0],
       [151,  52,   0],
       [  0,   0,   0]])

如果你想要一个3D数组,最后可以添加reshape,就像这样 -

out.reshape(a.shape + (9,))

但是,请注意,这将创建一个副本,而不是我们从函数本身获得的有效的基于步骤的视图。