最近画像認識について勉強中です。とりあえず、数式で理解した後スクラッチで書いてみるのが一番早いかなと思ったので、読んだ傍からRで書いています。
画像認識始めました~手始めにRでスクラッチでフィルタリングしてみた~ - バナナでもわかる話
画像認識始めました~ガウシアンフィルタをRで実装してみた - バナナでもわかる話
参考本はこれ。
前回はガウシアンフィルタを使って前に撮ったイグアナちゃんをフィルタリングしたわけなんですけど、
今回はバイラテラルフィルタでやってみます。
スポンサーリンク
バイラテラルフィルタ
ガウシアンだと、各画素に対して均等に均していくことになるわけですが、これだと境界領域も均してしまうことになります。
そこで、画素の差にも考慮して重みづけしてやろうというのがこのフィルタです。
早速Rでコードを書いてみました。
#k個周りのバイラテラルフィルタ k=40 #位置の分散 sigma=3 #画素の分散 sigmar=3 #imageに画像を挿入する(前記事参照) #あとは実行するだけ image5=array(0,dim=c(dim(image)[1],dim(image)[2],3)) bira=function(mat=matrix(),ii,jj,kk,sigma,sigmar){ mid_gaso=mat[i,j,] zzz=mat[max(1,(ii-kk)):min(dim(image)[1],(ii+kk)),max(1,(jj-kk)):min(dim(image)[2],(jj+kk)),] hajix=max(1,(ii-kk)) hajiy=max(1,(jj-kk)) idox=1-hajix idoy=1-hajiy midPointx=ii+idox midPointy=jj+idoy Dim_matx=matrix(1:dim(zzz)[1],dim(zzz)[1],dim(zzz)[2])-midPointx Dim_maty=t(matrix(1:dim(zzz)[2],dim(zzz)[2],dim(zzz)[1]))-midPointy ggg=matrix(0,dim(zzz)[1],dim(zzz)[2]) for(iii in 1:dim(zzz)[1]){ for(jjj in 1:dim(zzz)[2]){ ggg[iii,jjj]=exp(-(Dim_matx[iii,jjj]^2+Dim_maty[iii,jjj]^2)/(2*sigma^2)-sum((zzz[iii,jjj,]-mid_gaso)^2)/(2*sigmar^2)) } } ggg } for(i in 1:(dim(image)[1])){ for(j in 1:(dim(image)[2])){ GG0=bira(mat=image,ii=i,jj=j,kk=k,sigma=sigma,sigmar=sigmar) GG=array(GG0,dim=c(dim(GG0)[1],dim(GG0)[2],3)) zzz=image[max(1,(i-k)):min(dim(image)[1],(i+k)),max(1,(j-k)):min(dim(image)[2],(j+k)),] W=sum(GG0) image5[i,j,]=(1/W)*apply((GG*zzz),3,sum) } }
出力結果
もとのやつ
かなりノイズが減って滑らかになっているのがわかるでしょうか。
こうやってノイズを消すんですね~。
次回はエッジの検出をやっていきます。