LoginSignup
6
3

More than 1 year has passed since last update.

Keras、cv2、PILの画像水増しの比較

Last updated at Posted at 2021-08-22

画像の水増しをしたい…!

ディープラーニングをやっていると画像分類をしたくなる時が来る。
そんな時、圧倒的に足りなくなるのが画像データだと思う。

賢明な皆さんは画像の水増しに思い当っているはずなので、それぞれのライブラリの比較を行う。

私のおすすめは、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()

完成した画像がこちら
catrot60.jpg

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)

このように、明るさを変えたり白と黒の二色で表すこともできる。

cat-hsv1-1-0.5.jpg
cat-thresh-128.jpg

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()

また、このように引き延ばしたりも可能である
img_0_9285.jpg

終わりに

deep learningでは前処理が結果の8割を占めているといわれている。
今回取り扱ったものはほんの一部でしかないので、各々自分に必要なものを使ってほしい。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3