DNNで使える画像データ水増し手法
はじめに
DNN(Deep Neural Network)を活用したディープラーニングにおいて、画像学習をさせようとしたときの話。
DNNでクラス分類の精度を上げるには、より良いデータを取得する必要があります。
良いデータとは主に、
- 画像枚数が十分
- 各タグの画像枚数が等しい
- 正確なアノテーション
などとされています。
これらを実現するにあたって必要なものは一貫して「画像データの枚数」にあります。
そこで、今回は「ガンマ変換」と「平滑化」を用いて、画像の水増しをする手法を備忘録的に書いておきます。
また、実際のサンプルデータとコードはgithubに置いてあります。
ガンマ変換(ガンマ補正)
輝度値を変化させることで実装できる変換手法です。
これにより、画像を明るくしたり暗くしたりして水増しします。
サンプルコードの
gamma = 0.4
の実数部を変えることで、輝度を変えることが可能です。
閾値は1で、数字が小さいと暗く、大きいと明るくなります。
0.4~1.6の範囲で、0.1刻みで水増ししていくのがおすすめです。
ガンマ補正とは
ガンマ補正の処理は、次の式で表せます。
y = x^γ
理論的には、「画素値がn倍になると、出力の明るさもn倍になる」という比例の関係にあります。(リニア)
しかし、実際の出力では上記のグラフのように、理論結果と同じ結果になるとは限りません。
そこで、ガンマ補正という手法を使い、実際の出力をリニアに近づける処理を行います。
平滑化
平滑化という難しそうな言葉を使っていますが、言ってしまえば「ぼかし処理」です。
OpenCVを使った平滑化の手法にはいくつか種類がありますが、今回は cv2.blur() を使用しました。
こちらもガンマ変換と同様に、
blur_size = (30, 30)
の実数部を変えることで、どのくらいぼかすかを指定することができます。
数字が大きくなるとよりぼやけます。
おすすめは(5, 5)~(20, 20)です。
平滑化処理の内容
平滑化処理でどのようなことが行われているかをテストしてみました。
コードもこちらに載せておきます。(githubのレポジトリには入れていません)
import cv2
blur_size = (5, 5)
img = cv2.imread('./images/sample.jpg', cv2.IMREAD_COLOR)
file = open('./testText/sample01.txt','w')
for i in range(10):
for j in range(10):
file.write(str(img[i, j, 0]) + ' ')
file.write('\n')
file.close()
img = cv2.blur(img,blur_size)
file = open('./testText/sample02.txt','w')
for i in range(10):
for j in range(10):
file.write(str(img[i, j, 0]) + ' ')
file.write('\n')
file.close()
※ (5, 5)ピクセルで平滑化処理をした場合のコードです。
サンプル画像の左上10 × 10ピクセル分のB値(RGBのB値)を、処理前と処理後でtxtファイルに出力しています。
処理前後のtxtファイルはこのようになりました。
5~10で並べられたB値が、6と7だけでソートされています。
平滑化処理は「カーネルの範囲内にある画素の平均値を取って」処理していることがわかりました。
おわりに
「おすすめ」としてどのくらいの範囲で指定すると良いよ~ってのを書きましたが、用途にもよると思うので、自分でサンプル画像などを使って試してみると良いと思います。