【问题标题】:Iteration multi-dimensional array in PythonPython中的迭代多维数组
【发布时间】:2015-01-16 09:38:47
【问题描述】:

我想使用滑动窗口对图像进行一些运算 (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 并处理一维向量,因此只有 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])

处理时间增加...

【问题讨论】:

    标签: python numpy multidimensional-array glcm


    【解决方案1】:

    由于您忘记实际提出问题,我将假设它是

    我怎样才能让它跑得快?

    好吧,在这种情况下,残酷的事实是,与 python 一样好,与单个像素操作相比,执行带有大量切片的 python for 循环总是相对昂贵。

    因此,如果您关心的是速度,您应该使用一种语言实现一些函数,使您可以获取 python 绑定(例如,C 与 cpython),并使用该函数。

    【讨论】:

      【解决方案2】:

      使用as_stridedy,您仍然需要单独访问子数组,例如:

      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))
      

      【讨论】:

        猜你喜欢
        • 2023-03-08
        • 2014-05-17
        • 1970-01-01
        • 1970-01-01
        • 2021-11-02
        • 2011-11-20
        • 2016-01-28
        相关资源
        最近更新 更多