我想使用滑动窗口在图像上计算一些操作(GLCM)。实现它的代码是:
import numpy as np
from skimage.feature import greycomatrix, greycoprops
from numpy.lib.stride_tricks import as_strided
image = np.arange(36).reshape((6,6))
window = 5
result = np.zeros(image.shape)
for i in xrange(window/2,image.shape[0]-window/2):
for j in xrange(window/2,image.shape[1]-window/2):
sample = image[i-(window/2):i+(window/2)+1, j - (window/2):j+(window/2)+1]
glcm = greycomatrix(sample, [1], [0], 256, symmetric=False, normed=True)
result[i,j] = greycoprops(glcm, 'contrast')[0, 0]
它有效,但两个for循环非常昂贵。我想提高速度,所以,在网上浏览,我尝试使用 as_stride 技巧:
from numpy.lib.stride_tricks import as_strided
image = np.arange(36).reshape((6,6))
window = 5
y = as_strided(image,shape=(image.shape[0] - window + 1,\
image.shape[1] - window + 1,) +\
(window,window), strides=image.strides * 2)
例如,计算第一个窗口的GLCM:
glcm = greycoprops(greycomatrix(y[0,0], [1], [0], 256, symmetric=False, normed=True))[0][0]
我尝试将所有滑动窗口应用为:
glcm[:,:] = greycoprops(greycomatrix(y[:,:], [1], [0], 256, symmetric=False, normed=True))[0][0]
但在这种情况下,y[:,:]
没有ndim==2
y[0,0]
,ndim==4
,等等。我无法找到一种方法,以智能方式迭代保留ndim == 2
的所有子集( greycomatrix 函数所需)。
修改
我尝试使用ravel并在1D向量上工作,因此,只需1个for循环。这是代码:
a = y.ravel()
print a.shape
glcm=np.zeros(a.shape[0]/(window*window))
for i in np.arange(a.shape[0]/(window*window)):
glcm[i] = greycoprops(greycomatrix(a[i*25:i*25+25].reshape(5,5), [1], [0], 256, symmetric=False, normed=True))[0][0]
result= glcm.reshape(y.shape[0],y.shape[1])
处理时间增加......
答案 0 :(得分:1)
因为你忘了实际问一个问题,我会假设它是
如何快速运行?
嗯,在这种情况下,严酷的事实是,与python一样好,与单个像素操作相比,进行大量切片的python for
循环总是相对昂贵。 / p>
因此,如果速度是您的关注点,那么您应该使用允许您获取python绑定的语言(例如,C与cpython
)来实现某些函数,并使用该函数。
答案 1 :(得分:0)
使用as_strided
y
您仍然需要单独访问子数组,例如:
for i in range(y.shape[0]):
for j in range(y.shape[1]):
sample = y[i,j,...]
print sample
甚至
for row in y:
for sample in row:
print sample
除了你需要收集结果。
在这样的迭代中,as_strided
只有在更有效地访问子数组时才有好处。
但如果您可以重写GCLM计算以使用4d数组,那么它的真正好处就来了。一些numpy
操作被设计为在1或2个轴上操作,而其他操作只是“为了骑行而去”。例如,如果您的计算仅包括取图像的平均值。使用y
即可:
np.mean(y, axes=(-2,-1))