2016-06-12 6 views
1

Plattform: opencv 2.4.9 auf win7 mit VC2015OpenCV IDFT hat seltsame Geräusche und Hochpassfilter Ergebnis scheinen falsch

Ausgabe:

Eingabebild DFT Magnitudenbild

  1. 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

  1. 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; 
} 

Antwort

0

Die Rückwärts-Fourier-Transformation ist nicht normalisiert. In der Tat, wenn das Bild 512x512 ist, ist idft(dft(x)) 512x512 mal größer als x. Das seltsame Geräusch ist darauf zurückzuführen, dass Zahlen nicht mehr im Bereich von 0 - 255 liegen.

Insbesondere die Rückwärts-DFT bietet negative Werte und Werte so groß wie 6,6e7. Es kann durch Zugabe von überprüft werden:

ifft=ifft/(512*512); 

Das seltsame Geräusche entfernt:

double min, max; 
cv::minMaxLoc(ifft, &min, &max); 
std::cout << min<< " " << max <<std::endl; 

Herunterskalieren der Rückwärts dft kann durch Zugabe erfolgen.

2/Das normalize() - Ergebnis des Hochpassfilters scheint korrekt zu sein. Solch ein Filter wird ein verwackeltes Bild von dem Originalbild subtrahieren. Insbesondere ist der Durchschnitt des Ausgangs 0. Daher weist er negative und positive Werte auf. Da das Maximum und das Minimum in Ihrem Fall die gleiche Größe haben, wird normalize() den Nullwert nahe 127 \ approx 255/2 setzen. Dies ist der Grund, warum das Bild grau wird. Weißwerte entsprechen positiven Werten und Schwarzwerten negativen Werten.

convertTo() erhalten sehr große negative und positive Werte außerhalb des Bereichs 0 -255 für die Kanten. Diese Werte werden in Weiß konvertiert. Weit entfernt von den Kanten liegen die Werte nahe bei Null und die Farbe bleibt schwarz.

+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? –

+0

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