Tweet


* octave で画像処理 - 空間周波数領域での画像拡大 [#g0225a7b]

ここからは,独自研究色が強くなります.
理屈上は合ってるはずなので,モノの本を見れば多分論じているものはあるはずです.
が,実はその手の本は全く持ってなかったりします.

** 理想のアンチエイリアジングフィルタ [#z8f8d256]

これまでも何度も書いてきましたが,理想のアンチエイリアジングフィルタは
- 元々の空間周波数成分には全く影響を与えず
- エイリアジング成分のみを完全に除去する

というものです.

実は,この様な条件を完璧に満たすフィルタを作ろうとすると,元画像と同サイズの重み付け係数が必要になります.
今までサンプルに使っていた 256 x 256 の画像の場合,重み付け係数のサイズも 256 x 256 になります.

これでは計算量が爆発(O(N^4) になるのかな)してしまうので,現実のフィルタは
- 妥当な計算量で
- 「だいたい」このような条件を満たす

という二律背反な条件の間で妥協の元に設計されている,とも言えます.

** 理想的なスペクトルを捏造 [#r37d525d]

ここで,発想を逆転して
> 理想的なスペクトルが得られないなら捏造すればいいではないか

と考えてみます.

#ref(magnify_sf.png,center)

つまり,手順としては以下のようになります.
+ 元画像を 2 次元 FFT にかけて
+ エイリアジングの周波数領域を 0 で埋めて
+ 2 次元逆 FFT にかける

** やってみる [#zad57746]

空間周波数領域で拡大する関数 magnify_f を作ります.

 function y = magnify_f (x,m)
   r = rows(x);
   c = columns(x);
   r2 = floor(r/2);
   c2 = floor(c/2);
         
   y(m*r,m*c,ndims(x)) = 0;
   for i = 1:ndims(x)    
     y(:,:,i) = [x(1:r2,   1:c2, i ) zeros( r2, (m-1)*c ) x(1:r2,   c2+1:c, i );
                 zeros( (m-1)*r, m*c );
                 x(r2+1:r, 1:c2, i ) zeros( r2, (m-1)*c ) x(r2+1:r, c2+1:c, i ) ];
   endfor
 endfunction

FFT にかけた直後の,並べ替えする前の行列に対して使うように書きました.

 octave:1> [ x m a ] = imread ( 'gaishi.jpg' ); # 画像を読み込んで
 octave:2> x = double (x)/255;                  # 実数型に変換
 octave:3> y = fft2(x);                         # 2 次元 FFT にかけて
 octave:4> y2 = magnify_f(y,2);                 # スペクトルを捏造
 octave:5> x2 = ifft2(y2);                      # 2 次元逆 FFT にかける
 octave:6> imshow (real(x2));                   # 画像のプレビュー

#ref(gaishi2_sf_dim.jpg,center)

ありゃ,全体的に暗いですね.
画素が 4 倍に増えたので,明るさが 1/4 になってしまったようです.
4 倍してみます.
 octave:7> imshow (real(x2)*4);
#ref(gaishi2_sf.jpg,center)

ここらは 2 次元 FFT / 2 次元逆 FFT の定義のしかたに依存するので,別の処理系で計算する場合は「4倍」ではない場合もあります.注意.

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS