我正在玩弄使用python将各种图像内核应用于图像;我正在使用sklearn.特征提取以创建面片,但是,当我这样做时,似乎缺少一些数据,这将在我回go 重建图像时造成问题.我是做错了什么,还是在抓取边界 case 的补丁时必须在图像周围添加缓冲区?

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提取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是由于补丁击中了图像边界(没有填充).

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

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

Python相关问答推荐

具有2D功能的Python十六进制图

如何修复使用turtle和tkinter制作的绘画应用程序的撤销功能

在matplotlib动画gif中更改配色方案

添加包含中具有任何值的其他列的计数的列

理解Python的二分库:澄清bisect_left的使用

如何将ctyles.POINTER(ctyles.c_float)转换为int?

为什么这个带有List输入的简单numba函数这么慢

如何在polars(pythonapi)中解构嵌套 struct ?

使用@ guardlasses. guardlass和注释的Python继承

为什么以这种方式调用pd.ExcelWriter会创建无效的文件格式或扩展名?

在极性中创建条件累积和

如何更改groupby作用域以找到满足掩码条件的第一个值?

如果初始groupby找不到满足掩码条件的第一行,我如何更改groupby列,以找到它?

手动设置seborn/matplotlib散点图连续变量图例中显示的值

Python避免mypy在相互引用中从另一个类重定义类时失败

将链中的矩阵乘法应用于多组值

用fft计算指数复和代替求和来模拟衍射?

Autocad使用pyautocad/comtypes将对象从一个图形复制到另一个图形

Polars表达式无法访问中间列创建表达式

Django.core.exceptions.SynchronousOnlyOperation您不能从异步上下文中调用它-请使用线程或SYNC_TO_ASYNC