如何使用EMGU计算DFT及其反转?

如何计算图像的DFT(使用EMGU),显示它然后计算反转以恢复原始图像?

我将在这里回答我自己的问题,因为我花了一段时间才弄明白。

测试它在这里工作是一个图像 在此处输入图像描述
这是应用DFT后的预期结果。 在此处输入图像描述

而且没有进一步的ado这里是代码:

// Load image Image image = new Image(@"C:\Users\me\Desktop\lines.png"); // Transform 1 channel grayscale image into 2 channel image IntPtr complexImage = CvInvoke.cvCreateImage(image.Size, Emgu.CV.CvEnum.IPL_DEPTH.IPL_DEPTH_32F, 2); CvInvoke.cvSetImageCOI(complexImage, 1); // Select the channel to copy into CvInvoke.cvCopy(image, complexImage, IntPtr.Zero); CvInvoke.cvSetImageCOI(complexImage, 0); // Select all channels // This will hold the DFT data Matrix forwardDft = new Matrix(image.Rows, image.Cols, 2); CvInvoke.cvDFT(complexImage, forwardDft, Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD, 0); CvInvoke.cvReleaseImage(ref complexImage); // We'll display the magnitude Matrix forwardDftMagnitude = GetDftMagnitude(forwardDft); SwitchQuadrants(ref forwardDftMagnitude); // Now compute the inverse to see if we can get back the original Matrix reverseDft = new Matrix(forwardDft.Rows, forwardDft.Cols, 2); CvInvoke.cvDFT(forwardDft, reverseDft, Emgu.CV.CvEnum.CV_DXT.CV_DXT_INV_SCALE, 0); Matrix reverseDftMagnitude = GetDftMagnitude(reverseDft); pictureBox1.Image = image.ToBitmap(); pictureBox2.Image = Matrix2Bitmap(forwardDftMagnitude); pictureBox3.Image = Matrix2Bitmap(reverseDftMagnitude); private Bitmap Matrix2Bitmap(Matrix matrix) { CvInvoke.cvNormalize(matrix, matrix, 0.0, 255.0, Emgu.CV.CvEnum.NORM_TYPE.CV_MINMAX, IntPtr.Zero); Image image = new Image(matrix.Size); matrix.CopyTo(image); return image.ToBitmap(); } // Real part is magnitude, imaginary is phase. // Here we compute log(sqrt(Re^2 + Im^2) + 1) to get the magnitude and // rescale it so everything is visible private Matrix GetDftMagnitude(Matrix fftData) { //The Real part of the Fourier Transform Matrix outReal = new Matrix(fftData.Size); //The imaginary part of the Fourier Transform Matrix outIm = new Matrix(fftData.Size); CvInvoke.cvSplit(fftData, 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) return outReal; } // We have to switch quadrants so that the origin is at the image center private void SwitchQuadrants(ref Matrix matrix) { int cx = matrix.Cols / 2; int cy = matrix.Rows / 2; Matrix q0 = matrix.GetSubRect(new Rectangle(0, 0, cx, cy)); Matrix q1 = matrix.GetSubRect(new Rectangle(cx, 0, cx, cy)); Matrix q2 = matrix.GetSubRect(new Rectangle(0, cy, cx, cy)); Matrix q3 = matrix.GetSubRect(new Rectangle(cx, cy, cx, cy)); Matrix tmp = new Matrix(q0.Size); q0.CopyTo(tmp); q3.CopyTo(q0); tmp.CopyTo(q3); q1.CopyTo(tmp); q2.CopyTo(q1); tmp.CopyTo(q2); } 

本答案中的大部分信息来自OpenCV邮件列表中的一个问题和Steve Eddins关于图像处理中FFT的文章 。