簡體   English   中英

OpenCV傅立葉幅值-似乎不正確

[英]OpenCV Fourier Magnitude - doesn't seem correct

我相信在嘗試將傅立葉幅度譜轉換為圖像時遇到縮放問題。

我正在自己的視覺里程計項目上工作,以確定來自攝像機輸入的相應幀之間的平移和旋轉。 我已經成功地使用傅立葉變換的相位相關來確定平移,但是確定旋轉的一部分需要對幅度譜進行卷積。 基本上,我產生的幅度似乎不正確,如下所示。

原始圖片:
在此處輸入圖片說明

幅度,“ mag = 255 *(mag / max)”比例
在此處輸入圖片說明

幅度,無需縮放
在此處輸入圖片說明

不幸的是,我需要有關確定幅度的函數的幫助,我相信我的錯誤在於幅度的縮放,但不確定。 這個問題困擾了我一段時間,謝謝您的投入。

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;
}

許多圖像的光譜具有這樣的特征-幾個相對較高的峰,而場的其余部分幅度很小。 看起來您正在正確歸一化,只是細節丟失了,因為許多頻譜的幅度很小。 我經常發現,如果您想檢查細節,使用log(mag(spectrum))(甚至在某些情況下甚至使用log(log(mag(spectrum))))生成圖像會更有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM