Reputation: 13
I have the following code that use simple algorithm for fourier transform, but it not working like it should.
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;
}
This is the following result:
Obviously I made some mistake here, but I couldn't figure it out, the value in sqrt root can be negative that will result NaN but I am following the fourier transform formula.
Upvotes: 1
Views: 163
Reputation: 2682
Obviously you have misinterpreted the formulas. From another implementation I have
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];
So once you have the real and imaginary parts you do the square root
mag=Math.sqrt(real*real+imag*imag);
Also in the cosine/sine
cos[i][t]=Math.cos(2*Math.PI*t*i/n);
sin[i][t]=Math.sin(2*Math.PI*t*i/n);
I dont see a square rather a doubling.
--
I have updated your function as follows:
a) the real and imaginary parts need to be computed separately, there is no computation on the complex number b) some rearrangements
It seems to work and if you try with the image shown here http://homepages.inf.ed.ac.uk/rbf/HIPR2/fourier.htm the diagonal stripes you will get the diagonal as shown on that page.
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;
}
On the display side I have the following:
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");
Upvotes: 1