2013-11-14 3 views
0

Я пытаюсь преобразовать этот простой код Matlab на C++ с использованием OpenCV:Имея трудности с FFT и IFFT в OpenCV

localstd=sqrt(abs(ifft2(fft2(output).*gf))); 

Это означает, принимая FFT матрицы «выход», умножая его поэлементно с матрицей «gf», а затем взяв ifft этого, а затем возьмем величину этого.

Я пытаюсь следующий простой код:

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

    dft(complexI, complexI,cv::DFT_SCALE); 
    for (int i=0;i<complexI.rows;i++){ 
     for (int j=0;j<complexI.cols;j++){ 
      complexI.at<float>(i,j)*=gf.at<float>(i,j); 
     } 
    } 

    //now the inverse transform 
    dft(complexI,complexI,cv::DFT_INVERSE); 
    split(complexI, planes);     // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I)) 
    magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude 
    Mat localstd = planes[0]; 

for (int i=0;i<localstd.rows;i++){ 
    for (int j=0;j<localstd.cols;j++){ 
     localstd.at<float>(i,j)= sqrt(localstd.at<float>(i,j)); 
    } 
} 

Это очень просто - я применяю FFT, получение комплексных результатов. Затем умножая элемент на элемент с gf, затем, взяв обратное преобразование, разделим результат на две матрицы - вещественные и мнимые - тогда беря их величину.

Однако, хотя это очень просто, и я не вижу никаких ошибок, результаты очень разные, чем то, что я получаю в Matlab. Слишком большое значение объясняется ошибками округления.

Может ли кто-нибудь указать мне, что я могу делать неправильно?

Я использую Matlab2013a, OpenCV 2.4.5 с VS 2012 на окнах 7.

Спасибо заранее,

Гиль.

EDIT: Я добавил sqrt результатов, но все еще существуют большие различия.

+0

Как вы определяете фильтр? –

ответ

1

В версии MatLAB вы берете квадратный корень из результата и в OpenCV - нет. Вы проверили это?

+0

В openCV я беру квадратный корень (Magnitude принимает квадратный корень). См. Здесь: http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html – GilLevi

+0

Я имею в виду, что в MatLAB вы берете _additional_ квадратный корень. Функция abs в MatLAB для сложных данных делает то же самое, что и значение в OpenCV http://www.mathworks.com/help/matlab/ref/abs.html –

+0

Спасибо, я добавил sqrt, но результаты все еще очень разные. – GilLevi

1

Хорошо, сразу с места в карьер Я вижу проблему с вашей фильтрацией. Я точно не знаю, что будет делать этот цикл, но для частотной фильтрации вы должны использовать функцию mulSpectrums.

Также, если вы хотите взять квадрат величины, вы можете использовать функцию sqrt OpenCV без необходимости проходить через оператора at.

+0

Спасибо, я постараюсь изменить свой код в соответствии с вашими комментариями. – GilLevi

+0

Нет проблем, надеюсь, что это поможет –

1

Если gf также является сложной матрицей, то есть CV_64FC2/CV_32FC2, вам, вероятно, необходимо использовать mulSpectrums. В противном случае, если вы хотите размножить их вместе самостоятельно, вы должны использовать std :: complex для доступа к этим сложным значениям. std :: complex возьмет на себя сложную операцию.

for (int i=0;i<complexI.rows;i++){ 
     for (int j=0;j<complexI.cols;j++){ 
      complexI.at<complex<double>>(i,j)*=gf.at<complex<double>>(i,j); 
     } 
    } 
+0

Спасибо за вашу помощь! – GilLevi

Смежные вопросы