Help us understand the problem. What is going on with this article?

画像の水増し方法をTensorFlowのコードから学ぶ

More than 3 years have passed since last update.

はじめに

Deep Learningで画像を精度よく分類するにはとにかく枚数が必要です。しかし、大量の画像をすべて手作業で用意・タグ付けするのは困難です。そこで、タグ付けされた画像を加工することで画像の枚数を増やす(水増しする)ことが行われます。
スクリーンショット 2016-09-07 13.40.40.png

今回は、水増しするためにどのようなことをするのかをTensorFlowのコードから学びたいと思います。

具体的にはCIFAR-10のコードから学んでいきます。
cifar10/cifar10_input.py

実際のコードでは以下のように複数の処理を組み合わせて画像の水増しを行っていました。

# Image processing for training the network. Note the many random
# distortions applied to the image.

# Randomly crop a [height, width] section of the image.
distorted_image = tf.random_crop(reshaped_image, [height, width, 3])

# Randomly flip the image horizontally.
distorted_image = tf.image.random_flip_left_right(distorted_image)

# Because these operations are not commutative, consider randomizing
# the order their operation.
distorted_image = tf.image.random_brightness(distorted_image, max_delta=63)
distorted_image = tf.image.random_contrast(distorted_image, lower=0.2, upper=1.8)

# Subtract off the mean and divide by the variance of the pixels.
float_image = tf.image.per_image_whitening(distorted_image)

一つずつ見ると、CIFAR-10のコード中では以下の5つの処理が行われていました:

  • random_crop
  • random_flip_left_right
  • random_brightness
  • random_contrast
  • per_image_whitening

それぞれが何をしているのか視覚的に理解していきます。

tf.random_crop(value, size, seed=None, name=None)

random_crop関数は与えられたサイズ(size)で画像をランダムにトリミングするための関数です。
以下の画像は、実際に256x170の画像に対して、size=100x100でトリミングした結果です:

スクリーンショット 2016-09-07 12.26.51.png

seedに与える値によって、トリミングする位置が変化します。同じseed値なら何度実行しても同じ画像が生成されます。

tf.image.random_flip_left_right(image, seed=None)

random_flip_left_right関数は画像をランダムで水平方向に反転するための関数です。
以下の画像は、実際にrandom_flip_left_right関数を適用してみた結果です:
スクリーンショット 2016-09-07 13.21.57.png

確率的に反転が行われるので、seedの値によっては反転されないこともあります。

random_flip_left_rightに似た関数として、random_flip_up_downという関数もあります。random_flip_left_rightが水平方向に反転するのに対して、random_flip_up_downは垂直方向に反転を行います。

tf.image.random_brightness(image, max_delta, seed=None)

random_brightness関数はランダムな要因によって画像の明るさを調整するための関数です。
以下の画像は、実際にrandom_brightness関数を適用してみた結果です:
スクリーンショット 2016-09-07 13.40.40.png

max_deltaとseedの値によって、明るさの度合いが変わります。

tf.image.random_contrast(image, lower, upper, seed=None)

random_contrast関数はランダムな要因によって画像のコントラストを調整するための関数です。
以下の画像は、実際にrandom_contrast関数を適用してみた結果です:
スクリーンショット 2016-09-07 13.46.37.png

Contrast1はコントラストが低減され、Contrast2はコントラストが強調されていることがわかります。強弱の下限と上限は、lowerとupperで調整することができます。

tf.image.per_image_whitening(image)

per_image_whitening関数は平均が0になるように画像を白色化するための関数です。
以下の画像は、実際にper_image_whitening関数を適用してみた結果です:

スクリーンショット 2016-09-07 13.50.52.png

実際は各ピクセル値を(x - mean) / adjusted_stddevで計算しています。meanは画像内のすべてのピクセル値の平均で、adjusted_stddevはadjusted_stddev = max(stddev, 1.0/sqrt(image.NumElements()))と定義されます。ここで、stddevは画像内のすべてのピクセル値の標準偏差です。

その他

TensorFlowのCIFAR-10のexampleでは使っていないものの、水増しに使えそうな関数は他にもあります。それらについて5つほど紹介します。

tf.image.transpose_image(image)

transpose_image関数は、画像を転置してくれる関数です。
以下の画像は、実際にtranspose_image関数を適用してみた結果です:
スクリーンショット 2016-09-08 9.08.54.png

転置するだけなので、何回実行しても同じ結果です。転置した画像を更に転置すれば元の画像に戻ります。

tf.image.rot90(image, k=1)

rot90関数は、90度ごとに画像を反時計回りに回転させます。
以下の画像は、実際にrot90関数を適用してみた結果です:
スクリーンショット 2016-09-08 9.12.28.png

kの値を変更することで、何度回転させるかを指定することができます。

tf.image.random_hue(image, max_delta, seed=None)

random_hue関数は、ランダムな要因によりRGB画像の色相を調整するための関数です。
以下の画像は、実際にrandom_hue関数を適用してみた結果です:
スクリーンショット 2016-09-08 9.17.04.png

max_deltaは0から0.5の範囲である必要があります。

tf.image.random_saturation(image, lower, upper, seed=None)

random_saturation関数は、RGB画像の彩度を調整するための関数です。
以下の画像は、実際にrandom_saturation関数を適用してみた結果です:
スクリーンショット 2016-09-08 9.21.20.png

拡大・縮小

拡大・縮小については以下にまとめたのでそちらを参照してください:

参考

tis
創業40年超のSIerです。
https://www.tis.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away