1

我正在尝试生成简单图像的傅立叶光谱。但我得到的只是噪音。我尝试关注许多链接,这些链接建议缩小两者之间的值,[0, 255]但即使在缩放之后我也只能得到黑色图像,我这样做是这样的:

缩放代码:

//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(dft[k][0]*dft[k][0] + dft[k][6]*dft[k][7]);
                if (max < mag)
                    max = mag;
            }
        }

请注意,我没有采用dft数组的第一个值,因为它太大(因为它是 DC 值)。也就是说,我是从k=1forloop图开始的。

后来我这样做是为了缩放

mag = 255 * (mag/max) ;  

没有缩放的代码:

#include <stdio.h>
#include "cv.h"
#include "highgui.h"
#include "fftw3.h"

/**
 * Sample code to compute the DFTs of IplImage
 */
 
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 = cvClone(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);
  idft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);

  /* Create plans */
  plan_f = fftw_plan_dft_2d(w, h, in, dft, FFTW_FORWARD, FFTW_ESTIMATE);
  plan_b = fftw_plan_dft_2d(w, h, dft, idft, FFTW_BACKWARD, 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;
        //printf( "%f\n" , in[k][0] ); 
    }
  }

  /* Forward & inverse DFT */
  fftw_execute(plan_f);
  fftw_execute(plan_b);
  
  double max, min = 0;
  
  /* Create output image */
  img2 = cvCreateImage(cvSize(w, h), 8, 1);
   
  /* Convert DFT result to output image */
  for (i = 0, k = 0; i < h; i++)
  {
    for (j = 0; j < w; j++, k++){
         
        double mag = sqrt(dft[k][0]*dft[k][0] + dft[k][2]*dft[k][3]);
        
      ((uchar*)(img2->imageData + i * img2->widthStep))[j] = mag;
    }
  }

    //printf("max : %f min : %f \n ", max, min );

  cvShowImage("iplimage_dft(): original", img1);
  cvShowImage("iplimage_dft(): result", img2);
  cvWaitKey(0);

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

int main( int argc, char** argv )
{
    IplImage *img3 = cvLoadImage( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
    iplimage_dft(img3);
    return 0;
}

输出: 使用上面的代码我只会得到噪音

但是如果我像这样引入缩放: 缩放后的​​代码

#include <stdio.h>
#include "cv.h"
#include "highgui.h"
#include "fftw3.h"

/**
 * Sample code to compute the DFTs of IplImage
 */
 
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 = cvClone(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);
  idft = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);

  /* Create plans */
  plan_f = fftw_plan_dft_2d(w, h, in, dft, FFTW_FORWARD, FFTW_ESTIMATE);
  plan_b = fftw_plan_dft_2d(w, h, dft, idft, FFTW_BACKWARD, 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][5] = 0.0;
        //printf( "%f\n" , in[k][0] ); 
    }
  }

  /* Forward & inverse DFT */
  fftw_execute(plan_f);
  fftw_execute(plan_b);
  
  
  /* 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(dft[k][0]*dft[k][0] + dft[k][6]*dft[k][7]);
            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(dft[k][0]*dft[k][0] + dft[k][8]*dft[k][9]);
        
        //Scaling
        mag = 255 * (mag/max);
        
      ((uchar*)(img2->imageData + i * img2->widthStep))[j] = mag;
    }
  }

    //printf("max : %f min : %f \n ", max, min );

  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_destroy_plan(plan_b);
  fftw_free(in);
  fftw_free(dft);
  fftw_free(idft);
  cvReleaseImage(&img1);
  cvReleaseImage(&img2);
}

int main( int argc, char** argv )
{
    IplImage *img3 = cvLoadImage( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
    iplimage_dft(img3);
    return 0;
}

缩放后的输出 缩放后

请告诉我我做错了什么?我应该如何进行缩放以获得正确的图像光谱。

4

2 回答 2

4

我在这个链接上找到了解决方案:http: //www.admindojo.com/discrete-fourier-transform-in-c-with-fftw/

我正在使用 OpenCV 及其部分工作来实现相同的功能。我会提出我的解决方案,我会完成的。

干杯!

编辑 2013 年 4 月 4 日:

我使用 OpenCV 只是为了显示图像,但为了计算 FFT,我使用了 FFTW 库。这非常简单直接。

于 2012-03-21T18:16:19.357 回答
2

你做的一切都是对的,但你需要一个对数尺度来查看傅立叶系数的典型小值变化的影响(就像在你的解决方案中,输出中有小的白色域)。然后大的值将是白色的,小的变化将变成你正在寻找的。即使您没有使用 OpenCV(此处为 v. 2.4.2),您也可以在此处找到一个完整的教程,除了理论之外还描述了它非常酷:http: //docs.opencv.org/doc/tutorials/core/discrete_fourier_transform /discrete_fourier_transform.html

我刚看到你的问题。也许答案来得太晚了,但它可能会在未来对其他人有所帮助。那么您能否将这个答案投票为您的问题的正确答案?我是stackoverflow的新手,需要一些声誉才能完全参与^^

于 2012-10-19T09:09:33.583 回答