2013-11-18 4 views
-1

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

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

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

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

Mat complexI; 
dft(output, complexI,cv::DFT_SCALE||DFT_COMPLEX_OUTPUT); 
Mat copmlexI2=Mat(n,n,CV_32F); 
mulSpectrums(complexI,gf,copmlexI2,DFT_COMPLEX_OUTPUT); 
dft(copmlexI2,copmlexI2,cv::DFT_INVERSE||DFT_COMPLEX_OUTPUT); 

Mat planes[]= {Mat::zeros(output.size(), CV_32F), Mat::zeros(output.size(), CV_32F)};; 
split(copmlexI2, 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)); 
    } 
} 

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

Это очень просто. Я беру dft «output», умножаю его спектр на «df» и принимаю ifft из этого. Затем я разбиваю результат на реальную и мнимую плоскость и беру величину. Наконец, я беру sqrt этого и нормализую, делясь на 255.

Результаты, которые я получаю, сильно отличаются от того, что я получаю в Matlab. Что мне здесь не хватает? Любые идеи о том, как исправить код?

Заранее благодарен!

+0

Ну, на первый взгляд, похоже, что вы вызываете 2D fft в MATLAB и 1D fft в OpenCV: может быть, это и есть причина? – fpe

+0

Как они отличаются? Можете ли вы предоставить изображения? – Bull

+0

@fpe, вы уверены, что это 1D fft? Что функция выполняет 2D fft в opencv? Благодаря! – GilLevi

ответ

6

Это не правильно

cv::DFT_INVERSE||DFT_COMPLEX_OUTPUT 

, если вы хотите объединить двоичные значения, вы должны использовать "двоичный или":

cv::DFT_INVERSE | DFT_COMPLEX_OUTPUT 

или + операция

cv::DFT_INVERSE + DFT_COMPLEX_OUTPUT 

|| B - логично или. A, B и результат могут быть истинными или ложными.

A | B - побитовое или.

Вы также можете попробовать флаг DFT_SCALE.

DFT_SCALE масштабирует результат: разделите его на число массивов элементов. Обычно он объединяется с DFT_INVERSE.

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