在张量流中调整具有动态形状的图像的大小

时间:2019-04-23 14:58:42

标签: python tensorflow image-resizing

我想用动态形状调整3D图像的大小,例如从形状(64,64,64,1)变为(128,128,128,1)。想法是沿一个轴解开图像,然后使用tf.image.resize_images并再次堆叠它们。

我的问题是tf.unstack无法处理大小可变的输入。如果运行代码,我将获得"ValueError: Cannot infer num from shape (?, ?, ?, 1)"

我曾考虑使用tf.split来代替,但是它期望输入整数。有人知道解决方法吗?

这里是一个例子:

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 个答案:

答案 0 :(得分:1)

tf.image.resize_images可以同时调整多张图像的大小,但不允许您选择批处理轴。但是,您可以操纵张量的尺寸以首先放置所需的轴,以便将其用作批处理尺寸,然后在调整大小后放回原位:

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

在您的示例中:

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)