I have an image
of shape (466,394,1)
which I want to split into 7x7 patches.
image = tf.placeholder(dtype=tf.float32, shape=[1, 466, 394, 1])
Using
image_patches = tf.extract_image_patches(image, [1, 7, 7, 1], [1, 7, 7, 1], [1, 1, 1, 1], 'VALID')
# shape (1, 66, 56, 49)
image_patches_reshaped = tf.reshape(image_patches, [-1, 7, 7, 1])
# shape (3696, 7, 7, 1)
unfortunately does not work in practice as image_patches_reshaped
mixes up the pixel order (if you view images_patches_reshaped
you will only see noise).
So my new approach was to use tf.split
:
image_hsplits = tf.split(1, 4, image_resized)
# [<tf.Tensor 'split_255:0' shape=(462, 7, 1) dtype=float32>,...]
image_patches = []
for split in image_hsplits:
image_patches.extend(tf.split(0, 66, split))
image_patches
# [<tf.Tensor 'split_317:0' shape=(7, 7, 1) dtype=float32>, ...]
this indeed preserves the image pixel order unfortunately it creates a lot of OPs which is not very good.
How do I split an image into smaller patches with less OPs?
Update1:
I ported the answer of this question for numpy to tensorflow:
def image_to_patches(image, image_height, image_width, patch_height, patch_width):
height = math.ceil(image_height/patch_height)*patch_height
width = math.ceil(image_width/patch_width)*patch_width
image_resized = tf.squeeze(tf.image.resize_image_with_crop_or_pad(image, height, width))
image_reshaped = tf.reshape(image_resized, [height // patch_height, patch_height, -1, patch_width])
image_transposed = tf.transpose(image_reshaped, [0, 2, 1, 3])
return tf.reshape(image_transposed, [-1, patch_height, patch_width, 1])
but I think there is still room for improvement.
Update2:
This will convert patches back to the original image.
def patches_to_image(patches, image_height, image_width, patch_height, patch_width):
height = math.ceil(image_height/patch_height)*patch_height
width = math.ceil(image_width/patch_width)*patch_width
image_reshaped = tf.reshape(tf.squeeze(patches), [height // patch_height, width // patch_width, patch_height, patch_width])
image_transposed = tf.transpose(image_reshaped, [0, 2, 1, 3])
image_resized = tf.reshape(image_transposed, [height, width, 1])
return tf.image.resize_image_with_crop_or_pad(image_resized, image_height, image_width)