调整张量流中的3D数据,如tf.image.resize_images

时间:2017-05-05 22:04:00

标签: 3d tensorflow resize gpu scale

我需要调整一些3D数据的大小,例如2d数据的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])

转过来:

Original

成:

resized

我认为最近的邻居不应该有阶梯效应(我有意删除了颜色)。

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

2 个答案:

答案 0 :(得分:4)

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

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将是3维张量或灰度或RGB; resized_along_width是最终调整大小的张量。这里我们要将三维图像的大小调整为(50,60,70)

的尺寸

答案 1 :(得分:3)

张量已经是4D,1D分配给' batch_size'和其他3D分配宽度,高度,深度。如果您希望处理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号尺寸,而重塑我可以更多,并留下下一个开发者必须弄清楚你为什么要重塑。

更新以包含更改的第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])

这怎么可行?让我们想象深度是图像帧的数量, n 是颜色深度(RGB可能是3)。重塑将一个接一个地堆叠颜色框架。毫无疑问,你的张量流在输入后立即有一个卷积层。卷积层将像您的单色帧一样轻松处理您的彩色帧堆栈(尽管具有更强的计算能力和参数)。

并添加了缩放

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

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

其中size是2D张量,如果[new_height,new_width],或者在你的情况下 [width * scale,height * scale]

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]