I'm trying to implement fftshift from matlab for OpenCV. Can you please review the correctness of my algorithm? Have I missed something? Also, is there a better and faster way to do it?

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))

cv::vector<float> im(planes[1].cols);
cv::vector<float> re(planes[0].cols);
int m = planes[0].cols;
int p = ceil(m/2);

for (int i = 0; i < p; i++)
    im[i] = planes[1].at<float>(p + i +1); 
    im[p +i +1] = planes[1].at<float>(i +1);

    re[i] = planes[0].at<float>(p + i +1); 
    re[p +i +1] = planes[0].at<float>(i +1);
im[p] = planes[1].at<float>(0);
re[p] = planes[0].at<float>(0);
cv::Mat input[] = {cv::Mat(im),cv::Mat(re)};
  • 1
    \$\begingroup\$ You should replace the for loop with 2 copyTo() calls with the proper ROI set on the source and destination (use the () operator overload). \$\endgroup\$ Jan 5 '16 at 14:33

I think the best way to implement fftshift is like it is done in OpenCv itself:

//The body is inspired from OpenCV, the fct_fftshift is mine
void fct_fftshift(cv::Mat& src)
    int cx = src.cols/2;
    int cy = src.rows/2;

    cv::Mat q0(src, cv::Rect(0, 0, cx, cy));   
    cv::Mat q1(src, cv::Rect(cx, 0, cx, cy));  
    cv::Mat q2(src, cv::Rect(0, cy, cx, cy));  
    cv::Mat q3(src, cv::Rect(cx, cy, cx, cy)); 

    cv::Mat tmp;                           


int main(int argc, char* argv[])
  cv::Mat src=cv::imread(argv[1], CV_8UC1);
  fct_fftshift(src); //it will change your original image

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.