[英]Summing each 3x3 window of a M*N matrix, into a M/3*N/3 matrix with numpy
我正在尝试实现一个函数,该函数将给定矩阵的每个3x3窗口求和(或最终平均),并使用每个窗口的结果创建一个小9x的矩阵。
我无法找到一个有效和简洁的方法来做numpy。
有任何想法吗 ?
谢谢!
最简单的numpy方法,在卷积方面做得少得多,因此可能比基于fileter的方法更快,是将原始数组调整为具有额外维度的数组,然后通过对新维度求和将其减少回正常:
>>> arr = np.arange(108).reshape(9, 12)
>>> rows, cols = arr.shape
>>> arr.reshape(rows//3, 3, cols//3, 3).sum(axis=(1, 3))
array([[117, 144, 171, 198],
[441, 468, 495, 522],
[765, 792, 819, 846]])
如果你想要均值,你只需将得到的数组除以元素数:
>>> arr.reshape(rows//3, 3, cols//3, 3).sum(axis=(1, 3)) / 9
array([[ 13., 16., 19., 22.],
[ 49., 52., 55., 58.],
[ 85., 88., 91., 94.]])
此方法仅在您的数组的形状本身是3的倍数时才有效。
为了达到您要求的目标,我将在图像上应用[3x3]
盒式滤镜,而不是使用最近邻插值来调整矩阵的大小。
# Pseudo code
kernel = np.array([[1/9, 1/9, 1/9],
[1/9, 1/9, 1/9],
[1/9, 1/9, 1/9]])
avg_data= ndimage.convolve(data, kernel)
smaller_data = scipy.misc.imresize(avg_data, org_size/3, interp='nearest', mode=None)
如果你想要更高效的东西 - 正如@Jaime指出的那样 - 你可以做类似这样的事情我怎样才能有效地处理类似于Matlab的blkproc(blockproc)函数的块中的numpy数组 :
from numpy.lib.stride_tricks import as_strided as ast
def block_view(A, block= (3, 3)):
"""Provide a 2D block view to 2D array. No error checking made.
Therefore meaningful (as implemented) only for blocks strictly
compatible with the shape of A."""
# simple shape and strides computations may seem at first strange
# unless one is able to recognize the 'tuple additions' involved ;-)
shape= (A.shape[0]/ block[0], A.shape[1]/ block[1])+ block
strides= (block[0]* A.strides[0], block[1]* A.strides[1])+ A.strides
return ast(A, shape= shape, strides= strides)
if __name__ == '__main__':
B = block_view(A).sum(axis=(2,3))
当您尝试了解正在发生的事情时,请记住步幅表示我们需要在内存中偏移以遍历每个维度中的下一个单元格的字节数。 因此,如果您正在处理int32
数据类型,它将是4
的乘法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.