バナナでもわかる話

計量経済学・統計学が専門の大学院生です。統計学・経済学・投資理論・マーケティング等々に関する勉強・解説ブログ。ときどき趣味も。極力数式は使わずイメージで説明出来るよう心掛けていますが、時々暴走します。

画像認識始めました~手始めにRでスクラッチでフィルタリングしてみた~

なんか、最近自動運転だなんだと画像認識が流行りらしくて、私画像認識についてはあまり詳しくないので入門の為に買ってみました。

で、まだ全部は読んではいないのですが、とりあえず読んだ傍からスクラッチでコードを書いてみようかと思ってるわけです。

スポンサーリンク



空間フィルタリング

まず、何をするのかというと、画像認識をするためには色々画像から特徴を取り出したいというモチベがあるようで、でも特徴を取り出す前に元の画像だと細かすぎるというか、ざっくりいってしまうとノイズが多いので、画像を均すという処理をする必要があるようです。

その処理がフィルタリング


で、そのフィルタリングにもいっぱい種類があるとのことで説明してあったのですが、とりあえず手始めに平均化フィルタというものを試してみたいと思います。

平均化フィルタっていうのは何かというと、

画像データって縦横に色を示す値が並んだ行列のように表すことが出来るんですけど(正確には配列)

周りの色のデータと共に平均を取って均してやろう(平滑化,スムージング)と言う処理を取ります。

早速Rコード

画像の読み込みだけは流石にスクラッチではよくわからないというか、そんなとこで努力する意味も無いので、jpegパッケージで読み込みます。

install.packages("jpeg")
library(jpeg)
image=readJPEG("DSC_0004.JPG")

元画像DSC_0004.JPGは何かというと、この間記事であげたイグアナちゃんです。
f:id:bananarian:20181120002450p:plain


というわけで平均して均してノイズを取ります。

#平均を取る幅
k=1
image2=array(0,dim=c(dim(image)[1],dim(image)[2],3))
for(i in 1:(dim(image)[1])){
	for(j in 1:(dim(image)[2])){
		zzz=image[max(1,(i-k)):min(dim(image)[1],(i+k)),max(1,(j-k)):min(dim(image)[2],(j+k)),]
		image2[i,j,]=apply(zzz,3,mean)
}}

ということで均した結果
f:id:bananarian:20181120002846p:plain

均す前
f:id:bananarian:20181120002450p:plain

あんまわからないですかね。微妙に色薄くなってます笑
k=1だからあんまりわからないですね~
恐らくこの平均化する周辺の範囲を拡大することでどんどん荒い画像になっていくはずです。

ためしに5でもやってみます。

k=5
image3=array(0,dim=c(dim(image)[1],dim(image)[2],3))
for(i in 1:(dim(image)[1])){
	for(j in 1:(dim(image)[2])){
		zzz=image[max(1,(i-k)):min(dim(image)[1],(i+k)),max(1,(j-k)):min(dim(image)[2],(j+k)),]
		image3[i,j,]=apply(zzz,3,mean)
}}

均した結果
f:id:bananarian:20181120014508p:plain

均す前
f:id:bananarian:20181120002450p:plain

手のあたりとか見ると結構荒いというか滑らかになってるのがわかりますね。
あと顔のあたりとか。

こんな風に元の画像のノイズを取ってから処理する必要があるみたいですね。
次回はまた別のフィルタリングを試してみます。