Reputation: 2137
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.
Upvotes: 0
Views: 913
Reputation: 560
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);
}
}
Upvotes: 1
Reputation: 1412
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.
Upvotes: 1
Reputation: 2860
In MatLAB version you take a square root from the result and in OpenCV - no. Have you checked this?
Upvotes: 1