アプリとサービスのすすめ

アプリやIT系のサービスを中心に書いていきます。たまに副業やビジネス関係の情報なども気ままにつづります

機械学習(ディープラーニング)画像認識・処理のための画像データ数値化&増やし方

今回は機械学習ディープラーニング)で画像データを収集し、それを増やす方法について書きます。

最終的にはDCGANで何かしら作成することを考えており、今回はDCGANのデータセットとして「より少ない手間で、よりたくさんのデータを作成する」をモットーに、画像データ収集法とそのデータを増やす方法(人工データ合成)をまとめておこうと思います。

目次
・画像データ収集方法
・画像のリサイズとラベル付け
・画像データを増やす方法

f:id:trafalbad:20170705152452j:plain



画像データ収集方法
画像のURLを集める
まず画像を集めるために、どっかしらのサイトからwebスクレイピングで画像のURLを収集します。一般的なサイトから画像のURLを取得する方法で、方法はいくつかある。
1.手作業で集める
2.サイトからスクレイピングする
3.Google Custom Search APIで画像を取得する

自分は手作業で集めました。スマホでポンポン保存して、AirDropでPCに送った。2のサイトからスクレイピングは限定的なので、3のGoogle Custom Search APIでのGoogle検索した画像をスクレイピングする方法がメジャーなようです。


ただ画像に著作権がある場合は、慎重になった方が良さそうです。

今回はスクレイピングした画像のURLを取得するケースを考えます。URLから画像を一括で取得するので、フォルダにURLの一覧を保存して、まとめておきます。



URLを画像に戻す
次はターミナルコマンドでフォルダのURLを画像に戻します。ターミナルから、

ls  
cd [保存場所]

でフォルダの場所に移行したら、下記のコマンドを入力します。

cat フォルダ名 | wget -I -

これでフォルダ内のURLが画像に変換され、downloadsに保存されます。一枚一枚保存されますので、新たなフォルダを作って保存し直します。


画像のリサイズとラベル付け


macで画像のリサイズ
次は画像の大きさがバラバラなので、縦、横を同じの正方形にして、好きなサイズにリサイズ。

今回は見やすさも考えて、128×128pxにしました。opencvpythonでリサイズもできますが、mac OSにフォルダ内のデータを一括してリサイズする機能が付属していますので、こちらを使います。

詳しくはこの記事を参照
これでフォルダ内の画像は一括してリサイズされます。



画像のラベル付けについて
画像にラベル付けする作業はとても面倒くさいので、それを簡単にする方法がいくつかあります。

方法1.ruby on railsのアプリを用いた方法
ruby on railsで画像を見ながらラベルをつけるアプリを作成しました。

trafalbad.hatenadiary.jp


画像を確認しながらラベル情報を入力するというのは普通は無理なんですが、それ用のrailsアプリを作った。

画像収集のレギュラーな方法としては、webスクレイピング→ラベル付けの順番でやるのが普通だと思います。


方法2.DCGANで同一カテゴリの画像を生成する方法
これはイレギュラーな方法です。今度試そうと思ってるんですが、DCGANでラベルのカテゴリ毎の画像を作成させる方法です。ラベルの種類が10個あったら、カテゴリ毎にDCGANに画像(つまり10種類の画像)を生成させ、データを増やそうと言うわけです。

まず少量のデータセットをカテゴリ別に作り、次にDCGANでカテゴリ別の画像を大量に作成させます。




こちらは実際にやってる人は見たことないんですが、DCGANの使い方としては非常に有能ではないかと思ってます。なぜなら、ラベル付けも必要ないし、データ収集も少量で済むからです。

本記事ではこの方法は触れませんが、別記事でDCGANの活用方法としてデータセットを増やすことについて触れたいと思ってます。



画像データを増やす方法
画像のデータが集まったら画像を増やしていきます。具体的にはopencvで左右反転させたり、色彩を淡くしたりする方法。画像をベクトルに変換することで、機械学習のデータとしては十分、学習データに値するものになります。


opencvで画像を数値化
まず、opencvのインストール(方法はこちらを参照)。フォルダ内の相対パスを取得して、画像を数値に変換します。

from PIL import Image
import os
import _pickle as cPickle
import os
import sys
import pickle
import numpy as np
import cv2, matplotlib
import numpy as np
import matplotlib.pyplot as plt

path1="フォルダパス"
images = os.listdir(path1)#画像の読み込み
img_batch=[]
for i in images:
    img_batch.append(cv2.imread(path1+'/'+i))#フォルダ内の画像を数値化

今回は変換した画像は300枚。各画像は(128, 128, 3)の形式です。画像を表示するときには、そのまんまmatplotlibで表示できます。



画像の増やす
変換した画像300枚を元手に画像を増やして行きます。今回はQiitaの画像水増しテクニックを使います。opencvで淡くしたり、することもできますが、画質が粗くなるケースがあるので、画像の質を保ちながら画像を増やすテクニックを使います。

方法はねずみ算式に増やしていきます。まず素画像300枚に反転をかけ、600枚に増やします。次に600枚にコントラスト調整をかけ、1200枚にします。この方法でねずみ算式に増やし、200枚の画像を、5000枚に増やすことができました。

本当はもっと増やせたんですが、128pxだと見易さの兼ね合いから平滑化など、の処理は省きました。
画像が見やすいものならQiitaの記事の通りにやって次のようにねずみ算式に300枚の画像を18000枚に増やして問題ないはずです。

コントラスト調整(300×2)
Salt&Pepperノイズ(600×2)
ガンマ変換(1200×2)
平滑化(2400×2)
ガウス分布に基づくノイズ(4800×2)
反転(9600×2)

最後に「反転」をかけるのがコツです。こうすることで、より多くの画像の鮮明度を保持することが可能になります。
ちなみに「角度変換」をかけることで「反転」と同じ効果が得られます。「角度変換」は値を変えると何回も使えるので2倍に増やすには本当に便利。

rad=np.pi/220 # 角度変換
# distance to move to x-axis
move_x = 0
# distance to move to x-axis
move_y = 96 * -0.00000000000000006
 
matrix = [[np.cos(rad),  -1 * np.sin(rad), move_x], [np.sin(rad),   np.cos(rad), move_y]]
 
affine_matrix3 = np.float32(matrix)
px_size=(96,96)
afn=[]
for i in seen10000:
    afn.append(cv2.warpAffine(i, affine_matrix3, px_size, flags=cv2.INTER_LINEAR))


matplotlibで64枚を可視化してみる

tensorflowでも複数の画像をまとめて表示する方法があります。今回はそれを真似てnumpyとmatplotlibを使って可視化。


今回は元画像64枚一気に表示します。



f:id:trafalbad:20170930141735p:plain


今のところはどんな画像かを確認するためのもの。なので、そんなに凝らなくていいと思ったので64枚一気に表示させてみました。

iti=t_image[160:230]
col=8
rows = []
for i in range(8):
    rows.append(np.hstack(iti[col * i + 0:col * i + col]))
plt.imshow(np.vstack(rows))
plt.show() #淡くしたの64枚可視化



今回は画像のデータを収集&増やす方法を書きました。まあopencvを使えば簡単なのですが、案外まとめてあるサイトがなかったのでまとめました。


この画像を元にDCGANで何かしてみようと思ってます。特にデータセットを増やすことができたら、かなり有用性があるのではと思いますが。そこら辺も含めてDCGANについてはまた別記事で書くつもり。