sklearn patchextractor ...缺少元素

sklearn patchextractor...missing elements

我正在尝试使用 python 将各种图像内核应用于图像;我正在使用 sklearn.feature_extraction 创建补丁,但是,当我这样做时,似乎丢失了一些数据,这会在我返回重建图像时导致问题。我是做错了什么,还是在抓取边界情况的补丁时必须在图像周围添加缓冲区?

from PIL import Image
sklearn.feature_extraction import image
import numpy as np

img = Image.open('a.png')
arr = np.array(img)
patches = imagePatchExtractor(patch_size=(3,3)).fit(arr).transform(arr)

>>>arr.shape
(1080, 1080, 3)
>>>patches.shape
(1164240, 3, 3)
>>>1164240/1080
1078.0

这里有两点需要理解:

  1. image.PatchExtractor 提取所有可能的补丁,每个维度的步幅为 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 是由于补丁碰到了图像边界(没有填充)。

  2. 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() 填充图像。请注意,默认情况下它会填充所有轴,因此我们需要手动指定填充量 per-axis:

# 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)