您的位置:首页 > 运维架构

Displaying Fourier transforms in OpenCV

2017-09-08 14:45 211 查看



I'm just learning to use OpenCV and am having a problem with using DFT. I've done a signal processing class which used MatLab, so I'm trying to go through some of the exercises we did in that class. I'm trying to get and display the FT of an image, so I can
mask some of the frequencies. I'd like to be able to see the FT, so I know how big to make the mask, but when I tried, I got an image like this:

rather than like one of these
alt text http://www.ceremade.dauphine.fr/~peyre/numerical-tour/tours/graphics_synthesis_fourier/index_03.png
Am I forgetting a step somewhere? I'm loading the image, converting its type to CV_32FC1, getting the matrix of it, getting the DFT, and then getting turning the resulting matrix back into an image. I'll post the code I'm using if it will be of any help?

Or if someone has a link to an example of displaying the FT? I could only find ones which used it for the convolution.

EDIT: Did I get the Phase of the image?
matlab image-processing opencv fft 

  edited Jun 5 '10 at 10:22 asked Jun 5 '10 at 10:14 Simonw 487
4 10 26      Certainly it is not the phase of the input image. Since your image is only black and white -- when it should have a range of gray values -- my guess is that you are having some error in conversion. –  Alceu
Costa Jun 13 '10 at 23:13

 | 


Answers

1

I have run into similar trouble in trying to visualize the magnitude of a 2D DFT on an image with respect to OpenCV. I finally churned out a working implementation. I wouldn't consider it great code, and it has only been tested on a 256 x 256 8-bit (gray-scale)
single-channel image--lenna.png (it may need to be tweaked to appropriately pad for other image dimensions). The mean-squared error between the input image and the reconstructed
image is zero, so it is working as it should. OpenCV v2.1 is required.

file: mstrInclude.h
#ifndef _MASTER_INCLUDE_
#define _MASTER_INCLUDE_

// Standard
#include <stdio.h>
#include <string>
#include <sstream>
#include <iostream>
#include <cmath>
using namespace std;

// OpenCV2.1
#include "cv.h"
#include "highgui.h"
using namespace cv;

#define LOAD_IMAGE "lenna.png"

#endif // _MASTER_INCLUDE_


file: main.cpp
#include "mstrInclude.h"
void translateImg(Mat& imgIn, Mat& imgOut)
{
int i, j;

for (i = 0; i < imgIn.rows; i++)
for (j = 0; j < imgIn.cols; j++)
imgOut.at<double>(i,j) = imgIn.at<double>(i,j) * pow(-1.0, i+j);
}
void scaleImg(Mat& imgIn, Mat& imgOut, float scaleFactor)
{
int i, j;

for (i = 0; i < imgIn.rows; i++)
for (j = 0; j < imgIn.cols; j++)
imgOut.at<double>(i,j) = (double)scaleFactor * log(1.0 + imgIn.at<double>(i,j));
}

void consoleOut(cv::Mat outMat, int rows = 5, int cols = 5)
{
rows = ((rows == -1 || rows >= outMat.rows) ? outMat.rows : rows);
cols = ((cols == -1 || cols >= outMat.cols) ? outMat.cols : cols);

for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols; j++)
{
cout << outMat.at<double>(i, j);
cout << " ";
}
cout << endl;
}
}

double calcMSE(Mat& imgOrig, Mat& imgReconst)
{
int valOrig = 0, valReconst = 0;
double MSE = 0.0;

for(int i = 0; i < imgOrig.rows; i++)
{
for (int j = 0; j < imgOrig.cols; j++)
{
valOrig = imgOrig.at<unsigned char>(i, j);
valReconst = imgReconst.at<unsigned char>(i, j);

MSE += pow( (double)(valOrig - valReconst), 2.0 );
}
}
return (MSE / (imgOrig.rows * imgOrig.cols));
}

string convertInt(int number) // converts integer to string
{
stringstream ss;
ss << number;
return ss.str();
}

int main(unsigned int argc, char* const argv[])
{
int dftH, dftW;
cv::Mat imgIn;

imgIn = cv::imread(LOAD_IMAGE, 0); //grayscale
cv::imshow("Original Image", imgIn);
waitKey();

dftH = cv::getOptimalDFTSize(imgIn.rows);
dftW = cv::getOptimalDFTSize(imgIn.cols);

Mat imgMod;
Mat imgPrecFFT(dftH, dftW, CV_64FC1, Scalar::all(0));
imgIn.convertTo(imgMod, CV_64FC1);
imgPrecFFT = imgMod(cv::Range::all(), cv::Range::all()).clone();

// translate image
std::vector<Mat> imgsTrans;
imgsTrans.push_back(Mat_<double>(imgIn.size(), CV_64FC1));
imgsTrans.push_back(Mat_<double>(imgIn.size(), CV_64FC1));
imgsTrans[1].setTo(Scalar::all(0), Mat());
translateImg(imgPrecFFT, imgsTrans[0]);

Mat imgPrecTransFFT(imgIn.size(), CV_64FC2, Scalar::all(0));
cv::merge(imgsTrans, imgPrecTransFFT);

// dft
cv::Mat imgFFT;
dft(imgPrecTransFFT, imgFFT, DFT_COMPLEX_OUTPUT);
cv::Mat imgDispFFT;

// calculate magnitude
Mat imgMagnitude(imgIn.size(), CV_64FC1);
std::vector<Mat> chans;
cv::split(imgFFT, chans);
cv::magnitude(chans[0], chans[1], imgMagnitude);

// scale magnitude image
Mat imgMagnitudeScaled(imgIn.size(), CV_64FC1);
scaleImg(imgMagnitude, imgMagnitudeScaled, 10.0);

// display magnitude image
cv::Mat imgDisp;
cv::convertScaleAbs(imgMagnitudeScaled, imgDisp);
imshow("Magnitude Output", imgDisp);
waitKey();

// inverse dft
cv::split(imgFFT, chans);
chans[1].zeros(imgIn.size(), CV_64FC1);
cv::merge(chans, imgFFT);
cv::Mat invFFT;
cv::idft(imgFFT, invFFT, DFT_REAL_OUTPUT + DFT_SCALE);

// translate image back to original location
cv::split(invFFT, imgsTrans);
Mat imgAfterTrans(imgIn.size(), CV_64FC1);
translateImg(imgsTrans[0], imgAfterTrans);
imgAfterTrans.convertTo(imgDisp, CV_8UC1);

imshow("After Inverse Output", imgDisp);
waitKey();

// calculate and output mean-squared error between input/output images
double MSE = calcMSE(imgIn, imgDisp);
cout<<endl<<"MSE: "<<MSE<<endl;
waitKey();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: