<p>在图像处理中,最常用的方法是使用求和面积表,这是1984年<a href="http://classes.soe.ucsc.edu/cmps160/Fall05/papers/p207-crow.pdf">this paper</a>中引入的一种思想。其思想是,当你通过在一个窗口上加上来计算一个数量,并将窗口(例如,向右移动一个像素)时,你不需要添加新窗口中的所有项,你只需要从总数中减去最左边的列,然后添加新的最右边的列。因此,如果从数组中在两个维度上创建一个累加和数组,则可以在一个窗口上通过两个和和和一个减法得到和。如果为数组及其平方保留面积求和表,那么很容易从这两个表中得到方差。下面是一个实现:</p>
<pre><code>def windowed_sum(a, win):
table = np.cumsum(np.cumsum(a, axis=0), axis=1)
win_sum = np.empty(tuple(np.subtract(a.shape, win-1)))
win_sum[0,0] = table[win-1, win-1]
win_sum[0, 1:] = table[win-1, win:] - table[win-1, :-win]
win_sum[1:, 0] = table[win:, win-1] - table[:-win, win-1]
win_sum[1:, 1:] = (table[win:, win:] + table[:-win, :-win] -
table[win:, :-win] - table[:-win, win:])
return win_sum
def windowed_var(a, win):
win_a = windowed_sum(a, win)
win_a2 = windowed_sum(a*a, win)
return (win_a2 - win_a * win_a / win/ win) / win / win
</code></pre>
<p>要确保这一点:</p>
<pre><code>>>> a = np.arange(25).reshape(5,5)
>>> windowed_var(a, 3)
array([[ 17.33333333, 17.33333333, 17.33333333],
[ 17.33333333, 17.33333333, 17.33333333],
[ 17.33333333, 17.33333333, 17.33333333]])
>>> np.var(a[:3, :3])
17.333333333333332
>>> np.var(a[-3:, -3:])
17.333333333333332
</code></pre>
<p>这应该比基于卷积的方法快一些。</p>