在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有困难的主要内容,如果未能解决你的问题,请参考以下文章