Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TensorFlow Resize image tensor to dynamic shape

I am trying to read some image input for an image classification problem with TensorFlow.

Of course, I am doing this with tf.image.decode_jpeg(...). My images have variable size and hence I am not able to specify a fixed shape for the image tensor.

But I need to scale the images depending on their actual size. Specifically, I want to scale the shorter side to a fixed value and the longer side in a way that the aspect ratio is preserved.

I can get the actual shape of a certain image by shape = tf.shape(image). I am also able to do the computation for the new longer edge like

shape = tf.shape(image)
height = shape[0]
width = shape[1]
new_shorter_edge = 400
if height <= width:
    new_height = new_shorter_edge
    new_width = ((width / height) * new_shorter_edge)
else:
    new_width = new_shorter_edge
    new_height = ((height / width) * new_shorter_edge)

My problem now is that I cannot pass new_height and new_width to tf.image.resize_images(...) because one of them is a tensor and resize_images expects integers as height and width inputs.

Is there a way to "pull out" the integer of the tensor or is there any other way to do my task with TensorFlow?

Thanks in advance.


Edit

Since I also had some other issues with tf.image.resize_images, here's the code that worked for me:

shape = tf.shape(image)
height = shape[0]
width = shape[1]
new_shorter_edge = tf.constant(400, dtype=tf.int32)

height_smaller_than_width = tf.less_equal(height, width)
new_height_and_width = tf.cond(
    height_smaller_than_width,
    lambda: (new_shorter_edge, _compute_longer_edge(height, width, new_shorter_edge)),
    lambda: (_compute_longer_edge(width, height, new_shorter_edge), new_shorter_edge)
)

image = tf.expand_dims(image, 0)
image = tf.image.resize_bilinear(image, tf.pack(new_height_and_width))
image = tf.squeeze(image, [0])
like image 950
mackcmillion Avatar asked Feb 04 '16 18:02

mackcmillion


People also ask

How do I resize an image in tensorflow dataset?

This is achieved by using the "tf. image. resize()" function available in the tensorflow. It will resize the images to the size using the specified method.

How do you flatten a tensor in tensorflow?

To flatten the tensor, we're going to use the TensorFlow reshape operation. So tf. reshape, we pass in our tensor currently represented by tf_initial_tensor_constant, and then the shape that we're going to give it is a -1 inside of a Python list.


1 Answers

The way to do this is to use the (currently experimental, but available in the next release) tf.cond()* operator. This operator is able to test a value computed at runtime, and execute one of two branches based on that value.

shape = tf.shape(image)
height = shape[0]
width = shape[1]
new_shorter_edge = 400
height_smaller_than_width = tf.less_equal(height, width)

new_shorter_edge = tf.constant(400)
new_height, new_width = tf.cond(
    height_smaller_than_width,
    lambda: new_shorter_edge, (width / height) * new_shorter_edge,
    lambda: new_shorter_edge, (height / width) * new_shorter_edge)

Now you have Tensor values for new_height and new_width that will take the appropriate value at runtime.


*  To access the operator in the current released version, you'll need to import the following:

from tensorflow.python.ops import control_flow_ops

...and then use control_flow_ops.cond() instead of tf.cond().

like image 104
mrry Avatar answered Nov 12 '22 15:11

mrry