在 tensorflow 中调整 3D 数据的大小,如 tf.image.resize_images

Resize 3D data in tensorflow like tf.image.resize_images

我需要调整一些 3D 数据的大小,例如在 tf.image.resize_images 二维数据的方法中。

我想我可以尝试在循环中 运行 tf.image.resize_images 并交换轴,但我认为必须有更简单的方法。简单最近邻应该没问题。

有什么想法吗?这并不理想,但我可以满足于数据仅为 0 或 1 的情况,并使用类似:

tf.where(boolMap, tf.fill(data_im*2, 0), tf.fill(data_im*2), 1)

但我不确定如何获得 boolMap。使用 tf.while_loop 遍历所有值会显着降低性能吗?我觉得它会在 GPU 上运行,除非有某种自动循环并行化。

数据是大小为 [batch_size, width, height, depth, 1]

的张量

提前致谢。

N.B 输出维度应该是:

[batch_size, width*scale, height*scale, depth*scale, 1]

我想到了这个:

def resize3D(self, input_layer, width_factor, height_factor, depth_factor):
    shape = input_layer.shape
    print(shape)
    rsz1 = tf.image.resize_images(tf.reshape(input_layer, [shape[0], shape[1], shape[2], shape[3]*shape[4]]), [shape[1]*width_factor, shape[2]*height_factor])
    rsz2 = tf.image.resize_images(tf.reshape(tf.transpose(tf.reshape(rsz1, [shape[0], shape[1]*width_factor, shape[2]*height_factor, shape[3], shape[4]]), [0, 3, 2, 1, 4]), [shape[0], shape[3], shape[2]*height_factor, shape[1]*width_factor*shape[4]]), [shape[3]*depth_factor, shape[2]*height_factor])

    return tf.transpose(tf.reshape(rsz2, [shape[0], shape[3]*depth_factor, shape[2]*height_factor, shape[1]*width_factor, shape[4]]), [0, 3, 2, 1, 4])

轮到:

进入:

我认为最近的邻居不应该有楼梯效果(我故意去掉了颜色)。

Hars 回答正确,但是如果有人能破解它,我想知道我的问题是什么。

一个张量已经是4维的,1维分配给'batch_size',另一个3维分配给宽度、高度、深度。如果您正在寻找处理 3D 图像并在此配置中批量处理它们

[batch_size, width, height, depth, 1]

然后使用压缩函数移除不必要的最终维度,如下所示:

tf.squeeze(yourData, [4])

这将输出张量或形状

[batch_size, width, height, depth]

tensorflow 将优雅地使用它。

加法

如果您手边有尺寸并且想使用 tensorflow 的重塑功能,您可能会喜欢这样:

reshapedData = tf.reshape(yourData, [batch_size, width, height, depth])

就我个人而言,我会使用 squeeze 来向下一个程序员声明您的代码仅打算摆脱大小为 1 的维度,而 reshape 可以让我做得更多并且会让下一个开发者不得不尝试弄清楚你为什么要重塑。

更新以包含不断变化的第 4 个维度

您想有时使用维度 [batch_size, width, height, depth, 1] 有时使用 [batch_size, width, height, depth, n]

没问题。这是相同的解决方案,但现在你不能使用 squeeze 而是只剩下 reshape 像这样:

reshapedData = tf.reshape(yourData, [batch_size, width, height, depth*n])

这怎么行?假设 depth 是图像帧数,n 是颜色深度(对于 RGB 可能是 3)。重塑会将彩色帧一个接一个地堆叠起来。您的张量流无疑在输入后立即有一个卷积层。卷积层将像处理单色帧一样轻松地处理彩色帧堆栈(尽管需要更多的计算能力和参数)。

和添加缩放

好的,这是缩放图像的方法,调整大小后使用tf.image.resize_images

reshapedData = tf.image.resize_images( tf.reshape(yourData, [batch_size, width, height, depth*n]) , new_size )

如果 [new_height, new_width ],或者您的情况 [ width * scale , height * scale ][,其中 size 是二维张量=23=]

new_size = tf.constant( [ width * scale , height * scale ] )

再回到原来的样子

如果在调整图像大小之后您希望它再次成为形状:[batch_size, width, height, depth, n] 那么简单地使用此代码

tf.reshape(yourData, [batch_size, width*scale, height*scale, depth,n])

最后添加地址缩放深度也

这是我的解决方案:

我们想要重塑这个矩阵,并像这样在 numpy 中扩展 3d 矩阵一样扩展它

a = np.array([[1, 2, 3, 4, 5, 6, 7, 8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27],[1, 2,3, 4, 5, 6, 7, 8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27]])
print a.reshape([2,3,3,3])
a.reshape([54,1]).dot(np.ones([1,8])).reshape([2,3,3,3,2,2,2]).transpose([0,1,6,2,5,3,4]).reshape([2,6,6,6])
print a

这是张量流代码

isolate = tf.transpose(yourdata,[0,4,1,2,3])  # [batch_size,n,width,height,depth]
flatten_it_all = tf.reshape([batch_size * n * width * height * depth , 1])  # flatten it

expanded_it = flatten_it_all * tf.ones( [1,8] )
prepare_for_transpose = tf.reshape( expanded_it , [batch_size*n,width,height,depth,2,2,2] )

transpose_to_align_neighbors = tf.transpose( prepare_for_transpose, [0,1,6,2,5,3,4])
expand_it_all = tf.reshape( transpose_to_align_neighbors , [batch_size,n,width*2,height*2,depth*2] )

#### - removing this section because the requirements changed
# do a conv layer here to 'blend' neighbor values like:
# averager = tf.ones([2,2,2,1,1]) * 1. / 8.
# tf.nn.conf3d( expand_it_all , averager , padding="SAME")
# for n = 1.  for n = 3, I'll leave it to you.

# then finally reorder and you are done
reorder_dimensions = tf.transpose(expand_it_all,[0,2,3,4,1])  # [batch_size,width*2,height*2,depth*2,n]

我的方法是沿两个轴调整图像大小,在我粘贴在下面的代码中,我沿深度和宽度重新采样

def resize_by_axis(image, dim_1, dim_2, ax, is_grayscale):

    resized_list = []


    if is_grayscale:
        unstack_img_depth_list = [tf.expand_dims(x,2) for x in tf.unstack(image, axis = ax)]
        for i in unstack_img_depth_list:
            resized_list.append(tf.image.resize_images(i, [dim_1, dim_2],method=0))
        stack_img = tf.squeeze(tf.stack(resized_list, axis=ax))
        print(stack_img.get_shape())

    else:
        unstack_img_depth_list = tf.unstack(image, axis = ax)
        for i in unstack_img_depth_list:
            resized_list.append(tf.image.resize_images(i, [dim_1, dim_2],method=0))
        stack_img = tf.stack(resized_list, axis=ax)

    return stack_img

resized_along_depth = resize_by_axis(x,50,60,2, True)
resized_along_width = resize_by_axis(resized_along_depth,50,70,1,True)

其中 x 将是灰度或 RGB 的 3 维张量; resized_along_width 是最终调整大小的张量。这里我们要将 3-d 图像的尺寸调整为 (50,60,70)