画像処理で遊ぼう!



 画像処理って、大抵のことはPhotoshopでできるんですが、やっぱりちゃんとしたフィルタリングとなるとPhotoshopじゃ難しいです。で、私の場合、MATLABっていう行列演算やビジュアライゼーションツールがあらかじめ用意されているソフトウェアを用いてやってます。

 と言っても、その方法は我流。まともに本を見て勉強したこともちょこっとだけというありさま...。まあ、数学の知識ってのが多少あれば、ある程度までは我流でもできちゃうし、難しいところは全部MATLABがやってくれちゃうってわけなんですけどね(^^;。

 で、Japonaiserie in the United Statesの第3話「FUMIKOってナンデスカ?」で、ちょっとした画像処理をやったんで、それをここで紹介しようってなわけッス。まあ、デジカメでチョー質の悪い画像を撮ったときなんかには役に立つかも知れませんね。

 もっともMATLABってとても個人で買えるソフトじゃないので、あんまり参考にならなかったりして...(笑)



1.画像をMATLABに取り込もう!

 まずは画像をMATLABに取り込んでみましょう。MATLABでもMS-DOSのようにディレクトリがあるんで、まずは画像のあるディレクトリに移動してください。もしくは、デフォルトがMATLABR11(私はVer.5を用いているのでこのディレクトリ)の下のWorkになってますから、そこに画像をコピーした方がいいかもしれません。

 で、画像の取り込み方は簡単。ここではJPEGを例にしますけど、

》 A=imread('fumiko2.jpg');     <<注: '***.jpg'がファイル名

 これだけです(笑)。例えば画像のサイズが256×192なら、行列 A のサイズは256×192×3(R, G, B)のようになります。でも、このへんはあんまり気にしなくてOK。

 もし、画像を表示したければ、

》 image(A)

でOKです。

 で、私が今回画像処理する前のFUMIKOの画像は右の通り。何だか横線がいっぱい入ってますよね。これ、TVの映像をデジカメで撮って、さらに右下のちっちゃいFUMIKOを拡大したんで、走査線だとかデジカメのCCDの画素とTVとのモアレだとか、とにかくいろんなノイズが乗っかっちゃったんです。で、今回は主に、この横線をフィルタリングで除去しようってわけです。

 

2.フーリエ変換しよう!

 こっからは数学の知識が必要です。でも、詳しく知ってる必要はありませんので、さらっと見てもらえばOKです。画像をフーリエ変換すると、「ノイズの成分」ってやつが何となく分かるんですよ。で、ノイズの成分を消してやれば、画像はキレイになるってわけ。

 MATLABにはフーリエ変換が最初から用意されてます。絵をフーリエ変換するときは、絵が2次元なので二次元フーリエ変換ってやつをやるんですが、要は、

》 a=fft2(A);

ってやるだけ。これで a にフーリエ変換したものが入ります。a を表示するときは複素数なんでちょっと注意が必要で、とりあえず私は、

》 image(uint8(fftshift(abs(a))/10));

ってやりました。uint8は0-255の整数に四捨五入するため。fftshiftは無くてもいいです(詳しくは参考書参照)。abs(a)ってのは、複素数の大きさを実数にしてやるもので、10で割ったのはこれも適当。自分で適当にいじって見やすくしてください。

 

3.フィルタ処理しよう!

 さあ、FUMIKOのフーリエ像は右図。白が大きな値なんですが、横線の縞模様ってこのフーリエ像て規則的なパターンになって現れます。右図では、上下にある魚の骨みたいな構造とか、
真中の左上と右下にちょっと出てる太い線とかがたぶん縞模様由来のパターンです。で、大抵、絵のパターンっていうのは、中央付近(周波数成分が高いところ)なので、思い切って真中だけ抜き出しちゃうわけです。このやり方は、参考書を見て自分でやって下さい。分からなければ私にメールしていただいても結構ですが(^^;。

 で、真中だけ抜き取って回りをゼロにしたのが下図。それを元に戻して画像にしたのが、その隣。どうでしょう???

     

 

4.逆フーリエ変換で元に戻そう!

 さてさて、上でお見せしたような元の画像へ戻すのは、このフィルタ処理したものを仮に b とすると、

》 B=ifft2(b);

ってやるだけ。これを逆フーリエ変換と呼びます。これで、B には画像が入ったんですが、コンピュータの数値計算では本来実数に戻るべきものも少し複素数になっちゃうので、さっきの abs(b) ってのを使うのと、また0-255の整数にしなきゃいけないから uint8 ってのを使って、

》 image(uint8(abs(B)));

ってやります。これでMATLAB上でフィルタ処理した画像を見ることができます。横線はほとんど消えましたね。でも、まだ斜め線が入っているのと、少し画像がボケた気がします。これは、斜め線の成分がまだ残っているからで、良く見るとフィルタ処理したフーリエ像の中に斜め線がありますよね。でも、それまで消そうとしてさらに真中の小さな部分だけを抜き取るとどうなるかというと、もっと画像がボケちゃうんです。だから、そこだけピンポイントで成分を消してしまうという技もありますが、MATLABでそこまでやるのは結構大変...てゆーか、我流の私にはそこまで要求しないでチョーダイ、って感じなのね...(--;

 

5.画像ファイルを出力しよう!

 さあ、最後の画像ファイル出力。これはもう簡単もいいところ。

》 imwrite(uint8(abs(B)), 'fumiko_filt.jpg','jpg');

 上のimwriteの引数のうち、最初のやつは先ほどのimageで出力したのと同じ、0-255の整数値を持つ行列。次がファイル名。最後が画像タイプで、他にもBMPなんかも選べます。上はJPEGの例ですが、圧縮率までここで選ぶこともできます。すばらしいッス。

 

6.さいごにおまけ

 さてさて、この記事だけでとても画像処理を理解していただけるなんて思ってませんが、難しいフーリエ変換の部分だけ数学的なバックグラウンドを知っていれば、この程度は本当にやればできるんです。フーリエ変換も、参考書にソースが載っているものもありますし、WEBにも結構転がってます。私も我流でライブラリを作っちゃいました。

 で、私的にはこれを見て「なーんだ、俺だってやれるじゃん!」って思ってくれれば幸いなんですが、そうでない人にはつまらないと思うので、最後におまけをば...

 フィルタ処理で除かれた可哀相なノイズの行方は...!? これも、実はさっきのフィルタ処理の除いた部分だけを同じように絵に戻せば見ることができます(笑)。まあ、かすかなFUMIKOをお楽しみください。

    

 へ、こんなんじゃおまけにならないって...。。゛(ノ><)ゝ ヒィィィ


次へ
掲示板へ テクノロジーの洞窟HOMEへ