0

我正在尝试使用 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,但仍然存在很大差异。

4

3 回答 3

1

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

于 2013-11-14T14:51:53.837 回答
1

如果 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);
        }
    }
于 2014-04-15T03:25:29.490 回答
1

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

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

于 2013-11-14T16:04:50.970 回答