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