简体   繁体   中英

OpenCV Fourier Magnitude - doesn't seem correct

I believe I am having a scaling issue in trying to convert the Fourier magnitude spectrum to an Image.

I am working on my own visual odometry project to determine the translation and rotation between consequtive frames from a camera input. I have been successful with determining translation using phase correlation of the fourier transform, however part of determining the rotation requires the magnitude spectrum to be convolved. Essentially the magnitude I have produced does not seem correct, as below.

Original Image:
在此处输入图片说明

Magnitude, with the 'mag = 255*(mag/max)' scaling
在此处输入图片说明

Magnitude, without the scaling
在此处输入图片说明

Unfortunately I would require help as to the function I am using to determine the magnitude, I believe my error is in the scaling of the magnitude but am unsure exactly. This issue has had me for some time and your input would be appreciated, thankyou.

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

The spectrum of many images have characteristics like this - several relatively high peaks with the rest of the field quite small in magnitude. It looks like you're normalizing right, it's just that the details are lost because the magnitude of much of the spectrum is very small. I've often found it more useful to use log(mag(spectrum)) (or even log(log(mag(spectrum))) in some cases) to generate an image if you're wanting to inspect details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM