短篇故事:
这是一个后续问题:将图像切成重叠补丁并将补丁合并到图像的快速方法]
我如何适应答案中提供的代码,以使其不仅适用于大小为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)
虽然您链接的答案是不正确的,但我认为最好不要对数组的跨度进行假设,而只是重用已有的跨度。它具有额外的优势,即使它不是连续的,也无需复制原始数组。对于扩展的图像形状,您可以执行以下操作:
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)
它很容易被带走,并且想要编写一些更通用的函数,这些函数不需要针对特定数组维数进行专门化处理。如果您觉得需要去那里,可以在这个要点中找到一些启发。