LoginSignup
343
337

More than 5 years have passed since last update.

機械学習のデータセット画像枚数を増やす方法

Last updated at Posted at 2016-01-07

画像水増しの意義

ディープラーニングのCNN等のクラス分類の精度を向上させるためには、優れた学習データセットが必要です。精度を担保するためには、以下のような工夫をする必要があります。

  • 十分な画像枚数を用意する。
  • 各タグの画像枚数を揃える
  • タグ付けをより正確に行う
  • 同じ分類のものでも、見た目が異なる場合は細かくタグを分ける

これらを行うためには、とにかく枚数が必要です。種類によって枚数に偏りがある場合もあり、すべて手作業で抽出・タグ付けしていると大変です。

そこで、ある程度タグ付けされた画像たちを加工することで、画像の枚数を増やすことを考えます。その手法を幾つか紹介します。なお説明には、高城れにさんを画像処理のサンプルに使うべきとの意見に基づき、高城れにさんを利用します。

水増し手法

OpenCV 3.0 Pythonで実装します。

実際に水増しに使えるソースをこちらに用意しておきます。

Github

コントラスト調整

コントラストを強調、低減させた画像を作ります。

強調するには、一定以下の低輝度の画素を0, 一定以上の高輝度の画素を255にし、中間の輝度のものを調整します。
逆に低減するには、輝度の幅を小さくするように調整します。こちらの図がわかりやすいです。
http://livedoor.blogimg.jp/progr-python2/imgs/f/8/f867a2e8.png

# ルックアップテーブルの生成
min_table = 50
max_table = 205
diff_table = max_table - min_table

LUT_HC = np.arange(256, dtype = 'uint8' )
LUT_LC = np.arange(256, dtype = 'uint8' )

# ハイコントラストLUT作成
for i in range(0, min_table):
    LUT_HC[i] = 0
for i in range(min_table, max_table):
    LUT_HC[i] = 255 * (i - min_table) / diff_table
for i in range(max_table, 255):
    LUT_HC[i] = 255

# ローコントラストLUT作成
for i in range(256):
    LUT_LC[i] = min_table + i * (diff_table) / 255

# 変換
src = cv2.imread("reni.jpg", 1)
high_cont_img = cv2.LUT(src, LUT_HC)
low_cont_img = cv2.LUT(src, LUT_LC)

コントラストを強調したもの
reni_takagi_2012_04_15_1.jpg

コントラストを低減したもの
reni_takagi_2012_04_15_2.jpg

参考
トーンカーブで画像の濃度変換

ガンマ変換

ディスプレイの表示などの際に使われる変換で、輝度値をγの値によって変化させます。
http://livedoor.blogimg.jp/progr-python2/imgs/0/4/043dfda9.png

コントラスト調整のソースのルックアップテーブルを、こちらに置き換えてください。

# ガンマ変換ルックアップテーブル
gamma1 = 0.75
gamma2 = 1.5
for i in range(256):
    LUT_G1[i] = 255 * pow(float(i) / 255, 1.0 / gamma1)
    LUT_G2[i] = 255 * pow(float(i) / 255, 1.0 / gamma2)

γ=1.5のとき
reni_takagi_2012_04_15_3.jpg

γ=0.75のとき
reni_takagi_2012_04_15_2.jpg

参考

ルックアップテーブル(ガンマ補正の例)

平滑化

画像を滑らかにします。ここでは平均化フィルタをかけています。

average_square = (10,10)
src = cv2.imread("reni.jpg", 1)
blur_img = cv2.blur(src, average_square)

10×10平均化フィルタ

reni_takagi_2012_04_15_5.jpg

参考
平滑化(移動平均、ガウシアン)フィルタ

ガウス分布に基づくノイズ

各画素にガウス分布に基づく生成値を足して、ノイズを付加します。

σ=15のガウシアンノイズ
reni_takagi_2012_04_15_7.jpg

src = cv2.imread("reni.jpg", 1)
row,col,ch= src.shape
mean = 0
sigma = 15
gauss = np.random.normal(mean,sigma,(row,col,ch))
gauss = gauss.reshape(row,col,ch)
gauss_img = src + gauss

参考
画像情報(輝度データ)の変換

Salt&Pepperノイズ

塩と胡椒をかけたようなノイズなので、こう呼ばれます。インパルスノイズとも言うそうです。

src = cv2.imread("reni.jpg", 1)
row,col,ch = src.shape
s_vs_p = 0.5
amount = 0.004
sp_img = src.copy()

# 塩モード
num_salt = np.ceil(amount * src.size * s_vs_p)
coords = [np.random.randint(0, i-1 , int(num_salt)) for i in src.shape]
sp_img[coords[:-1]] = (255,255,255)

# 胡椒モード
num_pepper = np.ceil(amount* src.size * (1. - s_vs_p))
coords = [np.random.randint(0, i-1 , int(num_pepper)) for i in src.shape]
sp_img[coords[:-1]] = (0,0,0)

0.4%の画素にノイズ
reni_takagi_2012_04_15_8.jpg

反転

左右の反転、上下の反転を行います。

src = cv2.imread("reni.jpg", 1)
hflip_img = cv2.flip(src, 1)
vflip_img = cv2.flip(src, 0)

拡大縮小

画像の一部を拡大、縮小します。

src = cv2.imread("reni.jpg", 1)
hight = src.shape[0]
width = src.shape[1]
half_img = cv2.resize(src,(hight/2,width/2))
343
337
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
343
337