问题描述
我有一个图像,我想使用垂直和水平步幅(如滑动窗口)将其拆分为多个图像,并且生成的图像都具有相同的分辨率。我怎样才能在 Python 中有效地做到这一点?我做了这么多:
from PIL import Image
def sliding_window(image,stride,imgSize):
width,height = image.size
img = []
for y in range(0,height-imgSize,stride):
for x in range(0,width-imgSize,stride):
# Setting the points for cropped image
left = x
top = y
right = x + imgSize
bottom = y + imgSize
im1 = image.crop((left,top,right,bottom))
img.append(im1)
return img
file = "/home/xxxxxx/yyyyyy.png"
im = Image.open(file)
img = sliding_window(im,1,838) # Strides of 1 takes too much time
但是这段代码需要太多的内存并且太耗时。请帮忙。
示例:
示例代码:img = sliding_window(im,200,300)
下图为800*800尺寸。
输出:
解决方法
正如您正确推测的那样,有一种方法可以在不复制原始数据的情况下查看原始数据的窗口。最简单的方法可能是使用相对较新的 sliding_window_view
函数:
from numpy.lib.stride_tricks import sliding_window_view
window = sliding_window_view(image,(838,838),axis=(0,1))
对于 2D 图像,您不需要显式 axis
,但它不会受到伤害,并且在 3D 情况下为您节省了一些麻烦。如果你想调整步幅,你可以只对结果进行子集化。例如,对于 (3,4)
的步幅:
window = window[::3,::4]
由于窗口轴必须(应该)以 C 顺序排在最后,因此 3D 图像会将通道移动到中间轴。要访问正确的形状,您可以使用类似 np.moveaxis
或 transpose
:
np.moveaxis(window[80,70],-1)
或
window[80,70].transpose(1,2,0).shape