From 45e0d3a53e6e9ecc8eb9681436e3598e1784179a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sacha=20Percot-T=C3=A9tu?= <zakinster@zakinster.com>
Date: Fri, 13 Jul 2012 14:59:02 +0200
Subject: [PATCH] Added the FFT operation

---
 app/Operations/FFTOp.cpp | 87 ++++++++++++++++++++++++++++++++++++++++
 app/Operations/FFTOp.h   | 35 ++++++++++++++++
 2 files changed, 122 insertions(+)
 create mode 100644 app/Operations/FFTOp.cpp
 create mode 100644 app/Operations/FFTOp.h

diff --git a/app/Operations/FFTOp.cpp b/app/Operations/FFTOp.cpp
new file mode 100644
index 0000000..6ebecbb
--- /dev/null
+++ b/app/Operations/FFTOp.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2011-2012 INSA Rennes
+ *
+ * This file is part of EIImage.
+ *
+ * EIImage is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EIImage is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EIImage.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include "ImgWidget.h"
+#include "FFTOp.h"
+#include "../Tools.h"
+#include "../Algorithms/FFT.h"
+#include <cmath>
+
+using namespace std;
+using namespace imagein;
+
+FFTOp::FFTOp() : Operation(Tools::tr("Discrete Fourier transform").toStdString())
+{
+}
+
+bool FFTOp::needCurrentImg() const {
+    return true;
+}
+
+void FFTOp::operator()(const imagein::Image* image, const map<const imagein::Image*, string>&) {
+
+    unsigned int width = nearestUpPower2(image->getWidth());
+    unsigned int height = nearestUpPower2(image->getHeight());
+
+    Image_t<double>* magnitudeImg = new Image_t<double>(width, height, image->getNbChannels());
+    Image_t<double>* phaseImg = new Image_t<double>(width, height, image->getNbChannels());
+//    Image_t<double>* realImg = new Image_t<double>(width, height, image->getNbChannels());
+//    Image_t<double>* imagImg = new Image_t<double>(width, height, image->getNbChannels());
+
+    complex<double>** data = new complex<double>*[width];
+    for(unsigned int i = 0; i < width; ++i) data[i] = new complex<double>[height];
+
+    for(unsigned int c = 0; c < image->getNbChannels(); ++c) {
+        for(unsigned int j = 0; j < image->getHeight(); ++j) {
+            for(unsigned int i = 0; i < image->getWidth(); ++i) {
+                data[i][j] = static_cast<double>(image->getPixel(i, j, c));
+            }
+        }
+        for(unsigned int j = image->getHeight(); j < height; ++j) {
+            for(unsigned int i = image->getWidth(); i < height; ++i) {
+                data[i][j] = 0;
+            }
+        }
+
+        FFT2D(data, width, height, 1);
+        for(unsigned int j = 0; j < height; ++j) {
+            for(unsigned int i = 0; i < width; ++i) {
+                const double real = data[i][j].real();
+                const double imag = data[i][j].imag();
+                const double magnitude = sqrt( real*real + imag*imag );
+                const double phase = atan2(imag, real);
+                const unsigned int cw = width/2;
+                const unsigned int ch = height/2;
+                const unsigned int ci = i >= cw ? i - cw : i + cw;
+                const unsigned int cj = j >= ch ? j - ch : j + ch;
+                magnitudeImg->setPixel(ci, cj, c, magnitude);
+                phaseImg->setPixel(ci, cj, c, phase);
+//                realImg->setPixel(ci, cj, c, real);
+//                imagImg->setPixel(ci, cj, c, imag);
+            }
+        }
+    }
+
+    this->outDoubleImage(phaseImg, " - FFT (phase)", true, false);
+    this->outDoubleImage(magnitudeImg, " - FFT (magnitude)", true, true);
+//    result.push_back(new DoubleImgWidget(phaseImg, " - FFT : phase", true, false));
+//    result.push_back(new DoubleImgWidget(magnitudeImg, " - FFT : magnitude", true, true));
+//    result.push_back(new DoubleImgWidget(realImg, " - FFT : real", true, true));
+//    result.push_back(new DoubleImgWidget(imagImg, " - FFT : imag", true, true));
+
+}
diff --git a/app/Operations/FFTOp.h b/app/Operations/FFTOp.h
new file mode 100644
index 0000000..66a60db
--- /dev/null
+++ b/app/Operations/FFTOp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2011-2012 INSA Rennes
+ *
+ * This file is part of EIImage.
+ *
+ * EIImage is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EIImage is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EIImage.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef FFTOP_H
+#define FFTOP_H
+
+#include <Operation.h>
+
+class FFTOp : public Operation
+{
+public:
+    FFTOp();
+
+    void operator()(const imagein::Image*, const std::map<const imagein::Image*, std::string>&);
+
+    bool needCurrentImg() const;
+};
+
+#endif // FFTOP_H
-- 
GitLab