使用 padding=wrap 快速 python 实现裁剪

Fast python implementation of cropping with padding=wrap

我有一个很长的 for 循环,我在不同位置以固定大小的平方裁剪图像 window 以获得 numpy 数组。
我使用的是 PIL 图片库中的 crop。然后我将它转换为 numpy 数组 np.asarray

from PIL import Image
import numpy as np
im=Image.open("image.png")
box=(left,top,left+width,top+width)
res=np.asarray(im.crop(box))

然而,唯一实现的填充(当你的裁剪中心小于边框的 width/2 时)恒定为 0,我希望它是 "wrap" 填充,就像在 numpy 中一样垫文档。

我的解决方案是做这样的事情。

array=np.asarray(Image.open("image.png"))
padded_array=np.pad(array,((width/2,width/2),(width/2,width/2),(0,0)),"wrap")
res=padded_array[top+width/2:top+width/2+width,left+width/2:left+width/2+width]

我想知道是否有更有效的方法。

您可以使用 numpy.take 包裹边缘,例如使用 3x3 裁剪 window:

a = numpy.arange(100).reshape((10,10))
a.take([8,9,10], mode="wrap", axis=1).take([9,10,11], mode="wrap", axis=0)

它也接受索引列表的列表,例如两次裁剪windows:

b = a.take([[8,9,10],[3,4,5]], mode="wrap", axis=1).take([[9,10,11],[9,10,11]], mode="wrap", axis=0)

然后您可以恢复裁剪后的内容 windows:

window1 = b[0,:,0::2].reshape(3,3)
>>> array([[98, 99, 90],
           [ 8,  9,  0],
           [18, 19, 10]])
window2 = b[1,:,1::2].reshape(3,3)
>>> array([[93, 94, 95],
           [ 3,  4,  5],
           [13, 14, 15]])

对于小 windows,这样做可能更有效,但对于更大的 windows,您可能希望在循环中一次指定一组索引。