2016-12-13 40 views
1

我有下面的代碼使用簡單的算法進行傅里葉變換,但它不像它應該那樣工作。傅立葉變換得到在java中的量級值

public int ft(int x, int y, int br, int a, int height, int width, int[][] pixelTemp, double c){ 
    int r; 
    int g; 
    int b; 
    double avg;  
    double newCitra = 0; 
    int temp; 
    for (int i=0; i<height; i++){ 
     for (int j=0; j<width; j++){ 
      temp = pixelTemp[i][j]; 
      r = (temp>>16)&0xff; 
      g = (temp>>8)&0xff; 
      b = temp&0xff; 
      avg = (r+g+b)/3; 
      if (Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))>0){ 
       if(-2*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))>0){ 
        newCitra = ((newCitra + (((double)avg/(double)(height*width)))*(sqrt(Math.pow((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))),2)+Math.pow((double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))),2))))); 
       } else { 
        newCitra = ((newCitra + (((double)avg/(double)(height*width)))*(sqrt(Math.pow((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))),2)-Math.pow((double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))),2))))); 
       }      
      } else { 
       if(-2*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))>0){ 
        newCitra = (newCitra + ((double)avg/(double)(height*width))*((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))))+(double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))))); 
       } else { 
        newCitra = (newCitra + ((double)avg/(double)(height*width))*((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))))-(double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))))); 
       } 
      } 
      /*System.out.println(newCitra);*/ 
     } 
    } 
    newCitra = (int) (Math.log(1+newCitra)*c); 
    int j = 30; 
    int i = 10; 
    /*System.out.println(Math.abs(sqrt(Math.pow((Math.cos(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width))))),2)-Math.pow((double)Math.sin(Math.toRadians(360*(((double)(i*x)/(double)height)+((double)(j*y)/(double)width)))),2))));*/ 
    int p = (255<<24) | ((int)newCitra<<16) | ((int)newCitra<<8) | (int)newCitra; 

    return p; 
} 

這是以下結果:

enter image description here

很顯然,我在這裏做了一些錯誤,但我無法弄清楚,在開方根值可以爲負,這將導致NaN的但我遵循傅里葉變換公式。

+0

您可以指向公式? – gpasch

回答

1

顯然你錯誤地解釋了公式。從另一個實現我

real += tempreal[row][t] * cos[col][t] - tempimag[row][t] * sin[col][t]; 
imag += tempreal[row][t] * sin [col][t] + tempimag[row][t] * cos[col][t]; 

所以一旦你擁有的實部和虛部你做的平方根

mag=Math.sqrt(real*real+imag*imag); 

另外在餘弦/正弦

cos[i][t]=Math.cos(2*Math.PI*t*i/n); 
sin[i][t]=Math.sin(2*Math.PI*t*i/n); 

我沒有看到一個平方而不是雙倍。

-

我已經更新了你的功能如下:

一)實部和虛部需要單獨計算,不存在計算上的複數 二)一些變換

它似乎工作,如果您嘗試使用這裏顯示的圖像http://homepages.inf.ed.ac.uk/rbf/HIPR2/fourier.htm對角線條紋,您將獲得該頁面上顯示的對角線。

public double ft(int x, int y, int br, int a, int height, int width, int[][] pixelTemp, double c){ 
    int r; 
    int g; 
    int b; 
    double avg;  
    double newCitrar = 0, newCitrai = 0; 
    int temp; 
    double f=(double)1/(double)(height*width); 
    for (int i=0; i<width; i++){ 
     for (int j=0; j<height; j++){ 
      temp = pixelTemp[i][j]; 
//   r = (temp>>16)&0xff; 
//   g = (temp>>8)&0xff; 
//   b = temp&0xff; 
      avg = temp; // (r+g+b)/3; 
     newCitrar = newCitrar + avg*Math.cos(2*Math.PI*(((double)(i*x)/(double)width)+((double)(j*y)/(double)height))); 
     newCitrai=newCitrai+avg*Math.sin(2*Math.PI*(((double)(i*x)/(double)width)+((double)(j*y)/(double)height))); 
     } 
    } 
    newCitrar *=f; 
    newCitrai *=f; 
    double newCitra=Math.sqrt(newCitrar*newCitrar+newCitrai*newCitrai); 
    return newCitra; 
} 

在顯示方面,我有以下:

BufferedImage bim=null; 
    try { 
    bim=ImageIO.read(new File("str.gif")); 
    } 
    catch (Exception ex) { System.err.println("error"); } 
    int wc=bim.getWidth(), hc=bim.getHeight(); 
    BufferedImage b2=new BufferedImage(wc, hc, BufferedImage.TYPE_INT_RGB); 

    int[] pix=bim.getRGB(0, 0, wc, hc, null, 0, wc); 
    int[][] pix2=new int[wc][hc]; 
    double ri; 
    for(i=0; i<wc; i++) 
    for(j=0; j<hc; j++) { 
    int rr=(pix[i+j*wc]&0x00ff0000)>>16, rg=(pix[i+j*wc]&0x0000ff00)>>8, rb=pix[i+j*wc]&0x000000ff; 
    ri=0.2126*rr+0.7152*rg+0.0722*rb; 
    pix2[i][j]=(int)ri; 
    } 
    double max=0; 
    for(i=0; i<wc; i++) 
    for(j=0; j<hc; j++) { 
    if(i%10==0 && j%10==0) System.out.println(i+" "+j); 
    double ki=ft(i, j, 0, 0, hc, wc, pix2, 1); 
    if(ki>max) max=ki; 
    b2.setRGB(i, j, (int)ki); 
    } 
    saveImageIO(b2, (time/1000)+"f-1"); 

    double cc=255./Math.log(1+max); 
    System.out.println(max+" "+cc); 
    for(i=0; i<wc; i++) 
    for(j=0; j<hc; j++) { 
    b2.setRGB(i, j, (int) (Math.log(1+(b2.getRGB(i, j)&0x00ffffff))*cc)); 
    } 

    saveImageIO(b2, (time/1000)+"f-2"); 
+0

在'avg =(r + g + b)/ 3;'中,'avg'被聲明爲'double',但賦予了'int'計算的結果,這將刪除任何小數部分。 –

+0

和??公式是否正確?你在說什麼? 3而不是3.3?你在說虛假! @Lew Bloch – gpasch

+0

@LewBloch您的評論是關於Asker自己的代碼。你在錯誤的地方輸入了這個嗎? –