2017-02-16 139 views
0

我想让输入图像(张量)在每批中随机地上/下或右/左移动。如何在Tensorflow中随机翻译或转换批量张量

例如,我有一批灰度图像,大小为[10, 48, 64, 1]

如果有一个形象,我知道我可以使用tf.pad和tf.slice(或其他内置功能)

但我想随机漂移适用于10个不同的图像与一个操作。

可能吗?或者我应该使用循环,如tf.scan?

回答

1

您是否在寻找tf.random_croptf.pad

那么,当使用tf.random_crop时,随机移位将应用于批次中的所有图像。批次内的换档是相同的,但对于不同的批次可能会有所不同。

如果你想在批处理中使用不同的移位,我认为最好使用队列/输入管道。有关更多信息,请参见https://www.tensorflow.org/programmers_guide/reading_data。 下面是我自己项目的一部分示例代码。 self.image_names是一个Python列表,其中包含所有训练图像的路径。在输入管道中,数据流就像一个流:你只需要处理一个图像,并且队列自动处理调度事情(一些线程读取数据,一些处理数据,一些将单个图像分成批次,其他人将数据馈送给GPU等,以保持整个管道忙碌)。在下面的代码中,imageslabels是队列。也就是说,当你处理这个变量时(就像我在self.data_augmentation中做的那样),你可以认为它只包含一个图像,但实际上队列处理它的每个项目(就像一个隐式循环),然后tf.train.shuffle_batch将洗牌数据在队列中并将它们分组分批。

def data_augmentation(images): 
    if FLAGS.random_flip_up_down: 
     images = tf.image.random_flip_up_down(images) 
    if FLAGS.random_brightness: 
     images = tf.image.random_brightness(images, max_delta=0.3) 
    if FLAGS.random_contrast: 
     images = tf.image.random_contrast(images, 0.8, 1.2) 
    return images 

def input_pipeline(self, batch_size, num_epochs=None, aug=False): 
    images_tensor = tf.convert_to_tensor(self.image_names, dtype=tf.string) 
    labels_tensor = tf.convert_to_tensor(self.labels, dtype=tf.int64) 
    input_queue = tf.train.slice_input_producer([images_tensor, labels_tensor], num_epochs=num_epochs) 

    labels = input_queue[1] 
    images_content = tf.read_file(input_queue[0]) 
    images = tf.image.convert_image_dtype(tf.image.decode_png(images_content, channels=1), tf.float32) 
    if aug: 
     images = self.data_augmentation(images) 
    new_size = tf.constant([FLAGS.image_size, FLAGS.image_size], dtype=tf.int32) 
    images = tf.image.resize_images(images, new_size) 
    image_batch, label_batch = tf.train.shuffle_batch([images, labels], batch_size=batch_size, capacity=50000, 
                 min_after_dequeue=10000) 
    # print 'image_batch', image_batch.get_shape() 
    return image_batch, label_batch 
+0

是否可以在批次内应用所有不同的随机移位? – user270700

+0

更新了我的答案。 – soloice

2

作为替代方案,也可以使用tf.contrib.image.transform()并使用参数A2B2到图像翻译:

import numpy as np 
import tensorflow as tf 

image1 = np.array([[[.1], [.1], [.1], [.1]], 
        [[.2], [.2], [.2], [.2]], 
        [[.3], [.3], [.3], [.3]], 
        [[.4], [.4], [.4], [.4]]]) 
image2 = np.array([[[.1], [.2], [.3], [.4]], 
        [[.1], [.2], [.3], [.4]], 
        [[.1], [.2], [.3], [.4]], 
        [[.1], [.2], [.3], [.4]]]) 
images = np.stack([image1, image2]) 
images_ = tf.convert_to_tensor(images, dtype=tf.float32) 

shift1_x = 1 
shift1_y = 2 
shift2_x = -1 
shift2_y = 0 
transforms_ = tf.convert_to_tensor([[1, 0, -shift1_x, 0, 1, -shift1_y, 0, 0], 
            [1, 0, -shift2_x, 0, 1, -shift2_y, 0, 0]], 
            tf.float32) 
shifted_ = tf.contrib.image.transform(images=images_, 
             transforms=transforms_) 
with tf.Session() as sess: 
    sess.run(tf.global_variables_initializer()) 

    shifted = sess.run([shifted_]) 
    print(shifted) 

变换投影矩阵,也可以是张量大小为N×8,因此可以以不同方式移动批次的每个图像。这可以通过tf.random_uniform()容易地扩展,以包括对每个图像的x/y偏移的一些随机性。

编辑: 要使用随机转变批次的每一个形象:

... 
images_ = tf.convert_to_tensor(images, dtype=tf.float32) 

num_imgs = images.shape[0] 
base_ = tf.convert_to_tensor(np.tile([1, 0, 0, 0, 1, 0, 0, 0], [num_imgs, 1]), dtype=tf.float32) 
mask_ = tf.convert_to_tensor(np.tile([0, 0, 1, 0, 0, 1, 0, 0], [num_imgs, 1]), dtype=tf.float32) 
random_shift_ = tf.random_uniform([num_imgs, 8], minval=-2.49, maxval=2.49, dtype=tf.float32) 
transforms_ = base_ + random_shift_ * mask_ 

shifted_ = tf.contrib.image.transform(images=images_, 
             transforms=transforms_) 
... 

编辑2: 完成的缘故,这里只是与其他辅助功能应用随机旋转和移到批次的每个单个图像:

def augment_data(input_data, angle, shift): 
    num_images_ = tf.shape(input_data)[0] 
    # random rotate 
    processed_data = tf.contrib.image.rotate(input_data, 
              tf.random_uniform([num_images_], 
                   maxval=math.pi/180 * angle, 
                   minval=math.pi/180 * -angle)) 
    # random shift 
    base_row = tf.constant([1, 0, 0, 0, 1, 0, 0, 0], shape=[1, 8], dtype=tf.float32) 
    base_ = tf.tile(base_row, [num_images_, 1]) 
    mask_row = tf.constant([0, 0, 1, 0, 0, 1, 0, 0], shape=[1, 8], dtype=tf.float32) 
    mask_ = tf.tile(mask_row, [num_images_, 1]) 
    random_shift_ = tf.random_uniform([num_images_, 8], minval=-shift, maxval=shift, dtype=tf.float32) 
    transforms_ = base_ + random_shift_ * mask_ 

    processed_data = tf.contrib.image.transform(images=processed_data, 
               transforms=transforms_) 
    return processed_data