// I lifted this code from brad geilfuss, without his permission, // who presumably lifted this code from someone else, because I know // he didn't write it from scratch. =) // I also modified it to not force 256 square images. // (now it takes any kind of square image) import java.awt.*; import java.io.*; public class FFT{ private final int FORWARD_FFT = -1; private final int REVERSE_FFT = 1; private float direction = (float)FORWARD_FFT; static final float twoPI = (float)(2 * Math.PI); private int N; private int numBits; private int width, height; private float minPSD = 9999999; private float maxPSD = -9999999; public boolean DisplayLogPSD = false; // These arrays hold the complex image data. float[][] cR_r, cR_i; // Red real and imaginary float r_data[] = null; float i_data[] = null; float mag[] = null; private void init() { minPSD = 9999999; maxPSD = -9999999; } public int[] psd(int dim) { // Take PSD on complex RGB values. // Magnitude of result. float[] magnitudeR = magnitudeSpectrum(cR_r, cR_i); double scaleFactor = 100; //255.0/Math.log(256); System.out.println("Max psd = "+maxPSD); scaleFactor = 255.0/(Math.log(1+maxPSD)); System.out.println("Scalefactor = "+scaleFactor); // Adjust 2-D FFT data so that the minimum PSD is // based at a value close to a black pixel. for(int i=0; imax) max = in[i]; return max; } void bitReverse2(){ /* bit reversal */ int n = r_data.length; int j=1; int k; for (int i=1; i=1 && k < j){ j = j - k; k = k / 2; } j = j + k; } // for } void bitReverse(){ /* bit reversal */ int n = r_data.length; int j=1; int k; for (int i=1; i>1; } return ans; } public void forwardFFT(float[] in_r, float[] in_i){ direction = FORWARD_FFT; fft(in_r, in_i); } public void reverseFFT(float[] in_r, float[] in_i) { direction = REVERSE_FFT; fft(in_r, in_i); } /** * FFT engine. */ public void fft(float in_r[], float in_i[]){ int id; // radix 2 number if sample, 1D of course. int localN; float wtemp, Wjk_r, Wjk_i, Wj_r, Wj_i; float theta, tempr, tempi; int ti, tj; // Truncate input data to a power of two int length = 1 << numBits; // length = 2**nu int n=length; // Copy passed references to variables to be used within // fft routines & utilities r_data = in_r; i_data = in_i; bitReverse2(); for(int m=1; m<=numBits; m++) { // localN = 2^m; localN = 1 << m; Wjk_r = 1; Wjk_i = 0; theta = twoPI / localN; Wj_r = (float)Math.cos(theta); Wj_i = (float)(direction * Math.sin(theta)); int nby2 = localN / 2; for(int j=0; j mag[k]) minPSD = mag[k]; if (maxPSD < mag[k]) maxPSD = mag[k]; k++; } } return(mag); } public float[] magnitudeSpectrum(float[] in_r, float[] in_i){ N = in_r.length; float[] mag = new float[N]; for(int i=0; i mag[i]) { minPSD = mag[i]; } } return(mag); } }