图像处理分析-FFT

  • 格式:docx
  • 大小:12.85 KB
  • 文档页数:6

实验

名称 实验5:频域滤波

掌握图像进行频域滤波的方法和步骤。

实验

1、掌握图像频域 DFT变换和反变换的方法。

目的 2、掌握图像频域滤波的步骤

1、灰度图像的 DFT和IDFT。

具体内容:利用 OpenCV提供的cvDFT函数对图像进行 DFT 和IDFT变换

2、利用理想高通和低通滤波器对灰度图像进行频域滤波

实验 具体内容:利用 cvDFT函数实现 DFT,在频域上利用理想高通和低通滤波器进行滤波,并把滤波过后的

内容 图像显示在屏幕上(观察振铃现象) ,要求截止频率可输入。

3、利用布特沃斯高通和低通滤波器对灰度图像进行频域滤波。

具体内容:利用 cvDFT函数实现 DFT,在频域上进行利用布特沃斯高通和低通滤波器进行滤波,并把滤

波过后的图像显示在屏幕上(观察振铃现象) ,要求截止频率和 n可输入。

1、实验步骤:利用 OpenCV提供的cvDFT函数对图像进行

核心代码如下:

//DFT变换

Ipllmage *DFT(lpllmage * src)

{

IplImage* fourier = cvCreatelmage(cvGetSize(src),IPL_DEPTH_6

int dft_H, dft_W; DFT和IDFT变换

实验 4F,2);

完成 dft_H = src->height;

dft_W = src->width;

CvMat *src_Re = cvCreateMat(dft_H,dft_W, CV_64FC1); // double Re, Im; 情况 CvMat *src_Im = cvCreateMat(dft_H,dft_W, CV_64FC1); //Imagi nary part

CvMat *sum_src =cvCreateMat(dft_H,dft_W, CV_64FC2); 〃2 cha nn els (src_Re, src_lm)

CvMat *sum_dst =cvCreateMat(dft_H,dft_W, CV_64FC2); cvCon

vert(src, src_Re);

cvZero(src_lm);

cvMerge(src_Re, src_lm, 0, 0, sum_src);

cvDFT(sum_src,sum_dst,CV_DXT_FORW ARD,0); cvCon

vert(sum_dst, fourier);

cvReleaseMat(&src Re); 〃2 channels (dst_Re, dst_lm)

cvReleaseMat( &src_lm);

cvReleaseMat (& sum_src);

cvReleaseMat (& sum_dst);

return fourier;

}

〃DFT反变换

Ipllmage *IDFT(lpllmage * fourier)

{

IplImage* dst = cvCreatelmage(cvGetSize(fourier),IPL_DEPTH_8U,1);

int dft_H, dft_W;

dft_H = fourier->height;

dft_W = fourier->width;

CvMat *dst_Re = cvCreateMat(dft_H,dft_W, CV_64FC1); // double Re, Im;

CvMat *dst_lm = cvCreateMat(dft_H,dft_W, CV_64FC1); //Imagin ary part

CvMat *sum_dst =cvCreateMat(dft_H,dft_W, CV_64FC2); //2 chann els (dst_Re, dst_lm)

CvMat *sum_src = cvCreateMat(dft_H,dft_W, CV_64FC2 );

cvCon vert(fourier, sum_src);

cvDFT(sum_src,sum_dst,CV_DXT_INV_SCALE,O);

cvSplit(sum_dst,dst_Re,dst_lm,O,O);

cvCo nvert(dst_Re, dst);

cvReleaseMat( &dst_Re);

cvReleaseMat (& dst_lm);

cvReleaseMat (& sum_src);

cvReleaseMat (& sum_dst);

return dst;

}

//归一化,将灰度映射到 0~255之间,并将能量最高的四角移到中心 ,生成图片频域能量图

void BuildDFTImage(IplImage *fourier, Ipllmage *dst)

{

Ipllmage *image_Re = 0, *image_lm = 0;

image_Re = cvCreatelmage(cvGetSize(fourier), IPL_DEPTH_64F, 1);

image_lm = cvCreatelmage(cvGetSize(fourier), IPL_DEPTH_64F, 1); //Imagi nary part

cvSplit(fourier, image_Re, image_lm, 0, 0 );

// Compute the magn itude of the spectrum Mag = sqrt(ReA2 + ImA2)

cvPow( image_Re, image_Re, 2.0);

cvPow( image_lm, image_lm, 2.0);

cvAdd( image_Re, image_lm, image_Re);

cvPow( image_Re, image_Re, 0.5 );

cvReleaseImage(&im age」m);

cvAddS(image_Re, cvScalar(1.0), image_Re); // 1 + Mag

cvLog(image_Re, image_Re ); // log(1 + Mag)

〃重新安排傅里叶图像中心

// Rearrange the quadrants of Fourier image so that the origin is at

// the image cen ter

double minVal = 0, maxVal = 0; cvMinM axLoc( image_Re, &minV al, &maxVal ); // Localize minimum and maximum values

CvScalar mi n;

min. val[0] = mi nV al;

double scale = 255 / (maxVal - min Val); cvSubS(image_Re, mi n, image_Re);

cvCon vertScale(image_Re, dst, scale);

cvReleaselmage(&i mage_Re);

// Rearrange the quadrants of Fourier image so that the origin is at

// the image cen ter

int n Row, n Col, i, j, cy, cx;

uchar tmp13, tmp24;

n Row = fourier->height;

nCol = fourier->width;

cy = n Row/2; // image cen ter

cx = nCol/2;

for( j = 0; j < cy; j++ )

{

for( i = 0; i < cx; i++ )

{

tmp13 = CV_IMAGE_ELEM( dst, uchar, j, i);

CV_IMAGE_ELEM( dst, uchar, j, i) = CV_IMAGE_ELEM(dst, uchar, j+cy, i+cx);

CV_IMAGE_ELEM( dst, uchar, j+cy, i+cx) = tmp13;

tmp24 = CV_IMAGE_ELEM( dst, uchar, j, i+cx);

CV_IMAGE_ELEM( dst, uchar, j, i+cx) = CV_IMAGE_ELEM( dst, uchar, j+cy, i);

CV_IMAGE_ELEM( dst, uchar, j+cy, i) = tmp24;

}

}

}

实验结果如图:

2、实验步骤:利用 cvDFT函数实现 DFT,在频域上利用理想高通和低通滤波器进行滤波,并把滤波过

后的图像显示在屏幕上(观察振铃现象) ,截止频率可输入。

核心代码如下:

void PassFilter(IplImage * fourier, i nt FLAG, double d0, i nt n1)

{

int i, j;

int state = -1;

double tempD;

long width, height;

width = fourier->width;

height = fourier->height;

long x, y;

x = width / 2;

y = height / 2;

CvMat* H mat;

H_mat = cvCreateMat(fourier->height,fourier->width, CV_64FC2);

for(i = 0; i < height; i++){

for(j = 0; j < width; j++){ if(i > y &&

j > x){ state = 3;

}else if(i > y){

state = 1;

}else if(j > x){

state = 2;

}else{

state = 0;

} switch(state){ case 0:

tempD = (double)sqrt(1.0*i * i + j * j);break;

case 1:

tempD = (double)sqrt(1.0*(height - i) * (height - i) + j * j);break;

case 2:

tempD = (double)sqrt(1.0*i * i + (width - j) * (width - j));break;

case 3:

tempD = (double)sqrt(1.0*(height - i) * (height - i) + (width - j) * (width - j));break; default:

break;

} switch(FLAG){

case IDEAL_LOW: if(tempD <= D0){

((double*)(H_mat->data.ptr + H_mat->step * i))[j * 2] = 1.0; ((double*)(H_mat->data.ptr

+ H_mat->step * i))[j * 2 + 1] = 0.0;