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?