0

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.

1
  • How do you define the filter? Commented Nov 14, 2013 at 15:48

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

3 Comments

In openCV I do take the square root (Magnitude takes the square root). See here: docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/…
I mean in MatLAB you take additional square root. Function abs in MatLAB for complex data is doing the same as magnitude in OpenCV mathworks.com/help/matlab/ref/abs.html
Thanks, I added the sqrt, but the results are still very different.
1

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.

2 Comments

Thanks, I'll try to modify my code according to your comments.
No problem, hope it helps
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.