在张量流中调整具有动态形状的图像的大小 [英] Resizing images with dynamic shape in tensorflow

查看:76
本文介绍了在张量流中调整具有动态形状的图像的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

我的问题是 tf.unstack 无法处理可变大小的输入.如果我运行代码,则会得到"ValueError:无法从形状(?,?,?,1)推断num""

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)"

我已经考虑过改用 tf.split ,但是它需要一个整数输入.有人知道解决方法吗?

I have considered using tf.split instead, however it expects an integer input. Does anybody know a workaround?

这里是一个例子:

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 可以同时调整多个图像的大小,但是不允许您选择批处理轴.但是,您可以操纵张量的尺寸以首先放置所需的轴,以便将其用作批处理尺寸,然后在调整大小后再放回该轴:

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

在您的示例中:

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)

这篇关于在张量流中调整具有动态形状的图像的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆