【问题标题】:Memory efficient extraction of overlapping patches from matrix从矩阵中高效提取重叠补丁
【发布时间】:2017-06-10 12:18:23
【问题描述】:

短篇小说:

这是一个后续问题:Fast Way to slice image into overlapping patches and merge patches to image

我必须如何调整答案中提供的代码,使其不仅适用于大小为 x,y 的图像,其中像素由浮点数描述,但由大小为 3,3 的矩阵描述?

此外,如何调整代码以使其返回一个生成器,允许我迭代所有补丁,而无需将所有补丁保存在内存中?

长篇大论:

给定一个形状为 (x,y) 的图像,其中每个像素由 (3,3) 矩阵描述。这可以描述为形状为 (x,y,3,3) 的矩阵。 进一步给定一个目标补丁大小,例如(11,11),我想从图像(x,y)中提取所有重叠的补丁。

请注意,我不想从矩阵 x,y,3,3 中获取所有补丁,而是从每个像素都是矩阵的图像 x,y 中获取所有补丁。

我希望将这些补丁用于补丁分类算法,有效地迭代所有补丁,提取特征并学习分类器。然而,考虑到巨大的图像和大的补丁大小,没有办法在不损害内存限制的情况下执行此操作。

可能的解决方案:

因此问题是:如何调整这段代码以适应新的输入数据?

def patchify(img, patch_shape):
    img = np.ascontiguousarray(img)  # won't make a copy if not needed
    X, Y = img.shape
    x, y = patch_shape
    shape = ((X-x+1), (Y-y+1), x, y) # number of patches, patch_shape
    # The right strides can be thought by:
    # 1) Thinking of `img` as a chunk of memory in C order
    # 2) Asking how many items through that chunk of memory are needed when indices
    #    i,j,k,l are incremented by one
    strides = img.itemsize*np.array([Y, 1, Y, 1])
    return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides)

【问题讨论】:

    标签: python numpy image-processing matrix slice


    【解决方案1】:

    虽然您链接的答案并不正确,但我认为最好不要对数组的步幅做出假设,而只是重用它已有的步幅。它的另一个好处是永远不需要原始数组的副本,即使它不是连续的。对于您的扩展图像形状,您会这样做:

    def patchify(img, patch_shape):
        X, Y, a, b = img.shape
        x, y = patch_shape
        shape = (X - x + 1, Y - y + 1, x, y, a, b)
        X_str, Y_str, a_str, b_str = img.strides
        strides = (X_str, Y_str, X_str, Y_str, a_str, b_str)
        return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides)
    

    很容易被带走并想要编写一些不需要专门化特定数组维度的更通用的函数。如果你觉得有必要去那里,你可以在this gist找到一些灵感。

    【讨论】:

    • 如果我理解正确的话,这个函数返回一个视图并且不分配内存。然而,当开始对该阵列的操作时,可能会创建一个副本。我该如何预防?可能会返回一个生成器?
    • 如果你迭代补丁,例如X, Y = img.shape[:2]; for x in range(X): for y in range(Y): patch = img[x, y]; ...,那么无论你对patch 做什么,最多只会复制那个特定的补丁。它会减慢速度,但不会占用大量内存,如果一次复制整个修补视图会发生这种情况。除此之外,是否可以避免复制在很大程度上取决于您要对补丁执行的操作。
    • @NikolasRieble 所以,最好的用例是在这个 6D 数组上使用某种缩减,但一般来说取决于用例本身。
    • @Divakar 所有补丁的列表将包含比原始图像更多的元素。如何使用减少来做到这一点?
    • @NikolasRieble 我并没有说使用归约来创建这个 6D 数组,我的意思是如果你在这个 6D 数组上使用一些归约代码就可以证明创建这么大的数组是合理的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 2012-07-17
    • 2018-10-06
    相关资源
    最近更新 更多