【问题标题】:Numpy - Generalize cropping over time dimensionNumpy - 泛化随时间维度的裁剪
【发布时间】:2020-07-31 09:53:13
【问题描述】:

我有一个裁剪方法,适用于 (N, M) 数组,我希望它适用于 (T, N, M) - 请参阅以下我尝试过但不起作用的方法(提示 - 无法获取 np.vectorize工作)

这是方法

def crop(image: np.ndarray) -> np.ndarray:
    """
    Crop a single image
    """
    image_cropped = image[~np.all(image == 0, axis=1)]
    image_cropped = image_cropped[:, ~np.all(image_cropped == 0, axis=0)]

    return image_cropped

我尝试了什么

  • np.vectorize(crop)(sequence_of_images) 导致此错误:numpy.AxisError: axis 1 is out of bounds for array of dimension 0
  • np.apply_along_axis(crop, 0, sequence_of_images) 导致此错误:numpy.AxisError: axis 1 is out of bounds for array of dimension 1

如何在不使用循环的情况下使其工作? (可以假设每张图片在时间维度上,裁剪后的大小都是一样的,虽然裁剪后的mask不一样)

【问题讨论】:

    标签: python performance numpy vectorization


    【解决方案1】:

    对于2D image,可以使用行和列的外部掩码复制链式索引。

    因此,

    m1 = ~np.all(image == 0, axis=1)
    m2 =  ~np.all(image_cropped == 0, axis=0)
    
    image_cropped = image[m1, :]
    image_cropped = image_cropped[:, m2]
    

    将等同于:

    image_cropped = image_cropped[outer_mask(m1, m2)]
    

    我们会将这些知识转移到3D 案例中。此外,可以使用 keepdims=True 减少 ALL 并最终使用处理外部操作的元素乘法,轻松地从两个 mak 构建 3D 的外部掩码。

    因此,我们将得到:

    mask_0s = image_nd == 0
    mask1 = ~np.all(mask_0s, axis=2, keepdims=True)
    mask2 = ~np.all(mask_0s, axis=1, keepdims=True)
    out = image_nd[mask1 & mask2]
    

    终于有了3D数组输出:

    out = out.reshape(image_nd.shape[0],-1,mask2[0].sum())
    

    【讨论】:

    • 漂亮!请您详细说明每个步骤,以便我理解这里的逻辑吗?
    • @bluesummers 添加了一些解释。
    猜你喜欢
    • 2018-12-10
    • 2018-11-02
    • 1970-01-01
    • 2018-08-05
    • 2012-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    相关资源
    最近更新 更多