2013-05-21 132 views
2

我試圖用EMGU可視化圖像的FFT。下面是我在處理圖像:EMGU/OpenCV不產生預期結果的圖像的FFT

enter image description here

這裏是預期的結果:

enter image description here

這裏就是我得到: enter image description here

這裏是我的代碼:

Image<Gray, float> image = new Image<Gray, float>(@"C:\Users\me\Desktop\sample3.jpg"); 
IntPtr complexImage = CvInvoke.cvCreateImage(image.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_32F, 2); 

CvInvoke.cvSetZero(complexImage); 
CvInvoke.cvSetImageCOI(complexImage, 1); 
CvInvoke.cvCopy(image, complexImage, IntPtr.Zero); 
CvInvoke.cvSetImageCOI(complexImage, 0); 

Matrix<float> dft = new Matrix<float>(image.Rows, image.Cols, 2); 
CvInvoke.cvDFT(complexImage, dft, Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD, 0); 

Matrix<float> outReal = new Matrix<float>(image.Size); 
Matrix<float> outIm = new Matrix<float>(image.Size); 
CvInvoke.cvSplit(dft, outReal, outIm, IntPtr.Zero, IntPtr.Zero); 

Image<Gray, float> fftImage = new Image<Gray, float>(outReal.Size); 
CvInvoke.cvCopy(outReal, fftImage, IntPtr.Zero); 

pictureBox1.Image = image.ToBitmap(); 
pictureBox2.Image = fftImage.Log().ToBitmap(); 

我在這裏犯了什麼錯誤?

更新:根據羅傑羅蘭的建議,這裏是我的更新代碼。結果看起來更好,但我不是100%確定它是正確的。這裏的結果:
enter image description here

Image<Gray, float> image = new Image<Gray, float>(@"C:\Users\yytov\Desktop\sample3.jpg"); 
     IntPtr complexImage = CvInvoke.cvCreateImage(image.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_32F, 2); 

     CvInvoke.cvSetZero(complexImage); // Initialize all elements to Zero 
     CvInvoke.cvSetImageCOI(complexImage, 1); 
     CvInvoke.cvCopy(image, complexImage, IntPtr.Zero); 
     CvInvoke.cvSetImageCOI(complexImage, 0); 

     Matrix<float> dft = new Matrix<float>(image.Rows, image.Cols, 2); 
     CvInvoke.cvDFT(complexImage, dft, Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD, 0); 

     //The Real part of the Fourier Transform 
     Matrix<float> outReal = new Matrix<float>(image.Size); 
     //The imaginary part of the Fourier Transform 
     Matrix<float> outIm = new Matrix<float>(image.Size); 
     CvInvoke.cvSplit(dft, outReal, outIm, IntPtr.Zero, IntPtr.Zero); 

     CvInvoke.cvPow(outReal, outReal, 2.0); 
     CvInvoke.cvPow(outIm, outIm, 2.0); 

     CvInvoke.cvAdd(outReal, outIm, outReal, IntPtr.Zero); 
     CvInvoke.cvPow(outReal, outReal, 0.5); 

     CvInvoke.cvAddS(outReal, new MCvScalar(1.0), outReal, IntPtr.Zero); // 1 + Mag 
     CvInvoke.cvLog(outReal, outReal); // log(1 + Mag) 

     // Swap quadrants 
     int cx = outReal.Cols/2; 
     int cy = outReal.Rows/2; 

     Matrix<float> q0 = outReal.GetSubRect(new Rectangle(0, 0, cx, cy)); 
     Matrix<float> q1 = outReal.GetSubRect(new Rectangle(cx, 0, cx, cy)); 
     Matrix<float> q2 = outReal.GetSubRect(new Rectangle(0, cy, cx, cy)); 
     Matrix<float> q3 = outReal.GetSubRect(new Rectangle(cx, cy, cx, cy)); 
     Matrix<float> tmp = new Matrix<float>(q0.Size); 

     q0.CopyTo(tmp); 
     q3.CopyTo(q0); 
     tmp.CopyTo(q3); 
     q1.CopyTo(tmp);      
     q2.CopyTo(q1); 
     tmp.CopyTo(q2); 

     CvInvoke.cvNormalize(outReal, outReal, 0.0, 255.0, Emgu.CV.CvEnum.NORM_TYPE.CV_MINMAX, IntPtr.Zero); 

     Image<Gray, float> fftImage = new Image<Gray, float>(outReal.Size); 
     CvInvoke.cvCopy(outReal, fftImage, IntPtr.Zero); 

     pictureBox1.Image = image.ToBitmap(); 
     pictureBox2.Image = fftImage.ToBitmap(); 
+2

我還沒有檢查過你創建了DFT,但是你沒有顯示你的想法 - 你應該計算並顯示對數功率譜,而不僅僅是Image.Log。請參閱此鏈接瞭解OpenCV示例 - http://opencv-users.1802565.n2.nabble.com/faint-image-after-Inverse-DFT-using-cvDFT-td2193072.html –

+0

根據您的建議更新了我的代碼,但我得到相同的結果。 – Johnny

+0

還有一個想法。強度的差異是否可以由不同的比特深度引起? 理想的結果似乎是8位,四捨五入。但是你的結果是浮動圖像。 – jnovacho

回答

3

我不能對所得到的圖像的大小/強度發表評論,但我可以給你一個點的圖像的空間分佈提示。

OpenCV不會重新安排將原點[0,0]置於圖像中心的象限。您必須手動重新安排象限。

看第6步下頁: http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html

它是OpenCV的官方文檔,所以它在C++中,但原則成立。

+0

我的代碼的最新版本起作用。這是你的答案和羅傑羅蘭的結果。謝謝! – Johnny

相關問題