# Trouble with DFT Complex output

**URL:** <https://forum.opencv.org/t/trouble-with-dft-complex-output/8731>\
**Category:** C++\
**Tags:** imgproc, core\
**Created:** [May 10, 2022, 8:21pm UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731 "2022-05-10T20:21:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tehfury87](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/tehfury87/32/5179_2.png) [@tehfury87](https://forum.opencv.org/u/tehfury87)\
**Post date:** [May 10, 2022, 8:21pm UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731/1 "2022-05-10T20:21:42Z")

</div>

I am trying to do a 2D FFT with complex input and output and I am not getting the expected results in the imaginary part. Using OpenCV 4.5.1 on Debian 11.

Here is my code:

```auto
    const cv::Size imgSize = { 256, 256 };
    cv::Mat I = cv::Mat::zeros(imgSize, CV_64FC1);
    cv::circle(I, {imgSize.width/2, imgSize.height/2}, imgSize.height/2-1,
               cv::Scalar::all(1.0), cv::FILLED, cv::LINE_4);
    cv::imshow("Intensity", I);
    cv::Mat phase = cv::Mat::zeros(imgSize, CV_64FC1);
    cv::imshow("Phase", phase);

    // Make complex matrix
    cv::Mat planesIn[] = { I, phase };
    cv::Mat complexFieldIn = cv::Mat::zeros(imgSize, CV_64FC2);
    cv::merge(planesIn, 2, complexFieldIn);

    cv::Mat complexFieldOut = cv::Mat::zeros(imgSize, CV_64FC2);
    cv::dft(complexFieldIn, complexFieldOut, cv::DFT_COMPLEX_INPUT|cv::DFT_COMPLEX_OUTPUT);
    std::cout << complexFieldOut.rows << "x" << complexFieldOut.cols
              << " " << complexFieldOut.depth() << " " << complexFieldOut.type()
              << " " << complexFieldOut.elemSize1()
              << " " << complexFieldOut.step1() << std::endl;

    fftshift(complexFieldOut); // (impl. copied from example code)

    cv::Mat planesOut[] = { cv::Mat::zeros(imgSize, CV_64FC1), cv::Mat::zeros(imgSize, CV_64FC1) };
    cv::split(complexFieldOut, planesOut);

    // Normalize for display
    cv::Mat real, imag;
    cv::normalize(planesOut[0], real, 0, 1, cv::NORM_MINMAX);
    cv::imshow("REAL", real);
    cv::normalize(planesOut[1], imag, 0, 1, cv::NORM_MINMAX);
    cv::imshow("IMAG", imag);

    // Compute magnitude
    cv::Mat magI;
    cv::magnitude(planesOut[0], planesOut[1], magI);

    // Normalize for display
    cv::normalize(magI, magI, 0, 10, cv::NORM_MINMAX);
    cv::imshow("Magnitude", magI);

```

Here is the output (normalized for display):

 ![image](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/7/7d3b814811aab465ab70962c9234e0ee4cdeb42c.jpeg)

And here is the output from the equivalent in MATLAB using fft2:  
(forum not letting me upload another image here)

What is happening with the imaginary part in the OpenCV implementation?

---

<div class="post-metadata">

**Author:** ![tehfury87](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/tehfury87/32/5179_2.png) [@tehfury87](https://forum.opencv.org/u/tehfury87)\
**Post date:** [May 10, 2022, 8:27pm UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731/2 "2022-05-10T20:27:29Z")

</div>

Here is what I’m expecting, from MATLAB:

 ![image](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/7/70145e06f2e48f150f3f9edc7865be25d1b67f2d.jpeg)

---

<div class="post-metadata">

**Author:** ![tehfury87](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/tehfury87/32/5179_2.png) [@tehfury87](https://forum.opencv.org/u/tehfury87)\
**Post date:** [May 11, 2022, 1:30am UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731/3 "2022-05-11T01:30:45Z")

</div>

I see now the trouble is with the test input, with drawing a circle using cv::circle, which puts it off by one pixel.

---

<div class="post-metadata">

**Author:** ![crackwitz](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/crackwitz/32/14_2.png) [@crackwitz](https://forum.opencv.org/u/crackwitz)\
**Post date:** [May 11, 2022, 8:04am UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731/4 "2022-05-11T08:04:47Z")

</div>

you might also wanna check whether matlab “shifts” the spectrum to put DC in the middle, or not.

---

<div class="post-metadata">

**Author:** ![tehfury87](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/tehfury87/32/5179_2.png) [@tehfury87](https://forum.opencv.org/u/tehfury87)\
**Post date:** [May 11, 2022, 8:17pm UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731/5 "2022-05-11T20:17:31Z")

</div>

MATLAB requires an fftshift to move the origin to the center just like numpy and opencv (though OpenCV doesn’t provide the function)

---

<div class="post-metadata">

**Author:** ![tehfury87](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/tehfury87/32/5179_2.png) [@tehfury87](https://forum.opencv.org/u/tehfury87)\
**Post date:** [May 11, 2022, 8:30pm UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731/6 "2022-05-11T20:30:29Z")

</div>

I am still getting some bizarre results when adding an imaginary component. Say I put in a gradient for the “phase” array above.  
What I am expecting is this that the spot in the center moves over some number of pixels, depending on how big the gradient is.  
But what I am getting is this:  
 ![image](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/0/0bcceb927e436f4c6c97a68d8d85ed75bbeb8347.png)

Is it possible OpenCV wraps the imaginary part (like -1 to 1 or something?). It’s clearly not ignoring it, but it’s not doing what I would expect.

---

<div class="post-metadata">

**Author:** ![tehfury87](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/tehfury87/32/5179_2.png) [@tehfury87](https://forum.opencv.org/u/tehfury87)\
**Post date:** [May 11, 2022, 8:32pm UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731/7 "2022-05-11T20:32:27Z")

</div>

Again desired result from MATLAB:  
 ![image](https://us1.discourse-cdn.com/flex020/uploads/opencv/original/2X/1/106bdf6982ea6c5537aa86fc8ecf4275e66d22a9.png)  
(spot is shifted over 30 pixels)

---

<div class="post-metadata">

**Author:** ![tehfury87](https://sea2.discourse-cdn.com/flex020/user_avatar/forum.opencv.org/tehfury87/32/5179_2.png) [@tehfury87](https://forum.opencv.org/u/tehfury87)\
**Post date:** [May 12, 2022, 5:08pm UTC](https://forum.opencv.org/t/trouble-with-dft-complex-output/8731/8 "2022-05-12T17:08:25Z")

</div>

Ah it was the input again. I was missing this line from the MATLAB to convert to complex:  
P = `I.*exp(1j*Phase);`  
Any way to do this with OpenCV matrices without a loop? Pretty straightforward to write my own matrix exp() function using std::complex.
