如何高效迭代提取二维NumPy数组的滑动窗口子集?
高效实现Numpy数组的滑动窗口提取
处理大图像的滑动窗口遍历,嵌套循环的效率极低,尤其是图像尺寸较大时。下面提供两种无需嵌套循环的高效实现方式:
方法1:使用numpy.lib.stride_tricks.as_strided
这个方法直接利用数组的内存步长创建滑动窗口视图,不会额外复制数据,效率极高。但需要手动计算步长,使用时要注意避免越界访问:
import numpy as np # 示例数据 image = np.array([[1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]]) window_size = 3 # 计算输出的窗口数量 num_windows_h = image.shape[0] - window_size + 1 num_windows_w = image.shape[1] - window_size + 1 # 计算步长:复用原数组的行、列步长 strides = image.strides + image.strides # 创建滑动窗口视图 windows = np.lib.stride_tricks.as_strided( image, shape=(num_windows_h, num_windows_w, window_size, window_size), strides=strides ) # 查看结果 print(windows.shape) # 输出 (3, 3, 3, 3),对应3行3列的窗口位置 print(windows[0, 0]) # 第一个窗口,和手动切片结果一致
输出:
(3, 3, 3, 3) array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
方法2:使用skimage.util.view_as_windows
如果你不想手动处理步长,scikit-image库提供了封装好的view_as_windows函数,安全且易用,同样是创建视图不复制数据:
先安装依赖(未安装的话):
pip install scikit-image
代码实现:
import numpy as np from skimage.util import view_as_windows # 示例数据 image = np.array([[1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5], [1,2,3,4,5]]) window_size = 3 # 创建滑动窗口 windows = view_as_windows(image, window_shape=(window_size, window_size)) # 查看结果 print(windows.shape) # 输出 (3, 3, 3, 3) print(windows[0, 0]) # 第一个窗口
输出:
(3, 3, 3, 3) array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
遍历窗口的优化方式
如果需要逐个处理窗口,直接对生成的windows数组索引即可,相比原嵌套循环,这里没有每次切片的开销,效率提升明显:
for i in range(windows.shape[0]): for j in range(windows.shape[1]): window = windows[i, j] top_left = (j, i) bottom_right = (j + window_size, i + window_size) print(f'Window position: {top_left} -> {bottom_right}') print(window)
内容的提问来源于stack exchange,提问作者sermomon
相关产品推荐
相关产品推荐

