Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I need to resize some 3D data, like in the tf.image.resize_images method for 2d data.

I was thinking I could try and run tf.image.resize_images on it in a loop and swap axes, but I thought there must be an easier way. Simple nearest neighbour should be fine.

Any ideas? It's not ideal, but I could settle for the case where the data is just 0 or 1 and use something like:

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

But I'm not sure how to get boolMap. Would use of tf.while_loop to go over all the values dramatically decrease performance? i feel like it would on GPU unless the have some kind of automatic loop parallelisation.

The data is a tensor of size [batch_size, width, height, depth, 1]

Thanks in advance.

N.B The output dimensions should be:

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

I have come up with this:

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

Which turns:

Original

into:

resized

I believe nearest neighbour shouldn't have the stair-casing effect (I intentionally removed the colour).

Hars answer works correctly, however I would like to know whats wrong with mine if anyone can crack it.

like image 792
Greg Cawthorne Avatar asked May 05 '17 22:05

Greg Cawthorne


1 Answers

My approach to this would be to resize the image along two axis, in the code I paste below, I resample along depth and then width

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)

Where x will be the 3-d tensor either grayscale or RGB; resized_along_width is the final resized tensor. Here we want to resize the 3-d image to dimensions of (50,60,70)

like image 77
Savvy Avatar answered Nov 15 '22 09:11

Savvy