octave で画像処理 - 画像の拡大 その 1

そろそろ実際に画像をいじってみよう.

題材

今までの画像はサイズが大きくて処理に時間がかかるので,一部分を切り出してこいつを題材とします.

gaishi.jpg

補間無しでの拡大

まず,補間をしないで画像を拡大してみます. と,いきなり言われても「え?」となると思うので,手順を下に示します.

拡大前     拡大後

□     →  □■
           ■■

元々の画素1つに対し,縦横に(倍率-1)個の黒画素を追加し,画素を水増しします. これだけです.

関数

適当な関数が見つからなかったので,黒画素を追加して拡大する関数を作りました. magnify.m という名前で保存してください.

function y = magnify ( x, m )
  if ndims(x) != 3 
    return;
  endif

  y ( m*rows(x), m*columns(x), size(x,3) ) = 0;

  for d = 1:size(x,3)
    for r = 1:rows(x)
      mr = m*r;
      for c = 1:columns(x)
	y ( mr, m*c, d ) = x ( r, c, d );
      endfor
    endfor
  endfor
endfunction

この拡大処理は行列の積で表現することも可能なはずで,おそらくはそっちのほうが高速に計算できるんだろうけど…

拡大してみる

octave:1> [ x m a ] = imread ( 'gaishi.jpg' );  # 画像をロード
octave:2> x = double ( x ) /255;                # double 型の変数に変換
octave:3> imshow ( x );                         # 元画像を表示
octave:4> x2 = magnify ( x, 2 );                # 2倍に水増し拡大
octave:5> imshow ( x2 );                        # 拡大画像の表示

拡大画像の表示が妙なことになっていると思います. imshow() の表示はあまり綺麗にスケーリングしてくれないようです. あくまでも「プレビュー」だと思ったほうがいいでしょう.

というわけで,拡大した画像をファイルに保存します.

octave:6> imwrite ( x2, 'gaishi_x2.jpg', 'jpg' );

別の画像表示プログラムで表示させると,ちゃんと画素が水増しされているのがわかると思います.

gaishi_x2.jpg

空間周波数領域では

ここでおもむろに,元画像と水増し画像をそれぞれ 2 次元 FFT にかけてみます.

octave:6> y = fft2 ( x );
octave:7> y2 = fft2 ( x2 );

空間周波数領域でのスペクトルを表示させてみます. 前に作った swap2() を使っているので,中央が周波数 0 の点になります.

octave:8> imshow (abs(swap2(y/100)));
gaishi_f.jpg
octave:9> imshow (abs(swap2(y2/100)));
gaishi_x2_f.jpg

水増し画像のスペクトルは,元画像のスペクトルの周囲に余計なスペクトルが現れています. よく見ると,元画像のスペクトルと同じもののようです.

これは「折り返し歪み」とか「エイリアジング」とか呼ばれているものです. こんなに高い空間周波数成分は元画像には含まれていないので,このエイリアジングを除去できれば元画像が綺麗に拡大できるのではないかと考えられます.


添付ファイル: filegaishi_x2_f.jpg 703件 [詳細] filegaishi_f.jpg 656件 [詳細] filegaishi_x2.jpg 679件 [詳細] filegaishi.jpg 686件 [詳細]

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