c# - 图像的 EMGU/OpenCV FFT 未产生预期结果

标签 c# image-processing emgucv

我正在尝试使用 EMGU 可视化图像的 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();

我在这里犯了什么错误?

更新:根据 Roger Rowland 的建议,这是我更新的代码。结果看起来更好,但我不能 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();  

最佳答案

我无法评论生成图像的大小/强度,但我可以为您提供有关图像中点的空间分布的提示。

OpenCV 不会重新排列象限以将原点 [0,0] 置于图像中心。您必须手动重新排列象限。

查看下页的步骤 6: http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html

这是 OpenCV 的官方文档,所以它是用 C++ 编写的,但原理是成立的。

关于c# - 图像的 EMGU/OpenCV FFT 未产生预期结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16669007/

相关文章:

c# - 如何实现一个可编辑的 UITableView,类似于 Safari Bookmarks?

c++ - 多尺度检测循环在 OpenCV 的 HOG 检测中是如何工作的?

c++ - 我们如何更准确地检测人脸

c# - EmguCV/OpenCV 图像加法/减法

使用单个相机计算距离

c# - RijndaelManaged 实例的用途?

c# - 选择下拉列表中的第一项

c# - .NET 4.5 "Any CPU"带有 Perefer 32 位选项 : not work for dlls which have 32 and 64 bit versions with XCopy

c++ - 是否可以将 TDD 与图像处理算法一起使用?

c# - EMGU CV 2.4.9 人脸识别精度问题