画像の水増しをしたい…!
ディープラーニングをやっていると画像分類をしたくなる時が来る。
そんな時、圧倒的に足りなくなるのが画像データだと思う。
賢明な皆さんは画像の水増しに思い当っているはずなので、それぞれのライブラリの比較を行う。
私のおすすめは、Keras ImageDataGeneratorである。作るのがだいぶ楽ちんなので。
前提条件
- 元の画像はjpg形式とする。
- 画像編集としてではなく、あくまでディープラーニングを目的とした、大規模なデータセットの作成を目的とする。
前準備
main.py
import os
path = os.getcwd()
input_dir = os.path.join(path,"images") # 画像があるディレクトリ
output_dir = os.path.join(path,"Data_augmentation") # 保存先ディレクトリ
# ディレクトリ作成
if os.path.isdir(input_dir) is False:
os.mkdir(input_dir)
if os.path.isdir(output_dir) is False:
os.mkdir(output_dir)
PIL
最もシンプルで使いやすいライブラリ。
numpyにするだけなので感覚的な理解も容易。
サンプルを以下に記す。
example_PIL.py
from PIL import Image
import glob
import os
class PIL_img():
def __init__(self, input_dir, output_dir, name):
self.image = Image.open(input_dir)
self.name = name
self.output_dir = output_dir
def rot(self, degree=60, expand=True):
# 画像の回転
self.image = self.image.rotate(degree, expand=expand)
# 画像の保存
tag = "rot"+str(degree)
save_name = os.path.join(self.output_dir,name+tag+".jpg")
self.image.save(save_name)
for input_img in input_imgs:
pil_img = PIL_img(input_img, output_dir, name)
pil_img.rot()
openCV cv2
シンプルかつ、幅広い使い道があるライブラリ。
様々なメソッドがあり、より学習結果の向上が見込める画像を作れる。
※配列化するとき一般的にRGBなのだが、cv2はBGRになっているので注意が必要!!
サンプルを以下に記す。
example_cv2.py
import os
import cv2
class cv2_img():
def __init__(self, input_img, output_dir, name):
self.img = cv2.imread(input_img)
self.img_gray = cv2.imread(input_img, 0)
self.name = os.path.join(output_dir, name)
def hsv(self, hue=1, saturation=1, value=1):
# bgr→hsvに変換
hsv_img = cv2.cvtColor(self.img, cv2.COLOR_BGR2HSV)
# hsvの数値の変更
hsv_img[:, :, (0)] = hsv_img[:, :, (0)] * hue
hsv_img[:, :, (1)] = hsv_img[:, :, (1)] * saturation
hsv_img[:, :, (2)] = hsv_img[:, :, (2)] * value
# hsv→bgrに変換
hsv_img = cv2.cvtColor(hsv_img, cv2.COLOR_HSV2BGR)
# jpgの名前に処理の内容を記述
tag = "-hsv" + str(hue) + "-" + str(saturation) + "-" + str(value)
jpg_name = self.name + tag + '.jpg'
# ec2にjpgの保存
cv2.imwrite(jpg_name, hsv_img)
def thresh(self, threshold=128):
# 閾値を基準に白と黒に分ける
ret, thresh_img = cv2.threshold(self.img_gray, threshold, 255, cv2.THRESH_BINARY)
# jpgの名前に処理の内容を記述
tag = "-thresh-" + str(threshold)
jpg_name = self.name + tag + '.jpg'
# ec2にjpgの保存
cv2.imwrite(jpg_name, thresh_img)
input_imgs = glob.glob(input_dir + "/*.jpg")
name = "cat"
for input_img in input_imgs:
CV2_img = cv2_img(input_img, output_dir, name)
CV2_img.thresh()
CV2_img.hsv(1, 1, 0.5)
このように、明るさを変えたり白と黒の二色で表すこともできる。
Keras ImageDataGenerator
特殊な処理をせずともgif画像が読み取れる
openCVより多い画像処理
画像のURLをリストの状態で渡せるため、ディレクトリ丸ごと作成が可能!
名前を付ける必要がない!
ImageDataGenerator_ex.py
import os
from keras.preprocessing.image import load_img, img_to_array
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
import glob
class gen_img():
def __init__(self, input_dir, output_dir):
self.files = glob.glob(input_dir + "/*.jpg")
self.output_dir = output_dir
# 画像の回転
def rot(self, num=9, ranger=100):
for i, file in enumerate(self.files):
# ファイルの配列化
img = load_img(file)
x = img_to_array(img)
x = np.expand_dims(x, axis=0)
# データの作成
datagen_rotation = ImageDataGenerator(rotation_range=ranger)
img_rotation = datagen_rotation.flow(x, batch_size=1, save_to_dir=self.output_dir, save_prefix='img', save_format='png')
# 任意の回数保存
for i in range(num):
batch_rotation = img_rotation.next()
return batch_rotation
# 画像の拡大
def zoom(self, num=9, ranger=0.5):
for i, file in enumerate(self.files):
# ファイルの配列化
img = load_img(file)
x = img_to_array(img)
x = np.expand_dims(x, axis=0)
# データの作成
datagen_zoom = ImageDataGenerator(zoom_range=ranger)
img_zoom = datagen_zoom.flow(x, batch_size=1, save_to_dir=self.output_dir, save_prefix='img', save_format='jpg')
# 任意の回数保存
for i in range(num):
batch_zoom = img_zoom.next()
return batch_zoom
# 色の変更
def channel(self, num=9, ranger=100):
for i, file in enumerate(self.files):
# ファイルの配列化
img = load_img(file)
x = img_to_array(img)
x = np.expand_dims(x, axis=0)
# データの作成
datagen_channel = ImageDataGenerator(channel_shift_range=ranger)
img_channel = datagen_channel.flow(x, batch_size=1, save_to_dir=self.output_dir, save_prefix='img', save_format='jpg')
# 任意の回数保存
for i in range(num):
batch_channel = img_channel.next()
return batch_channel
def shear(self, num=9, ranger=0.2):
for i, file in enumerate(self.files):
# ファイルの配列化
img = load_img(file)
x = img_to_array(img)
x = np.expand_dims(x, axis=0)
# データの作成
datagen_channel = ImageDataGenerator(shear_range=ranger)
img_channel = datagen_channel.flow(x, batch_size=1, save_to_dir=self.output_dir, save_prefix='img', save_format='jpg')
# 任意の回数保存
for i in range(num):
batch_channel = img_channel.next()
return batch_channel
dig = gen_img(input_dir, output_dir)
dig.rot()
dig.zoom()
dig.channel()
dig.shear()
終わりに
deep learningでは前処理が結果の8割を占めているといわれている。
今回取り扱ったものはほんの一部でしかないので、各々自分に必要なものを使ってほしい。