画像をフーリエ変換してみる

寄稿:東條遼平

2次元フーリエ変換を使う

縦でも横でもいいのですが,画像の1行もしくは1列を時間で変化する波と考えると画像に対しフーリエ変換をすることができそうです.画像の縦もしくは横がnピクセルであれば,その行や列は

img18.png

の関数の離散値であると考えられそうです.とすれば画像のRGBデータに対し 2次元フーリエ変換を掛けてやることで周波数データにすることができます.フーリエ変換については 1次元フーリエ変換2次元フーリエ変換 を参照してください.

周波数データにしてなにが嬉しいかというと,この変換をすることで 2次元配列は次のような意味を持ちます.

bmpfourier.png

左上が配列の(0,0)右下を配列の(n,n)と考えてください.ざっくりと考えて上の画像で示す中央程,低周波がどれほどの重みを持っているのか,外側程,高周波がどれほどの重みを持っているのかという事になります.そのことを利用すれば様々な事ができるのですが,加工は次に回すとして,今回は変換してそのまま戻すという作業をしたいと思います.ちなみに理論上は可逆変化なので全く元通りになるハズですが,計算途中で誤差が出るため実際には不可逆になります.

   void RgbFrequencyTrans(Image *img, double *re, double *im, int flag)
   {
     int i, j;

     if(flag==DFT){
       for(i=0; i<img->height*img->width; i++){
         re[i] = img->data[i].r;
         im[i] = 0;
       }
     }

     dft_swap2(re, im, img->width, img->height);

     dft_idft2(re, im, img->width, img->height, flag);

     dft_swap2(re, im, img->width, img->height);

     if(flag==IDFT){
       for(i=0; i<img->height*img->width; i++){
         if(re[i]<0) re[i] = 0;
         if(re[i]>255) re[i] = 255;
         img->data[i].r = img->data[i].g = img->data[i].b = re[i];
       }
     }
   }

今回作った関数があまりに短いので全部載せています.既にフーリエ変換部分は完成しているため簡単に実装できました. dft_swap2などについては 2次元フーリエ変換 に詳しく書いています.特に言う事はないのですが,強いて言えば, double型からunsigned char型に変換する際に0から255の間に入るようにしてやる必要があることです.また,今回この関数はヘッダに宣言せずに,ソースファイルの中で宣言しています.これはこの関数がソースファイル内で使う為に作られた関数であることをアピールするためにしています.今回は実際に動かす為にmainで使っていますが,以降は外部からは直接使えないようにstaticを指定することにします.

Valid XHTML 1.1! home > コンピュータ > プログラミング >
リロード   新規 編集 凍結 差分 添付 複製 改名   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Modified by 物理のかぎプロジェクト PukiWiki 1.4.5_1 Copyright © 2001-2005 PukiWiki Developers Team. License is GPL.
Based on "PukiWiki" 1.3 by yu-jiPowered by PHP 5.2.17HTML convert time to 0.025 sec.