octave で画像処理 - 2 次元 FFT

octave での画像の読み書きができたところで,カッ飛ばしていきます.

2次元 FFT

ここで 2 次元 FFT について説明します.

2DFFT.png

まず,元の画像を横方向に1ラインずつ抜きだし,(1次元の)FFT をかけます. それらを寄せ集め,今度は縦方向に1ラインずつ抜きだし,FFT をかけ,寄せ集めます. この結果が 2 次元 FFT となります.

なお,横→縦と1次元 FFT を実行しても縦→横と1次元 FFT を実行しても同じ結果になることが知られています.

2 次元逆 FFT も同様に定義されます. こちらでも「横→縦」の逆変換でも「縦→横」の逆変換でも同じ結果になることが知られています.

octave では

octave では fft2(), ifft2() という関数で2次元 FFT・2次元逆 FFT を行うことができます.

octave:119> [ x, m, a ] = imread ( 'DSCF0135.JPG' );  # 画像ファイルを読み込み
octave:120> y = fft2 ( x );                           # 2次元 FFT の実行
octave:121> xx = ifft2 ( y );                         # 2次元逆 FFT の実行

実際に 2 次元 FFT をやってみる

理屈をグダグダ言っててもつまらないので,実際にやってみます. 画像はこんなやつを使ってみました.

DSCF0135.JPG

まずは画像ファイルを読み込んで

octave:26> [ x, m, a ] = imread ( 'DSCF0135.JPG' );

2 次元 FFT を実行します.

octave:27> y = fft2(x);

FFT では複素数で波の位相を表していますが,そのままでは表示に無理があるので,絶対値 ( √(Re^2 + Im^2) ) で画像にして表示してみます.

octave:28> imshow ( abs(y));

む,画像が真っ白だ.値が大きすぎてサチってるようです. 値を適当にスケーリングします. いろいろ試行錯誤したら,100000 で割ると,何となくいい感じのようです.

octave:29> imshow ( abs(y)/100000);

こんな感じの画像が表示されます.

fft2.jpg

左上 1/4 が周波数成分(の大きさ)で,右上,左下,右下には横方向・縦方向のエイリアジングが現れています. 1 次元の FFT のときのように,これらは負の周波数の成分,という見かたもできます.

というわけで,十文字に4等分して,上下左右を入れ替えてみます. が,そういう関数が見つからなかったので,適当に作ってみました. swap2.m という名前で保存すると,octave 上から swap2 (x) のように呼び出すことができます.

function y = swap2 ( x )
  r = rows(x);
  c = columns(x);
  r2 = floor(r/2);
  c2 = floor(c/2);

  y = [x(r2+1:r, c2+1:c, : ) x(r2+1:r, 1:c2, : );
       x(1:r2,   c2+1:c, : ) x(1:r2,   1:c2, : ) ];
endfunction

使ってみます.

octave:33> imshow ( abs(swap2(y))/100000 );

こんな感じの画像が表示されます. 画像の中央が低い周波数成分で,端に行くほど高い周波数成分を表しています.

fft2_swap.jpg

添付ファイル: filefft2_swap.jpg 1008件 [詳細] filefft2.jpg 991件 [詳細] fileDSCF0135.JPG 1096件 [詳細] file2DFFT.png 1013件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-04-04 (日) 10:30:12 (3855d)