【问题标题】:OpenCV Fourier Magnitude - doesn't seem correctOpenCV傅里叶幅度 - 似乎不正确
【发布时间】:2012-08-11 18:58:45
【问题描述】:

我相信我在尝试将傅里叶幅度谱转换为图像时遇到了缩放问题。

我正在开发自己的视觉里程计项目,以确定来自相机输入的连续帧之间的平移和旋转。我已经成功地使用傅立叶变换的相位相关确定平移,但是确定旋转的一部分需要对幅度谱进行卷积。基本上我产生的量级似乎并不正确,如下所示。

原图:

幅度,使用“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;
}

【问题讨论】:

  • 我认为 opencv 具有注册功能,可以满足您的需求(但方式不同)
  • 这个问题似乎更多的是关于FFTW而不是OpenCV。 This example 展示了如何使用 OpenCV 获取图像的 FFT。
  • 嗨,彼得,很抱歉,我的方法是基于 FFTW 的。我的理由是,经过研究,它计算离散傅立叶变换的速度比内置的 OpenCV 函数快得多。

标签: c image opencv fft fftw


【解决方案1】:

许多图像的光谱具有这样的特征 - 几个相对较高的峰,而场的其余部分在幅度上非常小。看起来你正在正常化,只是细节丢失了,因为大部分频谱的幅度非常小。如果您想检查细节,我经常发现使用 log(mag(spectrum))(甚至在某些情况下甚至 log(log(mag(spectrum))) 来生成图像更有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    相关资源
    最近更新 更多