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

Resizing images with dynamic shape in tensorflow

我想调整具有动态形状的 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)

tf.image.resize_images可以同时调整多张图片的大小,但是不能选择batch axis。但是,你可以操纵张量的维度,把你想要的轴放在最前面,所以它被用作批量维度,然后在调整大小后放回去:

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)