2012-08-15 65 views
1

我相信我在嘗試將傅里葉幅度譜轉換爲圖像時遇到縮放問題。OpenCV傅立葉幅度 - 似乎不正確

我正在開發自己的視覺測距項目,以確定攝像機輸入的攝影幀之間的平移和旋轉。我使用傅里葉變換的相位相關性來確定轉換的成功,但是確定旋轉的部分需要幅度譜被卷積。基本上我產生的數量似乎並不正確,如下所示。

原始圖像:
enter image description here

幅度,用 'MAG = 255 *(MAG /最大)' 縮放
enter image description here

幅度,而不縮放
enter image description here

不幸的是我會需要幫助,我正在使用的功能來確定幅度,我相信我的錯誤是在幅度的縮放,但我不確定。這個問題已經讓我有一段時間了,你的意見將不勝感激,謝謝。

void iplimage_dft(IplImage* img) 
{ 
    IplImage*  img1, * img2; 
    fftw_complex* in, * dft, * idft; 
    fftw_plan  plan_f, plan_b; 
    int   i, j, k, w, h, N; 

    /* Copy input image */ 
    img1 = cvCloneImage(img); 

    w = img1->width; 
    h = img1->height; 
    N = w * h; 

    /* Allocate input data for FFTW */ 
    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); 
    dft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); 

    /* Create plans */ 
    plan_f = fftw_plan_dft_2d(w, h, in, dft, FFTW_FORWARD, FFTW_ESTIMATE); 

    /* Populate input data in row-major order */ 
    for (i = 0, k = 0; i < h; i++) 
    { 
     for (j = 0; j < w; j++, k++) 
     { 
      in[k][0] = ((uchar*)(img1->imageData + i * img1->widthStep))[j]; 
      in[k][1] = 0.0; 
     } 
    } 

    /* Forward & inverse DFT */ 
    fftw_execute(plan_f); 

    /* Create output image */ 
    img2 = cvCreateImage(cvSize(w, h), 8, 1); 

    //Find the maximum value among the magnitudes 
    double max=0; 
    double mag=0; 
    for (i = 0, k = 1; i < h; i++){ 
     for (j = 0; j < w; j++, k++){ 
      mag = sqrt(pow(dft[k][0],2) + pow(dft[k][1],2)); 
      if (max < mag) 
       max = mag; 
     } 
    } 

    // Convert DFT result to output image 
    for (i = 0, k = 0; i < h; i++) 
    { 
     for (j = 0; j < w; j++, k++) 
     { 
      double mag = sqrt(pow(dft[k][0],2) + pow(dft[k][1],2)); 
      mag = 255*(mag/max); 
      ((uchar*)(img2->imageData + i * img2->widthStep))[j] = mag; 
     } 
    } 

    cvShowImage("iplimage_dft(): original", img1); 
    cvShowImage("iplimage_dft(): result", img2); 
    //cvSaveImage("iplimage_dft.png", img2,0); 
    cvWaitKey(0); 

    /* Free memory */ 
    fftw_destroy_plan(plan_f); 
    fftw_free(in); 
    fftw_free(dft); 
    cvReleaseImage(&img1); 
    cvReleaseImage(&img2); 
} 

int main(int argc, char** argv) 
{ 
    argv[1] = "image1.jpg"; 

    IplImage *img3 = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE); 
    iplimage_dft(img3); 
    return 0; 
} 
+0

我認爲opencv有一個註冊函數,它可以完成你可能需要的功能(但用不同的方式) – Gir 2012-08-15 14:11:47

+0

這個問題似乎比OpenCV更多關於[FFTW](http://www.fftw.org/)。 [這個例子](http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html)展示瞭如何使用OpenCV獲取圖像的FFT。 – 2012-08-15 14:23:09

+0

嗨,彼得,是的,我的方法基於FFTW。我的推理是,經過研究,它計算出的離散傅立葉變換比內置的OpenCV函數快得多。 – Josh 2012-08-17 00:29:13

回答

0

許多圖像的光譜具有這樣的特徵 - 幾個相對較高的峯值,其餘的光場的幅度相當小。看起來你正確的正確,只是細節丟失了,因爲大部分頻譜的幅度非常小。如果你想檢查細節,我經常發現它在某些情況下使用log(mag(spectrum))(甚至log(log(mag(spectrum)))來生成圖像更有用。