这里有两件事需要理解:
image.PatchExtractor
提取all possible patches,每个维度的步幅为1.例如,对于形状为(3, 3)
的面片,将得到arr[0:3, 0:3, 0]
,然后是arr[1:4, 1:4, 0]
,依此类推.因此,一般来说,对于(x, y)
的面片大小和(w, h)
的图像大小,每个通道将获得(w-x+1)*(h-y+1)
个面片.-x+1
和-y+1
是由于补丁击中了图像边界(没有填充).
PatchExtractor.transform()
期望第一个维度是n_samples
.所以,在你的例子中,形状应该是(1, 1080, 1080, 3)
.
综上所述,下面是一个带有一个通道的假较小图像的示例:
from sklearn.feature_extraction import image
import numpy as np
# Adding the n_samples dimension with reshape.
arr = np.arange(0, 6*6*1).reshape((1, 6, 6))
print(arr)
array([[[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]]])
# Get all possible patches.
patches = image.PatchExtractor(patch_size=(3, 3)).fit(arr).transform(arr)
print(np.shape(patches))
print(patches[0, :])
print(patches[1, :])
shape:
# (6-3+1) * (6-3+1) = 16
(16, 3, 3)
patches[0, :]:
array([[ 0., 1., 2.],
[ 6., 7., 8.],
[12., 13., 14.]])
patches[1, :]:
array([[ 1., 2., 3.],
[ 7., 8., 9.],
[13., 14., 15.]])
如你所见,结果与上面的解释相符.面片1相对于面片2向右移动一个像素.
因此,在您的情况下,对于形状为(1080, 1080, 3)
的图像:
# You also need this reshape to add the n_samples dimension.
arr = np.arange(0, 1080*1080*3).reshape((1, 1080, 1080, 3))
patches = image.PatchExtractor(patch_size=(3, 3)).fit(arr).transform(arr)
print(np.shape(patches))
# (1080-3+1)*(1080-3+1) = 1162084
(1162084, 3, 3, 3)
编辑-带填充的修补程序:
如果你想要每个像素有相同数量的补丁,你可以用np.pad()
块来填充图像.请注意,默认情况下,它会填充所有轴,因此我们需要手动指定每个轴的填充量:
# Padding amount for each axis. Here: amount should be patch_size-1.
# Here, the format is (pad_before, pad_after) for each dimension.
paddings = ((0, 0), (1, 1), (1, 1), (0, 0))
wrapped_arr = np.pad(arr, pad_width=paddings, mode='wrap')
wrapped_patches = image.PatchExtractor(patch_size=(3, 3)).fit(wrapped_arr).transform(wrapped_arr)
print(np.shape(wrapped_patches))
# 1080*1080 = 1166400
(1166400, 3, 3, 3)