DFT和FFT之间的差异(幅度)结果

时间:2015-06-01 10:53:19

标签: opencv dft

我的目标是在OpenCV中获取图像的DFT

使用dft函数,我能够计算它,然后通过计算它的大小来绘制它(然后,应用日志并最终对其进行标准化以绘制介于0和1之间的值)。

我的结果是,对于下面的图像,我给你看的结果(为了在图像的中心有较低的频率而使用交换):

Original picture DFT magnitude

然而,如果我把它与我使用Halcon之类的其他工具获得的结果进行比较,那对我来说似乎是不正确的,因为它似乎真的很高"高"值(我的意思是OpenCV DFT幅度):

FFT Halcon

我认为可能是出于以下原因:

  1. DFT (在OpenCV)和 FFT (Halcon)之间的差异
  2. 为了在OpenCV中显示幅度而执行的操作。
  3. 第一个问题是我很难分析,OpenCV没有FFT功能,Halcon也没有有DFT功能(如果我当然没有错),所以我无法直接比较它。

    第二个是我工作时间最长的一个,但我仍然找不到原因。

    我使用的代码用于绘制img(这是我的DFT图像)的幅度:

    // 1.- To split the image in Re | Im values
    Mat planes[] = {Mat_<float>(img), Mat::zeros(img.size(), CV_32F)};
    
    // 2.- To magnitude + phase
    split(img, planes);
    
    // Calculate magnitude. I overwrite it, I know, but this is inside a function so it will be never used again, doesn't matter
    magnitude(planes[0], planes[1], planes[0]);
    
    // Magnitude Mat
    Mat magI = planes[0];
    
    // 3.- We add 1 to all them in order to perform the log
    magI += Scalar::all(1);                    // switch to logarithmic scale
    log(magI, magI);
    
    // 4.- Swap the quadrants to center frequency
    magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));
    int cx = magI.cols/2;
    int cy = magI.rows/2;
    
    Mat q0(magI, Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
    Mat q1(magI, Rect(cx, 0, cx, cy));  // Top-Right
    Mat q2(magI, Rect(0, cy, cx, cy));  // Bottom-Left
    Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right
    
    // swap quadrants (Top-Left with Bottom-Right)
    Mat tmp;
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);
    
    // swap quadrant (Top-Right with Bottom-Left)
    q1.copyTo(tmp);
    q2.copyTo(q1);
    tmp.copyTo(q2);
    
    // 5.- Normalize
    // Transform the matrix with float values into a
    // viewable image form (float between values 0 and 1).
    normalize(magI, magI, 0, 1, CV_MINMAX); 
    
    // Paint it
    imshow( "Magnitud DFT", magI);
    

    总结:关于为什么我在这两个数量之间存在这种差异的任何想法

1 个答案:

答案 0 :(得分:3)

我会将我的评论总结为答案。

当人们考虑进行傅立叶变换以在逆域中工作时,假设进行逆变换将返回相同的函数/向量/无论什么。换句话说,我们假设

Inverse transform of a transform yields the original function

许多程序和库都是这种情况(例如Mathematica,Matlab / octave,Eigen/unsupported/FFT等)。但是,对于许多库(FFTWKissFFT等),情况并非如此,而且往往存在规模

Inverse transform of a transform yields a scaled original function

其中s通常是数组中元素(m)的数量与某事物的幂(如果在变换和反向中不以不匹配的方式缩放,则应为1)。这样做是为了避免迭代所有m元素乘以一个标度,通常为not important

话虽如此,当观察逆域中的比例时,缩放变换的各种库可以自由地使用不同的比例进行变换和逆变换。变换/逆的公共缩放对包括{m^-1m}和{m^-0.5m^0.5}。因此,在比较来自不同库的结果时,我们应该准备好m(按m^-1缩放而非缩放),m^0.5(按m^-0.5缩放比例的因子如果使用其他缩放因子,则不会按m^-1缩放比例缩放比例缩放m^-0.5)甚至其他缩放比例。

注意:此缩放因子与规范化数组有关,因此所有值均为[0,1]或数组的范数等于1。