Ask Your Question
2

Meaning of cv::idft() with DFT_REAL_OUTPUT option

asked 2015-12-23 04:38:03 -0600

polycarbonate gravatar image

updated 2015-12-23 17:33:50 -0600

I would like to ask about cv::idft() with DFT_REAL_OUTPUT for non-symmetric matrix. Let me explain in detail.

If an input matrix in time domain has only real component, dft of the input matrix has some kind of symmetric structure. For example,

const int width = 4;
const int height = 4;
cv::Mat in1ch = (cv::Mat_<double>(width, height)
    << 1.0, 0.2, 0.4, 0.5,
    0.4, 0.3, 0.2, 0.1,
    0.5, 0.7, 0.3, 0.8,
    0.2, 0.9, 0.8, 0.1
    );

// dfted: dft result of in1ch
// [7.4      0.4-0.6i  0.2       0.4+0.6i;
//  -0.2+i   1-0.6i    1.4-0.2i  -0.2-i;
//  1.4      1.2+1.4i  -0.2      1.2-1.4i;
//  -0.2-i   -0.2+i    1.4+0.2i  1+0.6i]
cv::Mat dfted;
cv::dft(in1ch, dfted, DFT_COMPLEX_OUTPUT);

And the idft result of the symmetric matrix will have only real component.

// idfted: idft result of dfted
// it is the same with in1ch
cv::Mat idfted;
cv::idft(dfted, idfted, DFT_REAL_OUTPUT | DFT_SCALE);

On the contrary, the idft result of a non-symmetric matrix will have real and imaginary component. However, if I give a non-symmetric matrix to cv::idft() with DFT_REAL_OUTPUT, I get a matrix having only real component.

// notSym: non-symmetric matrix which is almost the same with dfted
// [7.4      1.3+0.2i  0.2       0.4+0.6i;
//  -0.2+i   1-0.6i    1.4-0.2i  -0.2-i;
//  1.4      1.2+1.4i  -0.2      0.4+i;
//  -0.2-i   -0.2+i    1.4+0.2i  1+0.6i]
cv::Mat notSym = dfted.clone();
notSym.at<cv::Vec2f>(0, 1) = cv::Vec2f(1.3, 0.2);
notSym.at<cv::Vec2f>(2, 3) = cv::Vec2f(0.4, 1.0);

// idfted2:
// [1.1125  0.1  0.2875  0.6
//  0.5125  0.2  0.0875  0.2
//  0.6125  0.6  0.1875  0.9
//  0.3125  0.8  0.6875  0.2]
cv::Mat idfted2;
cv::idft(notSym, idfted2, DFT_REAL_OUTPUT | DFT_SCALE);

Here are the questions:

  • Q1. To apply cv::idft() for non-symmetric matrix Is a meaningful procedure? If so, what is the meaning of the result?
  • Q2. What is an implementation of cv::idft() with DFT_REAL_OUTPUT? Is there some reference?
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2015-12-24 02:12:06 -0600

LBerger gravatar image

updated 2015-12-24 02:17:36 -0600

You have to use a Mat with two channels like this : non hermitian symmetric

4.          2. - 2.i    0     2. + 2.i  
2. - 2.i  - 2.i         0     2.        
0           0           0     0         
2. + 2.i    2.          1.    3.i       


17. + i      16.    1. - i    - 2.   
17. - i      16.  - 1. - i      2.i  
- 1. - i       0    - 1. + i      2.   
- 1. + i       0      1. + i    - 2.i

and program is

int main(int ac, char** av) 
{
    Mat im(4,4,CV_32FC2);
    im.at<Vec2f>(0, 0) = Vec2f(4,0);
    im.at<Vec2f>(0, 1) = Vec2f(2,-2);
    im.at<Vec2f>(0, 2) = Vec2f(0,0);
    im.at<Vec2f>(0, 3) = Vec2f(2,2);

    im.at<Vec2f>(1, 0) = Vec2f(2,-2);
    im.at<Vec2f>(1, 1) = Vec2f(0,-2);
    im.at<Vec2f>(1, 2) = Vec2f(0,0);
    im.at<Vec2f>(1, 3) = Vec2f(2,0);

    im.at<Vec2f>(2, 0) = Vec2f(0,0);
    im.at<Vec2f>(2, 1) = Vec2f(0,0);
    im.at<Vec2f>(2, 2) = Vec2f(0,0);
    im.at<Vec2f>(2, 3) = Vec2f(0,0);

    im.at<Vec2f>(3, 0) = Vec2f(2,2);
    im.at<Vec2f>(3, 1) = Vec2f(2,0);
    im.at<Vec2f>(3, 2) = Vec2f(1,0);
    im.at<Vec2f>(3, 3) = Vec2f(0,3);

cout<<im<<endl;

Mat imx;
idft(im,imx);
cout<<imx<<endl;
return 0;
}
edit flag offensive delete link more

Comments

My example also uses 2ch mat like you. i.e. notSym is 2ch.

In your example, idft(im,imx) is equal to idft(im,imx, cv::DFT_COMPLEX_OUTPUT);. And no wonder the result has complex component, because I can get the same result by following a basic signal textbook.

My question is about the result of idft(im, imx, cv::DFT_REAL_OUTPUT). the result has only real component: [17, 15, 1, -1; 16, 16, 0, -0; -1, 1, -1, 1; 0, -0, 0, -0]

I would like to know the meaning of this and how to reproduce the result.

polycarbonate gravatar imagepolycarbonate ( 2015-12-24 07:15:06 -0600 )edit

Ok I understand but you try thing that's not in doc (I think) :

DFT_REAL_OUTPUT performs an inverse transformation of a 1D or 2D complex array; the result is normally a complex array of the same size, however, if the input array has conjugate-complex symmetry (for example, it is a result of forward transformation with DFT_COMPLEX_OUTPUT flag), the output is a real array; while the function itself does not check whether the input is symmetrical or not, you can pass the flag and then the function will assume the symmetry and produce the real output array (note that when the input is packed into a real array and inverse transformation is executed, the function treats the input as a packed complex-conjugate symmetrical array, and the output will also be a real array).

LBerger gravatar imageLBerger ( 2015-12-24 07:53:56 -0600 )edit

About format use in that case I think it's here

LBerger gravatar imageLBerger ( 2015-12-24 07:55:35 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-12-23 04:38:03 -0600

Seen: 3,853 times

Last updated: Dec 24 '15