MATHGRAM

主に数学とプログラミング、時々趣味について。

Keras tips: 様々な画像の前処理をカンタンにやってくれるkeras.preprocessingのまとめ

Kerasが徐々に流行って来ていると思ってたら、そんなことはなかった。

Qiitaのタグ数。(投稿日)
chainer: 263, TensorFlow: 532, Keras: 41

おいおい、嘘だろ・・・。

メインで使っている僕からするととても悲しいのでもっと普及するようにtips書いて行くことにします。

今回は、preprocessingの中にあるカンタンに画像の前処理をしてくれるメソッドたちのまとめです。

題名にはkeras.preprocessingと書きましたが、正確にはkeras.preprocessing.imageです。

自然言語系の前処理はまとめてません・・・。自分が自然言語処理を本格的にやったことないので・・・。 申し訳ないです、いつかまとめますね。

超重要だけど面倒な前処理もKerasにサクッとやってもらって、もっとカンタンにDeepLearningを楽しみましょう!

※以下のスクリプトは全てjupyterで実行しました。

もくじ

画像の読み込み

まずは基本となる画像の読み込みです。
画像の読み込みはload_img関数を使うことによってカンタンにできます。

以下のように使いましょう。

from keras.preprocessing.image import load_img
img = load_img("ice.jpg")

これでまずRGB画像として画像を読み込めます。裏ではPILが動いているのでRGBの順番です。BGRのOpenCVと共有するときは注意。 imgの出力はこんな感じ。 f:id:ket-30:20161115101035j:plain

読み込みのサイズも指定することができます。多くのモデルは固定幅の画像をinputすると思うのでこの機能は重要です。

img = load_img("ice.jpg", target_size=(300,400))

f:id:ket-30:20161115101751j:plain

さらにRGBではなくグレースケールで読み込むこともできます。

img = load_img("ice.jpg", grayscale=True, target_size=(200,300))

f:id:ket-30:20161115101934j:plain

画像をarrayに変換する

Kerasで画像をニューラルネットにinputする際はnumpyのarray型に変換しなければなりません。

img_to_arrayを使えば読み込んだ画像をカンタンに変換することができます。

from keras.preprocessing.image import load_img, img_to_array
img = load_img("ice.jpg", grayscale=True, target_size=(200,300))

array = img_to_array(img) 

arrayを画像に変換する。

生成モデルなどで出力した、arrayを画像に直す際はarray_to_imgを使いましょう。
img_to_arrayと同じくRGBとして出力します。

from keras.preprocessing.image import load_img, img_to_array, array_to_img
img = load_img("ice.jpg", grayscale=True, target_size=(200,300))
array = img_to_array(img) 

img = img_to_array(array) #上のimgと同じ画像に戻ります。

ニューラルネットにはarrayを255で割ってからinputすることが基本です。そのようなarrayを画像に直すにはscale=Trueとすることで自動で[0, 255]の値に修正してくれます。

from keras.preprocessing.image import load_img, img_to_array, array_to_img
img = load_img("ice.jpg", target_size=(200,300))
array = img_to_array(img) 


array /= 255 
img = img_to_array(array, scale=True) #上のimgと同じ画像に戻ります。

画像をランダムに回転させる

画像の回転はrandom_rotationを使います。
データの水増しをしたいときなどに使えますね。

引数はarrayなので注意。rgには角度の域値を指定します。
中ではnp.random.uniform(-rg,rg)で乱数を生成しているので、一回転全てを許容するときは360と指定します。

from keras.preprocessing.image import load_img, img_to_array, array_to_img, random_rotation
img = load_img("ice.jpg", target_size=(200,300))
array = img_to_array(img) 

rimg = random_rotation(array, rg=360)
ring = array_to_img(rimg)

rimgの出力はこんな感じ。
f:id:ket-30:20161115110518j:plain

画像をランダムにズームする

画像にズームするにはrandom_zoomを使います。
こちらも引数はarrayです。またzoom_rangeに範囲を指定したタプルを渡して使います。

from keras.preprocessing.image import load_img, img_to_array, array_to_img, random_zoom

img = load_img("ice.jpg", target_size=(200,300))
array = img_to_array(img) 

zimg = random_zoom(array, zoom_range=(0.5, 1.0))
zing = array_to_img(zimg)

上のようにzoom_rangeを指定すると、2倍から等倍の間でランダムにズームします。
またheightとwidthに関しても独立でランダムな値をとることに注意です。
カンタンにいうと伸びたり縮んだりしちゃいます。
そのような変換を許容する画像データにのみ使いましょう。

zimgの出力はこんな感じ。
f:id:ket-30:20161115112354j:plain

ちなみにzoom_rangeに1以上の値を指定すると、zoom_outします。 f:id:ket-30:20161115112549j:plain

こんな感じに、縮んだ部分は引き伸ばして出力されます。

画像をランダムにシフトする

画像にズームするにはrandom_shiftを使います。
こちらも引数はarrayです。さらにwrgとhrgには、どの程度シフトするかの倍率の範囲を指定します。 例えばwrgが0.1だった場合、ピクセル幅に0.1がかけられた分だけシフトします。
これらの倍率が指定範囲内でランダムに選択されるという感じです。

from keras.preprocessing.image import load_img, img_to_array, array_to_img, random_shift

img = load_img("ice.jpg", target_size=(200,300))
array = img_to_array(img) 

simg = random_shift(array, wrg=0.1, hrg=0.1)
sing = array_to_img(simg)

上のように指定した場合、 左に20pxから右に20pxの間 上に30pxから下に30pxの間からランダムに数字が選択されシフトします。

simgの出力はこんな感じ。
f:id:ket-30:20161115114457j:plain

これは結構使い所あると思います。

まとめ

いかがだったでしょうか。
今回のまとめを見て、

OpenCV使ってたけどもっとスッキリしたコードで前処理できそう!とか、

他のライブラリで前処理やってたけど今度から前処理もkerasでやっちゃおう!とか、

そもそもOpenCVをインストールができなくて画像処理ができなかってん・・・とか、(これはできるまで頑張った方がいいですがw)

そんな手助けになれたら幸いです。

以上です。

p.s. FCNの記事で予告したオセロ、頑張って作ってます。しばしのお待ちを。