问题
I want to resize 3D images with a dynamic shape, for instance go from shape (64,64,64,1) to (128,128,128,1). The idea is to unstack the image along one axis, then use tf.image.resize_images
and stack them again.
My issue is that tf.unstack
can not handle variable sized inputs. If I run my code I obtain "ValueError: Cannot infer num from shape (?, ?, ?, 1)"
I have considered using tf.split
instead, however it expects an integer input. Does anybody know a workaround?
Here is an example:
import tensorflow as tf
import numpy as np
def resize_by_axis(image, dim_1, dim_2, ax):
resized_list = []
# Unstack along axis to obtain 2D images
unstack_img_depth_list = tf.unstack(image, axis = ax)
# Resize 2D images
for i in unstack_img_depth_list:
resized_list.append(tf.image.resize_images(i, [dim_1, dim_2], method=1, align_corners=True))
# Stack it to 3D
stack_img = tf.stack(resized_list, axis=ax)
return stack_img
#X = tf.placeholder(tf.float32, shape=[64,64,64,1])
X = tf.placeholder(tf.float32, shape=[None,None,None,1])
# Get new shape
shape = tf.cast(tf.shape(X), dtype=tf.float32) * tf.constant(2, dtype=tf.float32)
x_new = tf.cast(shape[0], dtype=tf.int32)
y_new = tf.cast(shape[1], dtype=tf.int32)
z_new = tf.cast(shape[2], dtype=tf.int32)
# Reshape
X_reshaped_along_xy = resize_by_axis(X, dim_1=x_new, dim_2=y_new, ax=2)
X_reshaped_along_xyz= resize_by_axis(X_reshaped_along_xy, dim_1=x_new, dim_2=z_new, ax=1)
init = tf.global_variables_initializer()
# Run
with tf.Session() as sess:
sess.run(init)
result = X_reshaped_along_xyz.eval(feed_dict={X : np.zeros((64,64,64,1))})
print(result.shape)
回答1:
tf.image.resize_images can resize multiple images at the same time, but it does not allow you to pick the batch axis. However, you can manipulate the dimensions of the tensor to put the axis that you want first, so it is used as batch dimension, and then put it back after resizing:
import tensorflow as tf
def resize_by_axis(image, dim_1, dim_2, ax):
# Make permutation of dimensions to put ax first
dims = tf.range(tf.rank(image))
perm1 = tf.concat([[ax], dims[:ax], dims[ax + 1:]], axis=0)
# Transpose to put ax dimension first
image_tr = tf.transpose(image, perm1)
# Resize
resized_tr = tf.image.resize_images(image_tr, [dim_1, dim_2],
method=1, align_corners=True)
# Make permutation of dimensions to put ax in its place
perm2 = tf.concat([dims[:ax] + 1, [0], dims[ax + 1:]], axis=0)
# Transpose to put ax in its place
resized = tf.transpose(resized_tr, perm2)
return resized
In your example:
import tensorflow as tf
import numpy as np
X = tf.placeholder(tf.float32, shape=[None, None, None, 1])
# Get new shape
shape = tf.cast(tf.shape(X), dtype=tf.float32) * tf.constant(2, dtype=tf.float32)
x_new = tf.cast(shape[0], dtype=tf.int32)
y_new = tf.cast(shape[1], dtype=tf.int32)
z_new = tf.cast(shape[2], dtype=tf.int32)
# Reshape
X_reshaped_along_xy = resize_by_axis(X, dim_1=x_new, dim_2=y_new, ax=2)
X_reshaped_along_xyz = resize_by_axis(X_reshaped_along_xy, dim_1=x_new, dim_2=z_new, ax=1)
init = tf.global_variables_initializer()
# Run
with tf.Session() as sess:
sess.run(init)
result = X_reshaped_along_xyz.eval(feed_dict={X : np.zeros((64, 64, 64, 1))})
print(result.shape)
# (128, 128, 128, 1)
来源:https://stackoverflow.com/questions/55814061/resizing-images-with-dynamic-shape-in-tensorflow