Plattform: opencv 2.4.9 auf win7 mit VC2015OpenCV IDFT hat seltsame Geräusche und Hochpassfilter Ergebnis scheinen falsch
Ausgabe:
Eingabebild DFT Magnitudenbild
- seltsame Geräusche :
Ich benutze dft Übertragungsbild in Frequenzbereich und Übertragung zurück durch idft. Ich verwende 2 Möglichkeiten, um das Ergebnis zu erhalten. convertTo() und normalize(). Das Ergebnis von ConvertTo() hat seltsames Rauschen.
Normalisieren() Ergebnis ........... .......... .............. ........ convertTo() führen
- falsch Hochpassfilter Ergebnis:
I dft Bild übergeben (beide Re & Im) durch eine Gauß'sche Hochpassfilter und das Ergebnis. convertTo() und normalize() sind völlig verschieden. convertTo() scheinen Recht hat aber Lärm und normalisieren() ist seltsam, aber kein Lärm ...
Hochpassfilter Bild für die Anzeige
normalize() aufgrund hoher Passfilter Ergebnis ..... convertTo() Ergebnis des Hochpassfilters Ergebnis
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;
}
Dank @francis Also wenn ich glatte Region in 0 durch Hochpassfilter lassen wollen. Dann muss ich abs() verwenden, um den negativen Wert vor normalize() zu ändern? –
Gern geschehen! In der Tat, die Berechnung des absoluten Wertes vor der Normalisierung wird die Kanten hervorheben und Sie werden etwas erhalten, das dem Anfangsergebnis von 'convertTo()' ähnlich ist. – francis