package edu.tjhsst.imagedeblur.fourierTransform.core; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; import javax.swing.SwingWorker; import org.jscience.mathematics.number.Complex; import edu.tjhsst.imagedeblur.fourierTransform.FourierTransformMain; import edu.tjhsst.imagedeblur.fourierTransform.gui.JFourierProgressBar; /** * The Task that performs the Discrete Fourier Transformation. Extends the * SwingWorker class in order to prevent the GUI from becoming unresponsive as * the code runs. The FourierTransformation is caculated for * (-width/2,-height/2) to (width/2, height/2). * * @author Peter Chapman */ public class CreateFourierTransformTask extends SwingWorker { /** * The {@link FourierPixelImage} that the class will output the Fourier * Transformation to. */ FourierPixelImage fourierTransfromImage; /** * The progress bar for the transform. */ JFourierProgressBar bar; /** * This method performs the Fourier Transformation in the background so that * the GUI functions uninterrupted. * * @return A String that equals "Complete". */ @Override public String doInBackground() { try { File imageFile = FourierTransformMain.getImageFile(); BufferedImage image = ImageIO.read(imageFile); PixelImage pixelImage = new PixelImage(image); FourierTransformMain.getPanel().displayImage(pixelImage); FourierTransformMain.getPanel().updateUI(); bar = new JFourierProgressBar(pixelImage.getHeight()); FourierTransformMain.setPixelImage(pixelImage); fourierTransfromImage = new FourierPixelImage(image); createFourier(pixelImage, fourierTransfromImage); done(); return "Complete"; } catch (Exception e) { e.printStackTrace(); FourierTransformMain.displayError("Render failed: " + e.getMessage() + e.getStackTrace()); return "Falied"; } } /** * Updates the {@link JFourierProgressBar}. * * @param row * The row of the image that the transformation is currently * processing. */ public void process(Integer row) { bar.process(row); } /** * Run once the transformation is complete. The method updates the * {@link FourierPixelImage}, closes the progress bar, and displays the * Fourier Transformation. */ @Override public void done() { fourierTransfromImage.update(); bar.setVisible(false); FourierTransformMain.getMenu().getMenu().enableCreateTransformButton(); FourierTransformMain.getPanel().displayImage(fourierTransfromImage); FourierTransformMain.getPanel().updateUI(); } /** * Runs through the image and calculates the FourierTransformation at each * pixel. * * @param originalImage * The {@link PixelImage} of the original image. * @param fourierTransform * The {@link FourierPixelImage} of the Fourier Transformation. */ public void createFourier(PixelImage originalImage, FourierPixelImage fourierTransform) { int height = originalImage.getHeight(); int width = originalImage.getWidth(); for (int u = -height / 2; u < height / 2; u++) { process(new Integer(u + height / 2)); for (int v = -width / 2; v < width / 2; v++) fourierTransform.setPixel(u + (height / 2), v + (width / 2), findFourierPixel(u, v, originalImage)); } } /** * Caculates the magnitude of the point in the frequency domain. In other * words, finds the Fourier Transformation for a single point. * * @param u * The X value of the point to be caculated. * @param v * The Y value of the point to be caculated. * @param originalImage * The orignal image. * @return The double of the magnitude of the complex number created by the * Fourier Transformation. */ private double findFourierPixel(int u, int v, PixelImage originalImage) { double M = originalImage.getWidth(); double N = originalImage.getHeight(); Complex answer = Complex.ONE.times(1 / (M * N)); // first part of // equation Complex sum = Complex.ZERO; for (int x = 0; x <= M - 1; x++)// first sum { Complex ySum = Complex.ZERO; for (int y = 0; y <= N - 1; y++) { Complex yTerm = Complex.ONE.times(originalImage.getPixel(x, y)); Complex expTerm = Complex.I.times(-1);// -j expTerm = expTerm.times(2 * Math.PI); expTerm = expTerm.times((u * x) / M + (v * y) / N); Complex exp = expTerm.exp(); yTerm = exp.times(yTerm); ySum = ySum.plus(yTerm); } sum = sum.plus(ySum); sum.floatValue(); } answer = answer.times(sum); return answer.magnitude();// accuracy loss } } =