简体   繁体   中英

Having difficulty with FFT and IFFT in opencv

I'm trying to convert this simple Matlab code to C++ with openCV:

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

It means taking the fft of the matrix "output", multiplying it element by element with the matrix "gf", then taking the ifft of that and then taking the magnitude of that.

I'm trying the following simple code:

    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));
    }
}

It's very simple - I'm applying the fft, getting a complex results. Then multiplying element by element with gf, then taking the inverse transform, splitting the result to two matrices - real and imaginary- then taking the magnitude of that.

However, even though it's very simple and I don't see any errors, the results are very different then what I get in Matlab. Far too large to be explained by rounding errors.

Can someone please point me to what I might be doing wrong?

I'm using Matlab2013a, openCV 2.4.5 with VS 2012 on windows 7.

Thanks in advance,

Gil.

EDIT: I added sqrt of the results, but there are still large differences.

In MatLAB version you take a square root from the result and in OpenCV - no. Have you checked this?

Okay, right off the bat I see an issue with your filtering. I'm not sure exactly what that loop would do, but to do frequency filtering you should use the function mulSpectrums .

Also if you want to take the sqrt of the magnitude you can use OpenCV's sqrt function without having to go through the at operator.

if gf is a complex matrix as well, ie CV_64FC2/CV_32FC2, you probably need to use mulSpectrums. Otherwise if you want to multiply them together yourself, then you should use std::complex to access those complex values. std::complex will take of the complex operation for you.

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);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM