Matlab FFT vs OpenCv DFT

2019-07-19 18:19发布

I'm trying to convert some Matlab code to OpenCv and have problems with FFT. I've read topics with similar problem, but I still don't get what's wrong with my code (or my FFT-thinking). When I do it in MATLAB:

A = [1 2 3; 4 5 6;7 8 9]; %the simplest matrix i can think of
dft(A,[],1) %this should be 1-dim forward fft

I get:

ans = 
12.0000 +  0.0000i   15.0000 +  0.0000i   18.0000 +  0.0000i
-4.5000 +  2.5981i   -4.5000 +  2.5981i   -4.5000 +  2.5981i
-4.5000 -  2.5981i   -4.5000 -  2.5981i   -4.5000 -  2.5981i

But when I try to do it as simple as possible in OpenCV:

Mat A = (Mat_<float>(3,3) <<  1,2,3,
                                4,5,6,
                                7,8,9);
Mat planes[] = {Mat_<float>(A), Mat::zeros(A.size(), CV_32F)};
Mat complexI;    //Complex plane to contain the DFT coefficients
merge(planes, 2, complexI);
dft(complexI, complexI,DFT_ROWS);  // Applying DFT without padding
cout << complexI;

I get:

[6,0,-1.5,0.866,-1.5,-0.866;
15,0,-1.5,0.866,-1.5,-0.866;
24,0,-1.5,0.866,-1.5,-0.866]

which is completely different. I'm using DFT_ROWS to obtain 1D transformation, and not using padding because dft declaration in Matlab is not applaying it. Can anybody point out what is wrong with my FFT-thinking? How can I obtain results similar to Matlab?

Ok, so it was all about confusing rows and columns.

But now I can't figure out scaling for inverse transformation. In MATLAB:

A = [ 1 2 3; 4 5 6;  7 8 9; 10 11 12];
mask = [0 1 0 0; 0 1 0 0; 0 1 0 0]';
F = fft(A,[],1);
F(~mask) = 0;
real(ifft(F,[],1))
ans =
-1.5000  -1.5000  -1.5000
-1.5000  -1.5000  -1.5000
1.5000   1.5000   1.5000
1.5000   1.5000   1.5000

OpenCV:

Mat A = (Mat_<float>(4,3) <<  1,2,3,
                                4,5,6,
                                7,8,9,
                                10,11,12);

transpose(A,A);
Mat transformed;
dft(A,transformed,DFT_ROWS|DFT_COMPLEX_OUTPUT);  // Applying DFT
Mat mask = (Mat_<float>(4,3) << 0,0,0,
                                1,1,1,
                                0,0,0,
                                0,0,0);
transpose(transformed,transformed);
vector<Mat> transformed_splitted;
split(transformed, transformed_splitted);
transformed_splitted[0] = transformed_splitted[0].mul(mask);
transformed_splitted[1] = transformed_splitted[1].mul(mask);
merge(transformed_splitted,transformed);
transpose(transformed,transformed);
idft(transformed,transformed,DFT_ROWS|DFT_REAL_OUTPUT|DFT_SCALE);
transpose(transformed,transformed);
cout << transformed;

output:
[-3 -3 -3 -3;
-3 -3 -3 -3;
3 3 3 3;
3 3 3 3]

It seems to me, that there is something wrong with scaling. Funny thing is that for matrix 5x3 results from both codes are the same. For 8x3 additionaly some results differ. How can I obtain same results from both IFFT?

0条回答
登录 后发表回答