Ask Your Question

FFT at 3D Mat

asked 2015-12-10 03:07:19 -0500

rourou11 gravatar image

updated 2015-12-11 03:57:17 -0500

Hello, I want to computing FFT at 3D matin C++: I have n images that I want to calculate FFT at z axe for each pixel(x,y), and as a result the n images of amplitude and phase... but I have no idea how to make that please help me. image description

cv::Mat phase;
 cv::Mat magI;
 cv::Mat I;
 cv::Mat padded;
 cv::Mat output;     
  cv::Mat ampIm; 
  I = imread(liste[0].toStdString().c_str(), CV_LOAD_IMAGE_GRAYSCALE);
 int rows=I.rows;
 int cols=I.cols;

 for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
     for(int k=0;k<liste.size();k++)

        I = imread(liste[k].toStdString().c_str(), CV_LOAD_IMAGE_GRAYSCALE);
       Vec3b color =<Vec3b>(Point(i,j));<Vec3b>(Point(j+i*(rows-1),k))=color;


   int m = cv::getOptimalDFTSize(output.rows );
  int n = getOptimalDFTSize( output.cols ); // on the border add zero values
  cv::copyMakeBorder(output, padded, 0, m - output.rows, 0, n - output.cols, BORDER_CONSTANT, Scalar::all(0));

cv::Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
cv::Mat complexI;
merge(planes, 2, complexI);         // Add to the expanded another plane with zeros

dft(complexI, complexI,cv::DFT_ROWS|cv::DFT_COMPLEX_OUTPUT);            // this way the result may fit in the        source matrix

split(complexI, planes);                   // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))

  cv::cartToPolar   (planes[0],planes[1],magI,phase,true);
     magI += Scalar::all(1);                    // switch to logarithmic scale
        log(magI, magI);

     for(int k=0;k<liste.size();k++){
    for(int i=0;i<rows;i++){
     for(int j=0;j<cols;j++){
     Vec3b colorF<Vec3b>(Point(j+i*(rows-1),k));<Vec3b>(Point(i,j))=colorF;
   //save ampIm;
edit retag flag offensive close merge delete


Seriously, you need to understand what a FFT means before trying to compute things that make nonsense

LorenaGdL gravatar imageLorenaGdL ( 2015-12-10 03:12:18 -0500 )edit

I read a lot fo tutorials but they always show how to compute FFT at 1 image "mat" i didn't find FFT of 3D and what about FFT means I have Idea

rourou11 gravatar imagerourou11 ( 2015-12-10 03:45:47 -0500 )edit

That is the idea: FFT is for a single image. What you can do is to compute the FFT for each image and then compare them.

In other words, DFT "converts a finite list of equally spaced samples of a function into the list of coefficients of a finite combination of complex sinusoids, ordered by their frequencies, that has those same sample values. It can be said to convert the sampled function from its original domain (often time or position along a line) to the frequency domain." Does this fit your approach? Does it make sense what you want to do?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-12-10 04:13:32 -0500 )edit

Maybe this could be interesting. Another idea that might help is to reformat the information in the manner that each position (x,y) is changing in time, so having a vector of size N, you can apply your FFT on it and have the modifications in time

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-12-10 04:50:20 -0500 )edit

YES thdrksdfthmn IT's probably near to my goal to applicate FFT on vector of size N (number of frame) at each (x,y) is changing in time but how in c++.

rourou11 gravatar imagerourou11 ( 2015-12-10 08:15:30 -0500 )edit

dft accepts vectors as input and output, so, just try it like that. I suppose you have seen this tutorial

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-12-10 09:09:50 -0500 )edit

I get the best idea to express may self and I try to compute the Fourier transform with respect to the time coordinate. I try to reshape my 3D cube into a 2D matrix, where the vertical coordinate is the pixel index (in the range [0, MN-1]) and the horizontal coordinate the time (range [0, T-1]), i.e. each row contains the values of one pixel in the sequence.and then apply the DFT routine along each row with the cv::dft() function and the flag which, M x N is the size of each frame and T is the total number of frames . but the code didn't run I suupose because of big size of mat output. How can I resolve this thdrksdfthmn???

rourou11 gravatar imagerourou11 ( 2015-12-11 03:54:08 -0500 )edit

This is a nice challenge! How big gets your matrix? How are your matrix, aren't they sparse?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-12-11 06:43:55 -0500 )edit

I definite my matrix like that and that change from sequence to other

cv::Mat output(rows*cols,liste.size(),CV_8UC3);
rourou11 gravatar imagerourou11 ( 2015-12-11 07:50:37 -0500 )edit

I am asking about the values of M, N, and how many images you have? How bis is your matrix: M*N x T?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2015-12-11 08:11:16 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2016-05-28 21:29:27 -0500

It seems that a 3D dft can be performed using 1D dft on each axis.

Maybe it is possible to use the DFT_ROWS flag to perform the dft in one dimension and a 2D dft to perform the dft in the other 2 dimensions. Some rearranging of pixels will maybe have to be performed too, to get the proper MAT input for the dft.

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2015-12-10 03:07:19 -0500

Seen: 1,245 times

Last updated: Dec 11 '15