您可以组合使用reshape
and transpose
调用将图像切割成图块而不使用循环:
def split_image(image3, tile_size):
image_shape = tf.shape(image3)
tile_rows = tf.reshape(image3, [image_shape[0], -1, tile_size[1], image_shape[2]])
serial_tiles = tf.transpose(tile_rows, [1, 0, 2, 3])
return tf.reshape(serial_tiles, [-1, tile_size[1], tile_size[0], image_shape[2]])
where image3
是一个 3 维张量(例如图像),并且tile_size
是一对值[H, W]
指定图块的大小。输出是一个形状为的张量[B, H, W, C]
。在你的情况下,调用将是:
tiles = split_image(image, [28, 28])
得到形状为的张量[B, 28, 28, 1]
。您还可以通过反向执行以下操作从图块重新组合原始图像:
def unsplit_image(tiles4, image_shape):
tile_width = tf.shape(tiles4)[1]
serialized_tiles = tf.reshape(tiles4, [-1, image_shape[0], tile_width, image_shape[2]])
rowwise_tiles = tf.transpose(serialized_tiles, [1, 0, 2, 3])
return tf.reshape(rowwise_tiles, [image_shape[0], image_shape[1], image_shape[2]])
Where tiles4
是形状的 4D 张量[B, H, W, C]
, and image_shape
是原始图像的形状。在您的情况下,调用可能是:
image = unsplit_image(tiles, tf.shape(image))
请注意,这仅在图像大小可被图块大小整除时才有效。如果不是这种情况,您需要将图像填充到最接近的图块大小的倍数:
def pad_image_to_tile_multiple(image3, tile_size, padding="CONSTANT"):
imagesize = tf.shape(image3)[0:2]
padding_ = tf.to_int32(tf.ceil(imagesize / tile_size)) * tile_size - imagesize
return tf.pad(image3, [[0, padding_[0]], [0, padding_[1]], [0, 0]], padding)
您可以这样称呼:
image = pad_image_to_tile_multiple(image, [28,28])
然后在从图块中重新组装图像后,通过拼接去除 paddig:
image = image[0:original_size[0], 0:original_size[1], :]