代码之家  ›  专栏  ›  技术社区  ›  kmario23 Mazdak

从4D阵列裁剪图像的不同部分以增强数据

  •  1
  • kmario23 Mazdak  · 技术社区  · 8 年前

    我有以下成批RGB图像阵列(4D阵列):

    In [55]: img_arr = np.random.randint(0, 255, (10000, 32, 32, 3))
    

    现在,我只想裁剪某些维度,比如( 12x12 ),从左上角穿过所有 3 通道,最好沿着批次尺寸(即。 axis 0 )同样,一气呵成。我的想法是制作一个网格并将其切片。因此,我构建了这个网格:

    In [56]: grid = np.c_[np.arange(12)]+ np.r_[np.arange(12)]
    
    In [57]: grid.shape
    Out[57]: (12, 12)
    

    但是,当我对数组进行切片时,会得到一些意想不到的结果:

    In [58]: img_arr[:, grid, :].shape
    Out[58]: (10000, 12, 12, 32, 3)
    

    我预料到了,需要的结果是形状 (10000, 12, 12, 3) 但我不知道 32 来自。

    这只是一个例子。理想情况下,我想在图像viz上的10个不同位置进行裁剪。左上、右上、左下、右下等。,

    但是,通过首先进行左上角裁剪,其余部分应该是直观的。

    此外,正如您所看到的,我需要在一个4D阵列中沿批次维度存储超过100K的图像,所以如果有一个 看法 在进行这种随机裁剪时,因为这样会节省内存。

    1 回复  |  直到 8 年前
        1
  •  3
  •   willeM_ Van Onsem    8 年前

    我们可以使用 slicing 为此:我们可以指定第二和第三维度的范围,如:

    sub_img = img_arr[:, :12, :12 , :]

    然后 sub_img.shape == (10000, 12, 12, 3) . 因此,我们在此指定 0 到 12 (但我们不需要明确说明 0 ). 我们这样做是为了第二和第三维度。它也是一种声明性语言:我们构造一个 sub_img 其中第一个索引占全部( : ),第二项至第十二项( :12 )等。

    注意,我们不需要指定拖尾 : s、 我们还可以写:

    sub_img = img_arr[:, :12, :12]  # no last ":"

    切片为视图

    请注意,我们在这里 构造视图 ,我们有 不 复制数组,我们只构建一个视图。所以如果我们在 img_arr 在视图范围内,我们可以在 sub\u img ,反之亦然。如果需要副本,可以通过 array 建造商:

    sub_img = np.array(img_arr[:, :12, :12])  # making a copy, instead of a view

    然而,使用视图可能是有益的,因为它几乎不使用内存来存储视图(这里大约144字节,而副本大约需要34 MB),而且视图的构造几乎是即时的(通常它会随着 尺寸数量 ),而副本将随图元的数量而缩放。

    任意数量的维度使用 slice 物体

    例如,如果维度的数量是任意的,我们还可以传递 片 物体。

    例如,第一个表达式等效于:

    # equivalent to the first code fragment
    indices = (slice(None), slice(12), slice(12))
    sub_img = img_arr[indices]
    

    因此,如果维数是任意的,我们可以首先构造这样的元组。例如,除了第一个和最后一个维度之外,将所有维度切片为12的元组是:

    # generalized with arbitrary number of dimensions
    indices = (slice(None), *(slice(12) for _ in range(img_arr.ndim - 2)))
    sub_img = img_arr[indices]