在opencv中使用FFT和IFFT有困难

Posted

技术标签:

【中文标题】在opencv中使用FFT和IFFT有困难【英文标题】:Having difficulty with FFT and IFFT in opencv 【发布时间】:2013-11-14 14:45:27 【问题描述】:

我正在尝试使用 openCV 将这个简单的 Matlab 代码转换为 C++:

localstd=sqrt(abs(ifft2(fft2(output).*gf)));

这意味着取矩阵“输出”的 fft,将它与矩阵“gf”逐个元素相乘,然后取它的 ifft,然后取它的大小。

我正在尝试以下简单代码:

    Mat planes[] = Mat_<float>(output), Mat::zeros(output.size(), CV_32F);
    Mat complexI;
    merge(planes, 2, complexI);         // Add to the expanded another plane with zeros

    dft(complexI, complexI,cv::DFT_SCALE);   
    for (int i=0;i<complexI.rows;i++)
        for (int j=0;j<complexI.cols;j++)
            complexI.at<float>(i,j)*=gf.at<float>(i,j);
        
    

    //now the inverse transform
    dft(complexI,complexI,cv::DFT_INVERSE);
    split(complexI, planes);                   // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
    magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
    Mat localstd = planes[0];

for (int i=0;i<localstd.rows;i++)
    for (int j=0;j<localstd.cols;j++)
        localstd.at<float>(i,j)= sqrt(localstd.at<float>(i,j));
    

这很简单 - 我正在应用 fft,得到一个复杂的结果。然后将元素与 gf 相乘,然后进行逆变换,将结果分成两个矩阵 - 实数和虚数 - 然后取其大小。

然而,尽管它非常简单并且我没有看到任何错误,但结果与我在 Matlab 中得到的结果大不相同。太大,无法用舍入误差来解释。

谁能指出我可能做错了什么?

我在 Windows 7 上使用 Matlab2013a、openCV 2.4.5 和 VS 2012。

提前致谢,

吉尔。

编辑:我添加了 sqrt 的结果,但仍然存在很大差异。

【问题讨论】:

如何定义过滤器? 【参考方案1】:

在 MatLAB 版本中,您从结果中取平方根,而在 OpenCV 中 - 不。你检查过这个吗?

【讨论】:

在 openCV 中,我确实取平方根(幅度取平方根)。见这里:docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/… 我的意思是在 MatLAB 中你取 additional 平方根。 MatLAB 中用于复杂数据的函数 abs 与 OpenCV 中的幅度相同 mathworks.com/help/matlab/ref/abs.html 谢谢,我添加了sqrt,但结果还是有很大的不同。【参考方案2】:

好的,我马上就发现您的过滤存在问题。我不确定该循环究竟会做什么,但要进行频率过滤,您应该使用函数mulSpectrums。

此外,如果您想获取数量级的 sqrt,您可以使用 OpenCV 的 sqrt 函数,而无需通过 at 运算符。

【讨论】:

谢谢,我会根据你的cmets尝试修改我的代码。 没问题,希望对你有帮助【参考方案3】:

如果 gf 也是一个复矩阵,即 CV_64FC2/CV_32FC2,您可能需要使用 mulSpectrums。否则,如果您想自己将它们相乘,那么您应该使用 std::complex 来访问这些复杂值。 std::complex 将为您完成复杂的操作。

for (int i=0;i<complexI.rows;i++)
        for (int j=0;j<complexI.cols;j++)
            complexI.at<complex<double>>(i,j)*=gf.at<complex<double>>(i,j);
        
    

【讨论】:

感谢您的帮助!

以上是关于在opencv中使用FFT和IFFT有困难的主要内容,如果未能解决你的问题,请参考以下文章

FFT 和 IFFT 的长度

通过对 FFT 结果进行共轭来使用 FFT 进行 IFFT

Python ifft

FFT和IFFT的Matlab实现(幅频响应和相频响应)

FFT和IFFT的Matlab实现(幅频响应和相频响应)

FFTW 和 OpenCV 的 C++ 接口,Mat 输出中的实部和虚部