Platform: opencv 2.4.9 on win7 with VC2015
Issue:
Input image
DFT magnitude image
- strange noise:
I use dft transfer image into frequency domain and transfer back by idft. I use 2 ways to get the result. convertTo() and normalize(). the result by convertTo() has strange noise.
normalize() result ........... .......... ......................convertTo() result
- wrong high pass filter result:
I pass dft image(both Re & Im) through a Gaussian High Pass Filter and the result. convertTo() and normalize() are totally different. convertTo() seem right but has noise and normalize() is strange but no noise...
high pass filter image for display
normalize() result of high pass filter result..... convertTo() result of high pass filter result
Code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void DFT_Shift(Mat &a_tImage)
{
// rearrange the image so that the origin is at the image center
int cx = a_tImage.cols / 2;
int cy = a_tImage.rows / 2;
Mat q0(a_tImage, Rect(0, 0, cx, cy)); // Top-Left - Create a ROI per quadrant
Mat q1(a_tImage, Rect(cx, 0, cx, cy)); // Top-Right
Mat q2(a_tImage, Rect(0, cy, cx, cy)); // Bottom-Left
Mat q3(a_tImage, Rect(cx, cy, cx, cy)); // Bottom-Right
Mat tmp; // swap quadrants (Top-Left with Bottom-Right)
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
q2.copyTo(q1);
tmp.copyTo(q2);
}
int main()
{
Mat I = imread("Src.bmp", CV_LOAD_IMAGE_GRAYSCALE);
if (I.empty())
return -1;
Mat padded; // expand input image to optimal size
int m = getOptimalDFTSize(I.rows);
int n = getOptimalDFTSize(I.cols); // on the border add zero values
copyMakeBorder(I, padded, 0, m - I.rows, 0, n - I.cols, BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
#if DO_GHPF > 0
Mat tPlanesFilter[] = { Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F) };
#endif
Mat complexI;
merge(planes, 2, complexI); // Add to the expanded another plane with zeros
dft(complexI, complexI); // this way the result may fit in the source matrix
// compute the magnitude and switch to logarithmic scale
// => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
split(complexI, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
// Pass both Re & Im Planes through Gaussian High Pass Filter
#if DO_GHPF > 0
GaussianHighPassFilter(complexI, tPlanesFilter);
#endif
Mat magI = planes[0];
printf("Re: %f\n", planes[0].at<float>(40, 40));
printf("Im: %f\n", planes[1].at<float>(40, 40));
magnitude(magI, planes[1], planes[0]); // planes[0] = magnitude
// switch to logarithmic scale
magI += Scalar::all(1);
log(magI, magI);
// crop the spectrum, if it has an odd number of rows or columns
magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));
// dft data base should be shifted to image's center
DFT_Shift(magI);
// Transform the matrix with float values into a viewable image form (float between values 0 and 1).
normalize(magI, magI, 0, 1, CV_MINMAX);
imshow("Input Image", I); // Show the result
imshow("spectrum magnitude", magI);
magI = magI * 255;
imwrite("./Magnitude.jpg", magI);
#if 1 // test idft
Mat ifft;
idft(complexI, ifft, DFT_REAL_OUTPUT);
Mat ifftConvert;
ifft.convertTo(ifftConvert, CV_8U);
imwrite("./IDFT_CV_8U.jpg", ifft);
normalize(ifft, ifft, 0, 1, CV_MINMAX);
imshow("IDFT", ifft);
ifft = ifft * 255;
imwrite("./IDFT.jpg", ifft);
#endif
waitKey();
return 0;
}