tefactory
tefactory

Reputation: 23

The results of OpenCV idft() and MATLAB ifft2 does not match

So i'm testing my algorithm in MATLAB and it's done.

Then now doing cording for porting on C++ with OpenCV 2.4.5.

The problem is inverse fourier transform methods of two platforms, OpenCV and MATLAB.

So i have tested with simple matrix.

Here's test results.

The subject matrix is... 3 by 3 2-D.

   1 2 3
   4 5 6
   7 8 9

-MATLAB-

test = [ 1, 2, 3;
         4, 5, 6;
         7, 8, 9];

ifft2(test);

result

   5.0000 + 0.0000i  -0.5000 - 0.2887i  -0.5000 + 0.2887i
  -1.5000 - 0.8660i   0.0000 + 0.0000i   0.0000 + 0.0000i
  -1.5000 + 0.8660i   0.0000 + 0.0000i   0.0000 + 0.0000i

-OPENCV-

Note:Elements are same values.

Mat a = Mat::zeros(3, 3, CV_64FC1);
Mat b = Mat::zeros(3, 3, CV_64FC1);

 a.at<double>(0,0) = 1;
 a.at<double>(0,1) = 2;
 a.at<double>(0,2) = 3;

 a.at<double>(1,0) = 4;
 a.at<double>(1,1) = 5;
 a.at<double>(1,2) = 6;

 a.at<double>(2,0) = 7;
 a.at<double>(2,1) = 8;
 a.at<double>(2,2) = 9;

 idft(a, b, DFT_SCALE, 0);

result

    4.33333     -4.13077     2.79743
   -2.10313     -0.103134   -2.83518
   -0.563533     2.16852     1.43647

I still didnt have found the solution. Even this couldn't gave me a solution.

EDIT: The problem has been solved. I put the CV_64FC1 to idft() as an input and CV_64FC2 as an output. A two matrices must be have same depth, both input and output are have to be 64_FC2. And flags DFT+COMPLEX_OUTPUT+DFT_SCALE is same as MATLAB's ifft2.

-SOLVED-

Mat input = Mat::zeros(3, 3, CV_64FC2); 
Mat output = Mat::zeros(3, 3, CV_64FC2);
idft(input, output, DFT_COMPLEX_OUTPUT+DFT_SCALE, 0);

Upvotes: 2

Views: 1543

Answers (2)

chappjc
chappjc

Reputation: 30579

I believe you need cv::DFT_COMPLEX_OUTPUT+cv::DFT_SCALE since the input to idft clearly results in a complex-valued matrix.

Also, I think you'll need a 2-channel array for the output (type CV_64FC2), similarly for the input. As with any multi-channel image in OpenCV, you then access elements with the appropriate vector type (e.g. for doubles, .at<cv::Vec2d>(i,j), where the Vec2d stores the real and imaginary components at location i,j).

Upvotes: 2

Andrey  Smorodov
Andrey Smorodov

Reputation: 10852

I think if you use 2 channel input matrices (CV_64FC2) you should use

a.at<Vec2d>(0,0)[0] = 1; // Re - part
a.at<Vec2d>(0,0)[1] = 0; // Im - part

instead of:

a.at<double>(0,0) = 1;

Upvotes: 0

Related Questions