From c01234a6c2f363b492e5b4467e9463712bf7d11e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sacha=20Percot-T=C3=A9tu?= <zakinster@zakinster.com>
Date: Fri, 13 Jul 2012 17:55:10 +0200
Subject: [PATCH] Added invert DFT operation

---
 app/Operations/IFFTOp.cpp | 107 ++++++++++++++++++++++++++++++++++++++
 app/Operations/IFFTOp.h   |  34 ++++++++++++
 2 files changed, 141 insertions(+)
 create mode 100644 app/Operations/IFFTOp.cpp
 create mode 100644 app/Operations/IFFTOp.h

diff --git a/app/Operations/IFFTOp.cpp b/app/Operations/IFFTOp.cpp
new file mode 100644
index 0000000..c889a18
--- /dev/null
+++ b/app/Operations/IFFTOp.cpp
@@ -0,0 +1,107 @@
+/*
+ * 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 <QLabel>
+#include <QDialog>
+#include <QFormLayout>
+#include <QDialogButtonBox>
+#include "ImageListBox.h"
+
+#include "IFFTOp.h"
+#include "ImgWidget.h"
+#include "../Tools.h"
+#include "../Algorithms/FFT.h"
+#include <cmath>
+
+using namespace std;
+using namespace imagein;
+
+IFFTOp::IFFTOp() : DoubleOperation(Tools::tr("Discrete Fourier reconstruction").toStdString())
+{
+}
+
+bool IFFTOp::needCurrentImg() const {
+    return false;
+}
+
+void IFFTOp::operator()(const imagein::Image_t<double>*, const map<const imagein::Image_t<double>*, string>& imgList) {
+
+    QDialog* dialog = new QDialog();
+    dialog->setWindowTitle(dialog->tr("Parameters"));
+    dialog->setMinimumWidth(180);
+    QFormLayout* layout = new QFormLayout();
+    dialog->setLayout(layout);
+
+    ImageListBox_t<double>* magtdImgBox = new ImageListBox_t<double>(dialog, NULL, imgList);
+    ImageListBox_t<double>* phaseImgBox = new ImageListBox_t<double>(dialog, NULL, imgList);
+    layout->insertRow(0, "Magnitude : ", magtdImgBox);
+    layout->insertRow(1, "Phase : ", phaseImgBox);
+
+    QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel, Qt::Horizontal, dialog);
+    layout->insertRow(2, buttonBox);
+    QObject::connect(buttonBox, SIGNAL(accepted()), dialog, SLOT(accept()));
+    QObject::connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(reject()));
+
+    QDialog::DialogCode code = static_cast<QDialog::DialogCode>(dialog->exec());
+
+    if(code!=QDialog::Accepted) {
+        return;
+    }
+
+    const Image_t<double>* magnitudeImg = magtdImgBox->currentImage();
+    const Image_t<double>* phaseImg = phaseImgBox->currentImage();
+    unsigned int width = min(nearestUpPower2(magnitudeImg->getWidth()), nearestUpPower2(phaseImg->getWidth()));
+    unsigned int height = min(nearestUpPower2(magnitudeImg->getHeight()), nearestUpPower2(phaseImg->getHeight()));
+    unsigned int channels = min(magnitudeImg->getNbChannels(), phaseImg->getNbChannels());
+
+    Image* resImg = new Image(width, height, channels);
+//    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];
+
+    const unsigned int cw = width/2;
+    const unsigned int ch = height/2;
+    for(unsigned int c = 0; c < channels; ++c) {
+        for(unsigned int j = 0; j < height; ++j) {
+            for(unsigned int i = 0; i < width; ++i) {
+                const unsigned int ci = i >= cw ? i - cw : i + cw;
+                const unsigned int cj = j >= ch ? j - ch : j + ch;
+                const double magtd = magnitudeImg->getPixel(ci, cj, c);
+                const double phase = phaseImg->getPixel(ci, cj, c);
+                const double real = magtd * cos(phase);
+                const double imag = magtd * sin(phase);
+                data[i][j] = complex<double>(real,imag);
+            }
+        }
+
+        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();
+                Image::depth_t value = floor(data[i][j].real()+0.5);
+                value = min(255, max(0, value));
+                resImg->setPixel(i, j, c, value);
+            }
+        }
+    }
+
+    this->outImage(resImg, "DFT-reconstructed image");
+}
diff --git a/app/Operations/IFFTOp.h b/app/Operations/IFFTOp.h
new file mode 100644
index 0000000..aa7fdac
--- /dev/null
+++ b/app/Operations/IFFTOp.h
@@ -0,0 +1,34 @@
+/*
+ * 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 IFFTOP_H
+#define IFFTOP_H
+
+#include <Operation.h>
+
+class IFFTOp : public DoubleOperation
+{
+public:
+    IFFTOp();
+    void operator()(const imagein::Image_t<double>*, const std::map<const imagein::Image_t<double>*, std::string>&);
+
+    bool needCurrentImg() const;
+};
+
+#endif // IFFTOP_H
-- 
GitLab