Gilad - 1 year ago 727

C++ Question

I have already looked in this question

fftshift/ifftshift C/C++ source code

I'm trying to implement **fftshift from matlab**

this is the code *from the matlab* function for 1D array

`numDims = ndims(x);`

idx = cell(1, numDims);

for k = 1:numDims

m = size(x, k);

p = ceil(m/2);

idx{k} = [p+1:m 1:p];

end

y = x(idx{:});

my c++/openCV code is, what fftshift basically does is swap the values from a certain pivot place.

since I can't seem to understand how is the matrix built in opencv for complex numbers.

it says here

http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#dft

CCS (complex-conjugate-symmetrical

I thought it will be easier to split the complex numbers into real and imaginary and swap them. and then merge back to one matrix.

`cv::vector<float> distanceF (f.size());`

//ff = fftshift(ff);

cv::Mat ff;

cv::dft(distanceF, ff, cv::DFT_COMPLEX_OUTPUT);

//Make place for both the complex and the real values

cv::Mat planes[] = {cv::Mat::zeros(distanceF.size(),1, CV_32F), cv::Mat::zeros(distanceF.size(),1, CV_32F)};

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

int numDims = ff.dims;

for (int i = 0; i < numDims; i++)

{

int m = ff.rows;

int p = ceil(m/2);

}

my problem is that because of my input to the DFT is a

`vector<float>`

Can you think how a better way to make the swap of the values inside the cv::mat data struct?

Answer Source

this is for future reference: been tested and is bit accurate for 1D

```
cv::Mat ff;
cv::dft(distanceF, ff, cv::DFT_ROWS|cv::DFT_COMPLEX_OUTPUT);
//Make place for both the complex and the real values
cv::Mat planes[] = {cv::Mat::zeros(distanceF.size(),1, CV_32F), cv::Mat::zeros(distanceF.size(),1, CV_32F)};
cv::split(ff, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
int m = planes[0].cols;
int pivot = ceil(m/2);
//duplicate FFT results with Complex conjugate in order to get exact matlab results
for (int i = pivot + 1, k = pivot; i < planes[1].cols; i++, k--)
{
planes[1].at<float>(i) = planes[1].at<float>(k) * -1;
planes[0].at<float>(i) = planes[0].at<float>(k);
}
//TODO maybe we need to see what happens for pair and odd ??
float im = planes[1].at<float>(0);
float re = planes[0].at<float>(0);
for (int i = 0; i < pivot; i++)
{
//IM
planes[1].at<float>(i) = planes[1].at<float>(pivot + i +1);
planes[1].at<float>(pivot +i +1) = planes[1].at<float>(i +1);
//Real
planes[0].at<float>(i) = planes[0].at<float>(pivot + i +1);
planes[0].at<float>(pivot +i +1) = planes[0].at<float>(i +1);
}
planes[1].at<float>(pivot) = im;
planes[0].at<float>(pivot) = re;
```