2017-02-16 13 views
0

入力画像(テンソル)をすべてのバッチでランダムに上下または右にシフトしたいと思っています。Tensorflowでランダムにテンソルのバッチを変換またはシフトする方法

たとえば、サイズが[10, 48, 64, 1]のグレースケールイメージのバッチがあります。

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リストです。入力パイプラインでは、データストリームはストリームのように流れます。ただ1つのイメージだけを処理する必要があります。キューは自動的にスケジューリング作業を行います(一部のスレッドはデータを読み込み、一部はデータを処理し、 GPUなどにデータを送り、パイプライン全体をビジーに保ちます)。以下のコードでは、imageslabelsはキューです。つまり、この変数を処理すると(self.data_augmentationのように)、画像には1つの画像しか含まれていないと思うかもしれませんが、実際にはキュー内のすべての項目が処理されます(暗黙のループのようです)。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 
関連する問題