我正在尝试生成简单图像的傅立叶光谱。但我得到的只是噪音。我尝试关注许多链接,这些链接建议缩小两者之间的值,[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=1
上forloop
图开始的。
后来我这样做是为了缩放
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;
}
缩放后的输出
请告诉我我做错了什么?我应该如何进行缩放以获得正确的图像光谱。