我想将我的图像分成更小的窗口,这些窗口将被发送到神经网络进行训练(例如,用于人脸检测器训练)。我在Tensorflow中找到了tf.extract_image_patches
方法,这似乎正是我所需要的。这个问题解释了它的作用。
那里的示例显示了(1x10x10x1)
的输入(按顺序从1
到100
的数字),给定ksize
是(1, 3, 3, 1)
(和strides
(1, 5, 5, 1)
)。输出是这样的:
[[[[ 1 2 3 11 12 13 21 22 23]
[ 6 7 8 16 17 18 26 27 28]]
[[51 52 53 61 62 63 71 72 73]
[56 57 58 66 67 68 76 77 78]]]]
但是我希望这样的窗口(形状(Nx3x3x1)
,因此它是N
大小3x3
的补丁/窗口):
[[[1, 2, 3]
[11, 12, 13]
[21, 22, 23]]
...
那么,为什么所有的补丁值都存储在一维中呢?这是否意味着此方法不适用于我上面描述的目的,并且我不能使用它来准备训练批次?我还找到了另一种提取补丁的方法,sklearn.feature_extraction.image.extract_patches_2d
这种方法确实达到了我的期望。那么我应该理解为这两种方法不做同样的事情吗?
正确,这些函数返回不同的张量(多维数组)。
首先,tf.extract_image_patches
文档如下:
返回:
一个张量。与图像具有相同的类型。形状
[batch, out_rows, out_cols, ksize_rows * ksize_cols * depth]
包含图像的 4-D 张量 大小ksize_rows x ksize_cols x depth
在 "深度"维度。注意out_rows
和out_cols
是 输出补丁。
基本上,这表示[1, 2, 3]
、[11, 12, 13]
、[21, 22, 23]
窗口在"深度"维度上被展平或矢量化。out_rows
和out_cols
是根据strides
参数计算的,在本例中为strides=[1, 5, 5, 1]
,而padding
为'VALID'
。因此,输出形状为(1, 2, 2, 9)
。
换句话说:
strides
更改空间维度ksizes
更改深度
请注意,输出张量确实包含所有单独的窗口,因此您可以通过选择访问它们。
另一方面,sklearn.feature_extraction.image.extract_patches_2d
:
返回:
patches
:数组、形状 =(n_patches, patch_height, patch_width)
或(n_patches, patch_height, patch_width, n_channels)
从映像中提取的修补程序集合,其中n_patches
max_patches
或可以 提取。
这正是您所描述的:每个窗口都采用整个空间维度patch_height, patch_width
。这里,结果形状取决于patch_size
,不支持步幅和填充,第一个维度计算为补丁总数。