numpy滑动2d窗口计算

时间:2015-09-18 21:00:02

标签: python numpy multidimensional-array neighbours

我正在尝试学习一种方法来使用numpy来有效地解决在各种情况下涉及滑动窗口的问题。这是一个示例,说明我感兴趣的问题类型:

我有一个大的2d矩阵,我想对矩阵中每个元素的邻居进行计算。例如,我可能想要找到最大值,在每个索引处的(x-1,y)(x + 1,y + 1)索引处排除一些特殊的negibors值,并将结果放入另一个不同的2d“解决方案“矩阵。

请注意,convolution2d虽然有用但在这种情况下对我不起作用,因为我在每个像素上都有特定的操作,并且只想在特定的邻居(每个像素)上进行操作。

另外一个好处就是确保我不会超出界限。

最后,是否可以使用任何州?在所有邻居都为0的情况下,我希望分配一个新的整数id,每次发生时我都会增加。

以下是一个例子:

Window:

0 0 1
1 0 0
0 0 0


Input:

0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 9 9 0 0 9 0 0
0 0 0 0 0 0 0 0 0

Output:

0 0 0 0 0 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 1 0 0 2 0 0
0 0 0 0 0 0 0 0 0

4 个答案:

答案 0 :(得分:3)

使用np.roll()创建辅助矩阵。然后执行初始和辅助矩阵之间所需的任何操作。例如,取中央单元和两个邻居的平均值:

{{1}}

此外,roll()在边缘滚动,因此无需担心边界。

答案 1 :(得分:1)

我曾经创建过这个函数来将2D数组中的滑动块存储到列中,因此我们曾经认为在2D数组上的滑动窗口中应用的任何操作都可以轻松地应用于列。请在this solutionImplement Matlab's im2col 'sliding' in python了解详情。

现在,NumPy支持沿指定轴应用其大部分功能。因此,使用此工具,我们可以有效地以$(document).ready(function() { var mainPara = $(".para").children("p"), longPara = mainPara.html().substr(0), shortPara = mainPara.html().substr(0, 380); mainPara.html(shortPara).append("...<a class='linkBtn more' href='#'>show more</a>"); $(".linkBtn").each(function() { $(this).click(function(){ $(this).parent().html(longPara).append("<a class='linkBtn less' href='#'>show less</a>"); }); }); }); 方式在滑动窗口中应用几乎任何操作。这是它的正式定义 -

vectorized

以下是我们如何使用此工具解决手头的问题,假设def im2col(A,BLKSZ): # Parameters M,N = A.shape col_extent = N - BLKSZ[1] + 1 row_extent = M - BLKSZ[0] + 1 # Get Starting block indices start_idx = np.arange(BLKSZ[0])[:,None]*N + np.arange(BLKSZ[1]) # Get offsetted indices across the height and width of input array offset_idx = np.arange(row_extent)[:,None]*N + np.arange(col_extent) # Get all actual indices & index into input array for final output return np.take (A,start_idx.ravel()[:,None] + offset_idx.ravel()) 为2D输入数组 -

A

示例运行 -

# Get 3x3 sliding blocks from A and set them as columns.
Acol = im2col(A,[3,3])

# Setup kernel mask
kernel = np.ones((3,3),dtype=bool)
kernel[2,1:] = 0

# Mask rows of Acol with kernel and perform any operation, let's say MAX
out = Acol[kernel.ravel()].max(0).reshape(A.shape[0]-2,A.shape[1]-2)

答案 2 :(得分:1)

假设您的原始2D矩阵命名为A并且具有大小(n,m)

# extraction of 3x3 sub-matrices and storage in a new 2D matrix
B = [ [ A[i-1:i+2, j-1:j+2] for i in range(1, n-1) ] for j in range(1, m-1) ]
# conversion to a mask array
B = np.ma.array( B, mask=False )
# masking the unwanted elements of each sub-matrix
B.mask[:, :, 1, 2] = True
B.mask[:, :, 2, 2] = True

注意:选择创建子矩阵时的i和j的范围是为了避免边界。

对子矩阵B [i,j]的操作将忽略被遮罩的元素。

现在,在每个子矩阵上执行numpy操作(例如子矩阵的最大值)并将结果存储在2D矩阵中:

C = [ [ np.max(B[i,j]) for i in range(n-2) ] for j in range(m-2) ]

答案 3 :(得分:0)

我使用以下内容作为可读解决方案:

import numpy as np

def get_windows(arr, window_size=64, step=32):
  windows = []
  row = 0
  col = 0
  max_row, max_col = arr.shape
  while row < max_row:
    while col < max_col:
      windows.append(arr[row:row+window_size, col:col+window_size])
      col += step
    row += step
    col = 0
  return windows

a = np.random.rand(4, 4)
windows = get_windows(a, window_size=2, step=1)