EeBlog(テクニカルブログ)

AI(人工知能)実践 第10回 学習データの作成

AI(人工知能)実践 第10回です。

今まで行ってきたアヤメの分類については、既に用意されたデータを使用してきました。
実際に画像の判別等を行いたい場合、必ずしも既に用意されているとは限りません。
むしろ、判別したいものの画像セットやモデルが用意されていることの方が少ないかと思います。
では、ある特定のモノを判別させたい場合、
学習させる為の画像を数多く用意する必要がありますが、実際に用意出来る数には限りがあります。
しかし、数が少ない場合ですと、学習が思ったように進みません。
そこで、TensorFlowには画像を加工して学習用のデータが嵩増し出来るようなAPIが提供されています。
今回は、その画像加工の一部を紹介していきます。
該当するAPIは、「tf.image」となります。
 

では、公式サイト(https://www.tensorflow.org/api_guides/python/image)
で記載されているものをピックアップして紹介していきます。
なお、ソース例でimport文の記載がない場合、「import tensorflow as tf」の記載が省略されており、
実際には記載が必要です。
 

画像のデコード

特定の形式のファイルから変換します。

tf.image.decode_image(
contents,
channels=None,
name=None
)

tf.image.decode_png(
contents,
channels=0,
dtype=tf.uint8,
name=None
)

tf.image.decode_bmp(
contents,
channels=0,
name=None)

tf.image.decode_gif(
contents,
name=None
)

tf.image.decode_jpeg(
contents,
channels=0,
ratio=1,
fancy_upscaling=True,
try_recover_truncated=False,
acceptable_fraction=1,
dct_method=”,
name=None
)

上記のtf.image.decode_imageはその他のdecodeメソッドと少し毛色が違っており、
contentsに渡されたものがBMP、GIF、JPEG、PNGのいずれであるかを自動で判別し、
dtypeがtf.uint8のTensorに変換します。
なので、色々な形式の画像が格納されたフォルダを全部自動で読み込みたい等の場合には
tf.image.decode_imageメソッドを使用すると便利です。

使用例

#ファイル名
FNAME_ORIG="hydrangea.png"

#ファイルの読み込み
read_image = tf.read_file(FNAME_ORIG)
#読み込んだPNGをRGBのTensorへデコード変換
rgb_image = tf.image.decode_png(read_image, channels=3)

 

画像のエンコード

特定の形式のファイルへと変換します。

tf.image.encode_jpeg(
image,
format=”,
quality=95,
progressive=False,
optimize_size=False,
chroma_downsampling=True,
density_unit=’in’,
x_density=300,
y_density=300,
xmp_metadata=”,
name=None
)

tf.image.encode_png(
image,
compression=-1,
name=None
)

使用例

#ファイル名
FNAME_ORIG="hydrangea.png"

#ファイルの読み込み
read_image = tf.read_file(FNAME_ORIG)
#読み込んだPNGをRGBのTensorへデコード変換
rgb_image = tf.image.decode_png(read_image, channels=3)

#何かしら処理を実行

#RGBのTensorをPNGのTensorに変換
png_image = tf.image.encode_png(rgb_image)

 

サイズの変更

渡されたイメージのサイズを変更します。
使用するメソッドによって、画素補完法が異なります。

リサイズを行います。(縦横比を変更すると歪みます)
tf.image.resize_images(
images,
size,
method=ResizeMethod.BILINEAR,
align_corners=False
)

領域補完でリサイズを行います。
tf.image.resize_area(
images,
size,
align_corners=False,
name=None
)

バイキュービック法でリサイズを行います。
tf.image.resize_bicubic(
images,
size,
align_corners=False,
name=None
)

バイリニア法でリサイズを行います。
tf.image.resize_bilinear(
images,
size,
align_corners=False,
name=None
)

ニアレストネイバー法でリサイズを行います。
tf.image.resize_nearest_neighbor(
images,
size,
align_corners=False,
name=None
)

使用例

#ファイル名
FNAME_ORIG="hydrangea.png"

#ファイルの読み込み
read_image = tf.read_file(FNAME_ORIG)
#読み込んだPNGをRGBのTensorへデコード変換
rgb_image = tf.image.decode_png(read_image, channels=3)

#画像を200*300にリサイズ
rgb_image = tf.image.resize_images(rgb_image, [200,300])

 

反転、回転、転置

渡されたイメージの反転や回転、転置を行います。

画像の上下反転を行います。
tf.image.flip_up_down(image)

ランダム(1/2)で画像の上下反転を行います。
tf.image.random_flip_up_down(
image,
seed=None
)

画像の左右反転を行います。
tf.image.flip_left_right(image)

ランダム(1/2)で画像の左右反転を行います。
tf.image.random_flip_left_right(
image,
seed=None
)

高さと幅を入れ替えて、画像の転置を行います。
tf.image.transpose_image(image)

画像を反時計回りに90度回転させます。
tf.image.rot90(
image,
k=1,
name=None
)

使用例

#ファイル名
FNAME_ORIG="hydrangea.png"

#ファイルの読み込み
read_image = tf.read_file(FNAME_ORIG)
#読み込んだPNGをRGBのTensorへデコード変換
rgb_image = tf.image.decode_png(read_image, channels=3)

#画像の高さと幅を入れ替えて、転置する
rgb_image = tf.image.transpose_image(rgb_image)

 

その他の操作

上記で紹介した以外にも、トリミングや色空間の変換、
バウンディングボックスの操作、ノイズ除去などがあります。
公式サイト(https://www.tensorflow.org/api_guides/python/image)でまとめられてますので、確認してみて下さい。
 

実用例

1つ1つのファイルを取り込んで、変換して、を手動で行っていると、いうほど手間が減りません。
よって、あるフォルダにある画像全てをそれぞれ50枚増やすというメソッドを作ってみます。
今回は1枚の画像から色々増やすことが出来る、というところだけ見たいので適当に選びますが、
増やす際の処理に関しては、学習したい内容及び画像で適切なものを選択してください。
※色も含めて判別したい場合に、色を変更してしまう処理は行わない、等

import os
import sys
import glob
import tensorflow as tf

#イメージファイルのパス
IMG_DIR = 'c:\\work\\test\\images'
IMG_EXTENTION = '.png'

def createImage(fpath, count=50):
    #渡された引数のファイルパスをファイル名と拡張子に分割
    fname = os.path.basename(fpath)
    fname_base, fname_ext = os.path.splitext(fname)
    #作成する画像用のフォルダ作成
    output_dir = IMG_DIR + '\\' + fname_base
    dir_count = 0
    #作成しようとしたフォルダが既にある場合、後ろに(数字)を付ける
    while os.path.isdir(output_dir):
        dir_count+=1
        output_dir = IMG_DIR + '\\' + fname_base + '(' + str(dir_count) + ')'
    os.makedirs(output_dir)
    
    with tf.Session() as sess:
        #オリジナルファイルの読み込み
        read_image = tf.read_file(fpath)
        #読み込んだPNGをRGBのTensorへデコード変換
        rgb_image = tf.image.decode_png(read_image, channels=3)
        #RGBのTensorのデータ型をtf.float32に変換
        rgb_image_float = tf.image.convert_image_dtype(rgb_image, tf.float32)
        for n in range(count):
            #画像を200*300にリサイズ
            rgb_image_float = tf.image.resize_images(rgb_image_float, [200,300])
            #色相をランダムで変換
            change_image = tf.image.random_hue(rgb_image_float, max_delta=0.5) 
            #彩度をランダムで変換
            change_image = tf.image.random_saturation(change_image, lower=0.2, upper=1.8)
            #左右をランダムで反転(1/2の確率で反転させる)
            change_image = tf.image.random_flip_left_right(change_image)
            #RGBのTensorのデータ型をtf.uint8に変換
            change_image = tf.image.convert_image_dtype(change_image, tf.uint8)
            #RGBのTensorをPNGのTensorに変換
            png_image = tf.image.encode_png(change_image)
            #PNGのTensorをファイル出力
            write_result = tf.write_file(output_dir + '\\' 
                                         + fname_base + '_' + str(n+1) 
                                         + fname_ext, png_image)
            sess.run(write_result)
    sess.close()

print('process start')
for file in glob.glob(IMG_DIR + '\\\\*' + IMG_EXTENTION):
    print('Increase image from ' + file)
    createImage(file)

print('process end')

上記のソースを実行すると、こうなります。

実行前
プログラム実行前
実行後
プログラム実行後
変換後の紫陽花
変換後の金沢城

※なお、今回使用した画像2枚は筆者が撮影していますので、著作権に問題はありません。
学習を進めるにあたって使用する(集める)データに関して、表に出さないもの(学習では使用するが、例として表示したりしないもの)であれば
 日本の著作権法では第四七条の七にて利用することを認められていますが、扱いには十分に注意しましょう。
参考(http://www.cric.or.jp/db/domestic/a1_index.html より引用)

(情報解析のための複製等)
第四十七条の七 著作物は、電子計算機による情報解析(多数の著作物その他の大量の情報から、当該情報を構成する言語、音、影像その他の要素に係る情報を抽出し、比較、分類その他の統計的な解析を行うことをいう。以下この条において同じ。)を行うことを目的とする場合には、必要と認められる限度において、記録媒体への記録又は翻案(これにより創作した二次的著作物の記録を含む。)を行うことができる。ただし、情報解析を行う者の用に供するために作成されたデータベースの著作物については、この限りでない。

(平二一法五三・追加)」