如何有效地提取numpy中的子数组?

时间:2015-05-19 05:49:33

标签: python arrays numpy optimization

我有一个3D numpy数组给出的图像(宽度,高度和颜色作为尺寸)。现在我想提取给定形状的所有可能的子图像。例如,原始图像的宽度和高度分别为300和200像素,并且我想分别提取宽度和高度分别等于10和20像素的所有子图像。此外,我想将每个子图像作为一维数组(为此我需要指定一个特定的像素排序)。

我通过以下方式解决问题:

for col0 in range(w_max - max_shift):
    x3s_new = [x + col0 for x in x3s]
    for row0 in range(h_max - max_shift):

        vec_1 = []
        for col_shift, row_shift in px_inds:
            col = col0 + col_shift
            row = row0 + row_shift
            vec_1 += [ia[row, col, 0], ia[row, col, 1], ia[row, col, 2]]

        y3s_new = [y + row0 for y in y3s]
        vec_2 = list(ia[y3s_new, x3s_new, z3s])

在上面的代码中,我在代表图像的“矩阵”的列和行上做了一个循环。然后每个像素(由其列和行给出)我将其视为子图像的左上角并提取子图像。

vec_1vec_2是以1D数组(列表)形式给出的所需子图像。它们完全相同,我只想测试哪种方式更快。令人惊讶的是,生成vec_2vec_1需要更多时间。但是,根据this answer我的问题,预计会更快。那么,为什么它不会更快?

最后,我还想知道是否有更快的替代方法来循环遍历图像矩阵的所有列和行。

总结一下,我的问题是:如何以更快的方式实现我的需求?目前我需要大约5分钟来“处理”一张图片,这对我来说是不可接受的。

1 个答案:

答案 0 :(得分:3)

你应该使用Numpy切片。

给定一个3D numpy数组# This handles cross-origin resource sharing. # See: https://github.com/cyu/rack-cors config.middleware.insert_before 0, "Rack::Cors" do allow do # In development, we don't care about the origin. origins '*' # Reminder: On the following line, the 'methods' refer to the 'Access- # Control-Request-Method', not the normal Request Method. resource '*', :headers => :any, :methods => [:get, :post, :options, :delete, :put, :patch], credentials: true end end ,你可以选择它的一个子数组,例如,

M

或者,明确定义切片,

M_selection = M[i_min:i_max, j_min:j_max, k_min:k_max]

其中sl_i = slice(i_min, i_max) sl_j = slice(j_min, j_max) sl_k = slice(k_min, k_max) M_selection = M[sl_i, sl_j, sl_k] 等是子数组的边界。

有关更多详细信息,请参阅高级Numpy索引的documentation