ディープラーニングで使用するために画像を水増しします。何度か画像をディープラーニングの学習器にかけているのですが、やはり画像の枚数が少ないと結果が向上しない。また、画像を集めるのにも限界があるので水増しで対応です。
OpenCVのflip、threshold、GaussianBlur
今回も参照させていただいたサイトは下記のサイトさんです。
機械学習で乃木坂46を顏分類してみた | Aidemy | 10秒で始めるAIプログラミング学習サービスAidemy[アイデミー]
今回使った水増しの方法
flip
- 手法・・・反転
- 引数・・・(元の配列, 反転方向を示す値)
- 備考・・・0:上下反転, >0:左右反転, <0:上下左右反転
threshold
- 手法・・・閾値処理
- 引数・・・(元の配列, 閾値, 閾値を超えた場合に変更する値, 二値化の方法)
- 備考・・・thresholdは閾値と二値化された画像を返す
GaussianBlur
- 手法・・・ぼかし
- 引数・・・(元の配列, カーネルサイズ, G分ンプのσ)
flipはホクロの位置とか変わってしまうから迷ったのですが実装しました。
コード
パス以外は参照サイトさんのそのままです。(インデントが見えなかったのでインデントはこちらで入れています)
import os
import numpy as np
import matplotlib.pyplot as plt
import cv2
def scratch_image(img, flip=True, thr=True, filt=True):
methods = [flip, thr, filt]
filter1 = np.ones((3, 3))
images = [img]
scratch = np.array([
lambda x: cv2.flip(x, 1),
lambda x: cv2.threshold(x, 100, 255, cv2.THRESH_TOZERO)[1],
lambda x: cv2.GaussianBlur(x, (5, 5), 0)
])
doubling_images = lambda f, imag: np.r_[imag, [f(i) for i in imag]]
for func in scratch[methods]:
images = doubling_images(func, images)
return images
d_name = ['イソ', 'ウォニョン', 'ガウル', 'ユジン', 'リズ', 'レイ']
for name in d_name:
files = glob.glob(f'face_image/train/{name}/*')
img_filename_list = os.listdir(f'face_image/train/{name}')
for i in range(len(files)):
img = cv2.imread(files[i])
scratch_face_images = scratch_image(img)
for idx, val in enumerate(scratch_face_images):
fn, ext = os.path.splitext(img_filename_list[i])
file_name = os.path.join(f'face_scratch_image/{name}', fn+'_'+str(idx)+'.png')
cv2.imwrite(file_name, val)
このコードで300枚程度だった画像が2550枚になりました。ディープラーニングの学習器に通すのが楽しみですね!
numpyのr_やc_
scratch_image関数内にあるnp.r_は、np.c_と同様に配列を結合するオブジェクトです。r_は縦方向に配列を結合し、c_は横方向に配列を結合します。
- 配列と数値を混在させて結合できる
- スライスでステップ数やか分割数を指定して数列をつくれる
- vstack()やhstack()の代わりに使える