線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:7974
推到 Plurk!
推到 Facebook!

快速傅立葉轉換和反轉換的問題( FFT IFFT)

尚未結案
senboy
一般會員


發表:18
回覆:7
積分:5
註冊:2005-01-07

發送簡訊給我
#1 引用回覆 回覆 發表時間:2005-04-08 22:05:15 IP:140.113.xxx.xxx 未訂閱
我的FFT程式如下,在做轉換FFT和IFFT後,64x64 256x256 512x512 的圖都可正常轉過去再反轉回來 但是就是 128x128的轉回來後會有問題,不知道是哪些錯, 其他圖片也是一樣,只要碰到 128轉回來都有問題 麻煩各位高手幫忙看一下,謝謝
#ifndef FFT2D_H
#define FFT2D_H
#include "IPMatrix.h"
#define Pi 3.14159265358979323846
//---------------------------------------------------------------------------
void FFT1D(double* ar, double* ai,int n,int isign)
{
     double  u_r,u_i,w_r,w_i,t_r,t_i;
     int i,j,k,m,ip;
     int ln,n2,stepN,stepN2;
     //resort
     n2 = n / 2;
     j = 1;
     for (i = 1; i < n; i++ )
      {
       if (i < j)
        {
         t_r = ar[i - 1];
         t_i = ai[i - 1];
         ar[i - 1] = ar[j - 1];
         ai[i - 1] = ai[j - 1];
         ar[j - 1] = t_r;
         ai[j - 1] = t_i;
        }
       k = n2;
       while (k < j)
        {
         j = j - k;
         k = k / 2;
        }
       j = j + k;
      }         //
     ln = log(n)/log(2);
     stepN=1;
     for (k = 1; k <= ln; k++) /* loops thru stages */
      {
       stepN*= 2;
       stepN2=stepN / 2;
       w_r = cos(Pi/(double)stepN2 );
       w_i = isign*sin(Pi/(double)stepN2 );
       u_r = 1.0;
       u_i = 0.0;
       for (m = 1; m <= stepN2; m++) /* loops thru 1/2 twiddle values per stage */
        {
         for (i = m; i <= n; i += stepN) /* loops thru points per 1/2 twiddle */
          {
           ip = i + stepN2;
           t_r = ar[ip - 1] * u_r - u_i * ai[ip - 1];
           t_i = ai[ip - 1] * u_r + u_i * ar[ip - 1];               ar[ip - 1] = ar[i - 1] - t_r;
           ai[ip - 1] = ai[i - 1] - t_i;               ar[i - 1] =  ar[i - 1] + t_r;
           ai[i - 1] =  ai[i - 1] + t_i;
          }
         t_r = u_r * w_r - w_i * u_i;
         u_i = w_r * u_i + w_i * u_r;
         u_r = t_r;
        }
      }
     if(isign==-1)
      {
       for (i = 0; i < n; i++ )
       {
        ar[i]/=n;
        ai[i]/=n;
       }
      }
}    //---------------------------------------------------------------------------
void MatrixFFT2D(LMatrix &Or, LMatrix &Oi, LMatrix &Ir, LMatrix &Ii, int isign)
{
     int H = Ir.RowNo();
     int W = Ir.ColNo();         double* RowReal=new double[W];
     double* RowImag=new double[W];
     double* colReal=new double[H];
     double* colImag=new double[H];         //do for Row        
     for (int i=0;i    block 64 & IFFT
 
block 64 FFT

block 128 

block 128 FFT

block 128 IFFT 轉回來有錯

block 256 & IFFT

block 256 FFT

U128

U128 FFT

U128 IFFT 轉回來有錯
    發表人 - senboy 於 2005/04/08  22:17:19    發表人 - senboy 於 2005/04/08  22:19:22
        
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2005-04-09 09:16:12 IP:211.76.xxx.xxx 未訂閱
您的 FFT 應該沒有作好喔...    http://delphi.ktop.com.tw/topic.php?topic_id=60207
引言: 關於 FFT, 以一般的圖片, 作出來應該都是低頻較強, 所以在中間有 peak, 而您應該也使用了 DyanmicRangeCompression S(r) = c * log( 1 | r | ) 的方式來處理 FFT 後的資料, 否則應該只有中心一個亮點, 因為其他相對中心 都太小了,所以您應該很接近完成了才是。 以下是我以前作業的可執行檔的連結, 提供您參考 http://free.greenworld.com.tw/~dllee/leesoft/imagep.zip (功能很陽春,只能處理固定的256x256灰階BMP影像,而且如果螢幕使用低於32位元的色彩解析度還會失真,而程式自己已經不太能看懂... ) < face="Verdana, Arial, Helvetica"> 看您 post 的圖, 似乎是已作了 DyanmicRangeCompression, 但好像沒有 在一開始先作 FFT Translation, 就是將 image 乘上 (-1)^(i j) 的運算。 吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ KTOP OpenPLC - IEC 61131-3 geOShell XP Like 中文版
------
http://www.ViewMove.com
senboy
一般會員


發表:18
回覆:7
積分:5
註冊:2005-01-07

發送簡訊給我
#3 引用回覆 回覆 發表時間:2005-04-09 13:11:38 IP:140.113.xxx.xxx 未訂閱
嗯,我知道 image 乘上 (-1)^(i+j) 的運算是將低頻移到中心, 但那好像是為了將影像show出來好看所以才須要這麼做,反轉換後還要在乘(-1)^(i+j)回來,因為我只是要將圖轉到Frequency domain上做處理再轉回來, 所以就都沒做(-1)^(i+j),因此低頻在四個角落... 我有試過加上(-1)^(i+j),可得到和您一樣的結果, 可是....還是掛在 128x128........ src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=21499044&CC=480816"> 128 FFT 128 iFFT
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#4 引用回覆 回覆 發表時間:2005-04-09 21:27:58 IP:211.76.xxx.xxx 未訂閱
不知道您有沒有注意到, 您的 128 似乎多算或少算了幾次, 因為 128 的 FFT 圖似乎在高頻及低頻的強度是一樣的, 正常 FFT 完會是像  ●●◎●● ●◎⊙◎● ◎⊙○⊙◎ ●◎⊙◎● ●●◎●●    而您的 128 作出來像是    ○⊙○⊙○ ⊙●⊙●⊙ ○⊙○⊙○ ⊙●⊙●⊙ ○⊙○⊙○    ○最亮(能量最高) ⊙亮 ◎暗 ●最暗(能量最低)    很像是這題 http://delphi.ktop.com.tw/topic.php?topic_id=60207 一開始作出來的一樣,會有 pattern 重覆的問題。    FFT 的程式麻煩在於不易除錯,因為有時域(空間域)←→頻域的轉換, 又有虛數的問題,沒有適當的整理及轉換,很難看出有什麼問題。    吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ KTOP OpenPLC - IEC 61131-3 geOShell XP Like 中文版
------
http://www.ViewMove.com
m58610
初階會員


發表:22
回覆:83
積分:36
註冊:2003-09-07

發送簡訊給我
#5 引用回覆 回覆 發表時間:2005-04-10 01:20:27 IP:211.74.xxx.xxx 未訂閱
dllee你好 我最近都在寫DFT與IDFT的程式 想請問一下DyanmicRangeCompression的大略演算法 能否提示我一些 因為我現在用的是 1. log(1 F) 2. 取max與min後作內插法到0~255之間 但是這樣還不一定是最佳顯示的算式 只能說對於某些圖片來說是比較好的
senboy
一般會員


發表:18
回覆:7
積分:5
註冊:2005-01-07

發送簡訊給我
#6 引用回覆 回覆 發表時間:2005-04-10 15:37:59 IP:140.113.xxx.xxx 未訂閱
嗯,在試了好幾次後,發現果然是少算了一次 問題出在 ln = log(n)/log(2); n=128時 ln會得到6 不過,這種數值運算的錯誤,沒遇到過,還真不容易被發現....
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#7 引用回覆 回覆 發表時間:2005-04-11 05:40:08 IP:211.76.xxx.xxx 未訂閱
引言: dllee你好 我最近都在寫DFT與IDFT的程式 想請問一下DyanmicRangeCompression的大略演算法 能否提示我一些 因為我現在用的是 1. log(1 F) 2. 取max與min後作內插法到0~255之間 但是這樣還不一定是最佳顯示的算式 只能說對於某些圖片來說是比較好的
在那個作業中,我也是使用: DyanmicRangeCompression S(r) = c * log( 1 | r | ) 我有想過,其實應該可以自己發明類似的演算法, 主要就是把範圍 order 式的變小,因為影像的低頻占多數能量, 最簡單的方法就是一樣用 DyanmicRangeCompression 但中心點(低頻) 不參與,最後中心點直接給 255 灰階就對了,這樣,就不會因為整張 圖因中心點的數值實在是太大而變得很暗。 to senboy: 因為您的程式看起來實是幾乎是對的,我唯一不能確認的就是那個 ln 只是 按數學公式 Log2N 的算法是可以用 LogN/Log2... 也許是浮點轉整數的問題, 或許作個四捨五入的動作就 OK 了。 吃軟也吃硬 dllee.ktop.com.tw StatPlus 系統資源監測器 @ KTOP OpenPLC - IEC 61131-3 geOShell XP Like 中文版
------
http://www.ViewMove.com
系統時間:2024-05-13 21:54:09
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!