Pynote

Python、機械学習、画像処理について

Deep Learning - Augmentor で画像のデータセットを水増し (オーグメンテーション) する。

関連記事

pynote.hatenablog.com

インストール

pip でインストールできる。

pip install Augmentor 

基本的な使い方

回転や反転などデータセットを水増しするために画像に対して行う1つの処理を operation と参照する。

まずパイプラインを作成する。

class Augmentor.Pipeline.Pipeline(source_directory=None, output_directory=u'output', save_format=None)
  • 引数
    • source_directory: 入力画像があるディレクトリ。
    • output_directory: オーグメンテーションした結果を保存するディレクトリ。
    • save_format: 保存形式。"JPG", "PNG", "BMP", "GIF" から選択する。デフォルトは "JPG"。
import Augmentor

# パイプラインを作成する。
p = Augmentor.Pipeline("images")

パイプラインに行いたい operation を追加していく。

# 確率 0.7 でランダムに [-10, 10] 度の範囲で回転する。
p.rotate(probability=0.7, max_left_rotation=10, max_right_rotation=10)

# 確率 0.5 でランダムに [1.1, 1.5] の範囲で拡大する。
p.zoom(probability=0.5, min_factor=1.1, max_factor=1.5)

オーグメンテーションを実行する。

sample(n) で n 枚の画像を生成し、source_directory を基点とした相対パス output_directory に出力する。
output_directory を指定していなかった場合、source_directory 以下に output というディレクトリが作成され、そこに生成された画像が保存される。

p.sample(9)
images: 入力画像が置いてあるディレクトリ
├── output: 生成された画像が保存されるディレクトリ
│   ├── images_original_test.jpg_1d36790d-81c8-4553-be35-2e33733eb48f.jpg
│   ├── images_original_test.jpg_2747561d-134c-44cd-9110-d9156defedc9.jpg
│   ├── images_original_test.jpg_4857f1c5-f835-48ac-b96d-54c6fffa1a09.jpg
│   ├── images_original_test.jpg_793b9981-3441-4254-9c29-9eec4ca947af.jpg
│   ├── images_original_test.jpg_7be1864b-837b-49a5-8d8c-d41a01196572.jpg
│   ├── images_original_test.jpg_8082c7df-5a94-42ca-bc46-a6d1b820bb40.jpg
│   ├── images_original_test.jpg_8f65bd06-e92c-4e4f-8de0-7becca81b769.jpg
│   ├── images_original_test.jpg_a64b3a9c-8da0-4bbf-9a4f-9f569986d5d0.jpg
│   └── images_original_test.jpg_f424e36d-6224-4b8c-bfde-97a90b2a3e23.jpg
└── test.jpg

入出力の方式

入力画像の枚数と同じ枚数生成する。

p.process()

n 枚生成する。

p.sample(9)

ディレクトリから読み込む代わりに配列を渡す。

ディレクトリから画像を読み込む代わりにすでに読み込んである画像のリストを渡してオーグメンテーションしたい場合は、Augmentor.DataPipeline(images) でパイプラインを作成する。

from pathlib import Path

import numpy as np
import Augmentor
from PIL import Image

# ディレクトリから画像を読み込み、配列を作成する。
imgs = []
for path in Path("images").iterdir():
    if path.suffix not in [".jpg", ".jpeg", ".png", ".gif", ".bmp"]:
        continue  # 画像以外は無視する。
    # 画像を読み込む。
    img = Image.open(path)
    # 画像をリサイズする。
    img = img.resize((256, 256))

    imgs.append(np.array(img))
imgs = np.array(imgs)

# 画像データ imgs 及びラベルデータ labels を入力データとする。
p = Augmentor.DataPipeline(imgs)

p.rotate(probability=0.7, max_left_rotation=10, max_right_rotation=10)
p.zoom(probability=0.5, min_factor=1.1, max_factor=1.5)

x = p.sample(9)
x = np.array(x)
print(x.shape)
# (9, 256, 256, 3)

Keras Generator を作成する。

Keras の ImageDataGenerator の flow_from_directory() で作成できるジェネレーターを返す。
fit_generator() などの関数にそのまま渡すことができる。

import Augmentor

p = Augmentor.Pipeline("images")

p.rotate(probability=0.7, max_left_rotation=10, max_right_rotation=10)
p.zoom(probability=0.5, min_factor=1.1, max_factor=1.5)

gen = p.keras_generator(batch_size=9, scaled=True, image_data_format="channels_last")

x, y = next(gen)
print(x.shape, y.shape)
# (9, 782, 1024, 3) (9, 1)

keras_generator_from_array() を使用する場合、ディレクトリの画像の代わりに渡した画像及びラベルを入力とする。
Keras の ImageDataGenerator の flow() で作成できるジェネレーターを返す。

from pathlib import Path

import numpy as np
import Augmentor
from PIL import Image

# ディレクトリから画像を読み込み、配列を作成する。
imgs = []
for path in Path("images").iterdir():
    if path.suffix not in [".jpg", ".jpeg", ".png", ".gif", ".bmp"]:
        continue  # 画像以外は無視する。
    # 画像を読み込む。
    img = Image.open(path)
    # 画像をリサイズする。
    img = img.resize((256, 256))

    imgs.append(np.array(img))
imgs = np.array(imgs)
labels = np.arange(len(imgs))  # ダミー (実際は画像に対応するラベルを用意する)

p = Augmentor.Pipeline("images")

p.rotate(probability=0.7, max_left_rotation=10, max_right_rotation=10)
p.zoom(probability=0.5, min_factor=1.1, max_factor=1.5)

gen = p.keras_generator_from_array(
    imgs, labels, batch_size=9, scaled=True, image_data_format="channels_last"
)

x, y = next(gen)
print(x.shape, y.shape)
# (9, 782, 1024, 3) (9, 1)

operation の種類

probability

すべての operation は probability 引数をとり、その operation が実行される確率を指定する。
例えば、probability=0.5 の場合、50%の確率でその operation が実行される。

2値化する。(black_and_white)

画像をグレースケールに変換し、threshold 未満の画素は0、threshold 以上の画素は255として2値化する。

p.black_and_white(probability=1.0, threshold=100)


グレースケール化する。

画像をグレースケール化する。

p.greyscale(probability=1.0)


ヒストグラムを平坦化する。

p.histogram_equalisation(probability=1.0)


切り抜きする。

画像から大きさ (width, height) を切り抜く。
width が画像の幅より大きい場合、切り抜いた画像の幅は画像の幅となる。(height も同様)
centre=True の場合、画像の中心に合わせて切り抜く。

p.crop_by_size(probability=0.7, width=400, height=400, centre=False)

画像の中心に合わせて切り抜く場合、以下の関数もある。
randomise_percentage_area=False の場合、切り抜いた画像の面積が元の画像の percentage_area %となるように切り抜く。
randomise_percentage_area=True の場合、切り抜いた画像の面積が元の画像の [0, percentage_area] %となるように切り抜く。
この場合、切り抜いた画像の大きさはそれぞれ異なるため、keras_generator() など生成した画像がすべて同一サイズである必要がある関数は使用できないので注意する。

p.crop_centre(probability=0.7, percentage_area=0.8,
              randomise_percentage_area=False)

画像の中心に合わせずにランダムな位置から切り抜く場合、以下の関数もある。

p.crop_random(probability=0.7, percentage_area=0.8,
              randomise_percentage_area=False)

パラメータは crop_by_size() と同様である。

反転する。

左右反転する。

p.flip_left_right(probability=0.7)

上下反転する。

p.flip_top_bottom(probability=0.7)

上下左右反転する。

p.flip_random(probability=0.7)


ネガ反転する。

p.invert(probability=0.7)


明るさを変更する。

画像の明るさを [min_factor, max_factor] の範囲で変更する。

p.random_brightness(probability=0.7, min_factor=0.3, max_factor=1.7)


彩度を変更する。

画像の彩度を [min_factor, max_factor] の範囲で変更する。

p.random_color(probability=0.7, min_factor=0.3, max_factor=1.7)


コントラストを変更する。

画像のコントラストを [min_factor, max_factor] の範囲で変更する。

p.random_contrast(probability=0.7, min_factor=0.3, max_factor=1.7)


一部を歪ませる。

p.random_distortion(
    probability=0.8, grid_width=6, grid_height=6, magnitude=8)


画像の一部を隠す。

画像の面積の rectangle_area の割合を隠す。

p.random_erasing(probability=0.8, rectangle_area=0.2)


リサイズする。

resample_filter は "BICUBIC", "BILINEAR", "ANTIALIAS", "NEAREST" から選択する。

p.resize(probability=1.0, width=256, height=256, resample_filter="BICUBIC")

画像をアスペクト比を保持した状態で大きくする場合は以下の関数がある。
画像の幅及び高さを scale_factor (>= 1.0) 倍する。

p.scale(probability=1.0, scale_factor=1.5)

回転する。

画像を [-max_left_rotation, max_right_rotation] の範囲で回転する。
回転後に画素がない黒い部分が含まれないように切り抜かれる。

p.rotate(probability=0.7, max_left_rotation=10, max_right_rotation=10)

切り抜きを行わない場合は以下の関数がある。

p.rotate_without_crop(probability=0.7, max_left_rotation=10, max_right_rotation=10)

90°回転する。

p.rotate90(probability=0.7)

180°回転する。

p.rotate180(probability=0.7)

270°回転する。

p.rotate270(probability=0.7)

90°、180° または 270° 回転する。

p.rotate_random_90(probability=0.7)

せん断する。

画像を [-max_shear_left, max_shear_right] の範囲でせん断する。

p.shear(probability=1.0, max_shear_left=10, max_shear_right=10)

拡大する。

画像の中心に合わせて [min_factor, max_factor] の範囲で拡大する。

p.zoom(probability=0.7, min_factor=1.1, max_factor=1.5)

画像の中心以外に合わせて拡大する場合は以下の関数がある。
randomise_percentage_area=False の場合、切り抜いた画像の面積が元の画像の percentage_area %となるように拡大する。
randomise_percentage_area=True の場合、切り抜いた画像の面積が元の画像の [0, percentage_area] %となるように拡大する。

p.zoom_random(probability=0.7, percentage_area=0.8,
              randomise_percentage_area=True)


歪ませる。

skew (歪み) は以下の種類がある。


  • skew(probability, magnitude): Tilt Left, Tilt Right, Tilt Forward, Tilt Backward, Skew Type 0 ~ 7 の12種類のいずれか
  • skew_corner(probability, magnitude): Skew Type 0 ~ 7 の8種類のいずれか
  • skew_left_right(probability, magnitude): Tilt Left, Tilt Right の2種類のいずれか
  • skew_top_bottom(probability, magnitude): Tilt Forward, Tilt Backward の2種類のいずれか
  • skew_tilt(probability, magnitude): Tilt Left, Tilt Right, Tilt Forward, Tilt Backward の4種類のいずれか