您可以使用numpy.lib.stride_tricks.as_strided
来获取图像的窗口视图:
import numpy as np
from numpy.lib.stride_tricks import as_strided
rows, cols = 500, 500
win_rows, win_cols = 5, 5
img = np.random.rand(rows, cols)
win_img = as_strided(img, shape=(rows-win_rows+1, cols-win_cols+1,
win_rows, win_cols),
strides=img.strides*2)
现在,win_img[i, j]
是以位置[i,j]
为左上角的(win_rows,win_cols)
数组:
>>> img[100:105, 100:105]
array([[ 0.34150754, 0.17888323, 0.67222354, 0.9020784 , 0.48826682],
[ 0.68451774, 0.14887515, 0.44892615, 0.33352743, 0.22090103],
[ 0.41114758, 0.82608407, 0.77190533, 0.42830363, 0.57300759],
[ 0.68435626, 0.94874394, 0.55238567, 0.40367885, 0.42955156],
[ 0.59359203, 0.62237553, 0.58428725, 0.58608119, 0.29157555]])
>>> win_img[100,100]
array([[ 0.34150754, 0.17888323, 0.67222354, 0.9020784 , 0.48826682],
[ 0.68451774, 0.14887515, 0.44892615, 0.33352743, 0.22090103],
[ 0.41114758, 0.82608407, 0.77190533, 0.42830363, 0.57300759],
[ 0.68435626, 0.94874394, 0.55238567, 0.40367885, 0.42955156],
[ 0.59359203, 0.62237553, 0.58428725, 0.58608119, 0.29157555]])
然而,你需要小心,不要将图像的窗口视图转换为窗口副本:在我的例子中,这将需要25倍的存储空间。我相信numpy 1.7可以让你选择多个轴,因此你可以简单地执行以下操作:
>>> np.var(win_img, axis=(-1, -2))
我被困在numpy 1.6.2上,所以无法进行测试。另一个选项是,如果我记得我的数学没错的话,也许不能处理太大的窗口:
>>> win_mean = np.sum(np.sum(win_img, axis=-1), axis=-1)/win_rows/win_cols
>>> win_sqr_mean = np.sum(np.sum(win_img**2, axis=-1), axis=-1)/win_rows/win_cols
>>> win_var = win_sqr_mean - win_mean**2
现在win_var
是一个数组,其形状为
>>> win_var.shape
(496, 496)
win_var[i, j]
保存的是以[i, j]
为左上角的(5, 5)
窗口的方差。