在Python中快速运行滑动窗口方法的技巧

时间:2017-10-19 12:32:54

标签: python python-2.7 opencv sliding-window

Haar级联分类器使用带金字塔的滑动窗口方法来检测对象。对我来说,检测图像中的对象大约需要0.01秒。但是我的问题是在使用滑动窗口方法时如何快速? (我为检测对象实现了CNN,它使用滑动窗口检测没有金字塔的对象,尽管检测对象需要2秒钟)。我想知道更快地运行滑动窗口的技巧是什么?我使用了两个循环来滑动整个图像,但也使它平行,但它仍然比OpenCV实现慢得多。

1 个答案:

答案 0 :(得分:1)

(以我的经验)最快的方法是使用numpy.lib.stride_tricks.as_strided函数。实际上,我们要做的是首先使用numpy函数将所有补丁(滑动窗口位置)生成并存储在一个大数组中。然后我们可以将该数组映射到我们的函数。

首先,定义定义为的形状(图像高度,图像宽度,内核高度,内核宽度)。然后您可以跨越图像的各个位(即8位图像,每个像素为8位跨度)。在这种情况下,补丁将是图像步幅的两次重复。您可以使用img.strides检查步幅。

def some_func(roi):
    '''
    simple function to return the mean of the region
    of interest
    '''
    return np.mean(roi)

img = np.zeros((30000,30000), dtype=np.uint8)
img_shape = img.shape

size = 3 # window size i.e. here is 3x3 window

shape = (img.shape[0] - size + 1, img.shape[1] - size + 1, size, size)
strides = 2 * img.strides
patches = stride_tricks.as_strided(img, shape=shape, strides=strides)
patches = patches.reshape(-1, size, size)

output_img = np.array([some_func(roi) for roi in patches])
output_img.reshape(img_size)

在某些情况下,您还可以执行其他一些功能,例如对函数np.vectorize()进行矢量化处理。如果您想计算均值,则也可以只使用output_img = patches.mean(axis=(-1, -2))来避免映射到函数或重塑的需要。还有可能更快地将数组映射到函数see this post的方法。我已经给出了这种解决方案,因为可以将任何过程添加到函数中,而且这个问题似乎很笼统。