《数字图像处理》学习笔记(五)--傅里叶变换

来源:互联网 发布:手机屏幕监控软件 编辑:程序博客网 时间:2024/05/20 15:10

一、一维傅里叶变换及其反变换

  单变量离散函数f(x)(其中x=0,1,2,....,M-1)的傅里叶变换F(u)定义为等式:

同样给出F(u),能用逆DFT来获得原函数:

从欧拉公式中得到:

得出:

一个恰当的比喻是将傅里叶变换比做一个玻璃棱镜。棱镜是可以将光分成不同颜色成分的物理仪器,每个成分的颜色由波长(或频率)决定。傅里叶变换可看做“数学的棱镜”,将函数基于频率分成不同的成分。当我们考虑光时,讨论它的光谱或频率谱线。同样,傅里叶变换使我们能够通过频率成分来分析一个函数。这是属于线型滤波核心的重要概念。

  而在复数的分析下,我们发现有时在极坐标下表示F(u)很方便:

上式称为傅里叶变换的幅度或频率谱,同时

上式称为变换的相角或相位谱。

这里还有个概念叫做功率谱:

二、二维傅里叶变换

  这里主要说下二维傅里叶图像处理的步骤:

  (1)分别定义两个单通道浮点型图像,表示实部和虚部,对实部赋值,虚部置0,

  (2)合并上面定义的两个单通道图像,并做二维傅里叶变换

  (3)对二维傅里叶变换处理后的图像拆分成两个单通道浮点型图像,表示处理后的实部与虚部

  (4)求频谱的傅里叶谱值,首先进行对数变换,以将窄带低灰度输入图像映射到宽带高灰度输出图像上

  (5)然后对图像进行中心化处理

 

  (6)对图像进行归一化处理-->8u(0-255),通过公式:255*(Xk-Xmin)/(Xmax-Xmin)

  (7)对图像做带收缩的逆傅里叶变换

  (8)同(6)归一化处理得到原图

#include "dipHeader.h"void fft2(IplImage* timg,IplImage* fimg){IplImage* img_re;IplImage* img_im;IplImage* fourier;img_re = cvCreateImage(cvGetSize(timg),IPL_DEPTH_64F,1);  //实部img_im = cvCreateImage(cvGetSize(timg),IPL_DEPTH_64F,1);  //虚部fourier = cvCreateImage(cvGetSize(timg),IPL_DEPTH_64F,2); cvConvertScale(timg, img_re);cvZero(img_im); cvMerge(img_re,img_im,0,0,fourier);cvDFT(fourier,fimg,CV_DXT_FORWARD);cvReleaseImage(&img_im);cvReleaseImage(&img_re);cvReleaseImage(&fourier);}//分别对换I III和II IV象限void fft2shift(IplImage*fimg, IplImage* shiftimg){IplImage* img_re;IplImage* img_im;IplImage* fourier;img_re = cvCreateImage(cvGetSize(fimg),IPL_DEPTH_64F,1);  //实部img_im = cvCreateImage(cvGetSize(fimg),IPL_DEPTH_64F,1);  //虚部cvSplit(fimg,img_re,img_im,0,0);//compute the Fourier magtitudecvPow(img_re,img_re,2.0);cvPow(img_im,img_im,2.0);cvAdd(img_re,img_im,img_re);cvPow(img_re,img_re,0.5);//对数变换以加宽窄带低灰度输入图像cvAddS(img_re,cvScalar(1.0),img_re);cvLog(img_re,img_re);int row,col,colwidth;row = fimg->height;col = fimg->width;int xCenter, yCenter;xCenter = col/2;yCenter = row/2;double tmp13,tmp24;for (int x=0;x<xCenter;x++){for(int y=0;y<yCenter;y++){tmp13= CV_IMAGE_ELEM(img_re,double, x, y);CV_IMAGE_ELEM(img_re,double,x,y) = CV_IMAGE_ELEM(img_re,double,x+xCenter,y+yCenter);CV_IMAGE_ELEM(img_re,double,x+xCenter,y+yCenter)= tmp13;tmp24= CV_IMAGE_ELEM(img_re,double,x,y+yCenter);CV_IMAGE_ELEM(img_re,double,x,y+yCenter)=CV_IMAGE_ELEM(img_re,double,x+xCenter,y);CV_IMAGE_ELEM(img_re,double,x+xCenter,y)=tmp24;}}//归一化为 8u double minVal,maxVal;double scale,shift;cvMinMaxLoc(img_re,&minVal, &maxVal);scale = 255/(maxVal-minVal);shift = -minVal*scale;cvConvertScale(img_re,shiftimg,scale,shift);cvReleaseImage(&img_re);cvReleaseImage(&img_im);}void main(){IplImage *src;    IplImage *Fourier;   //傅里叶系数       IplImage *dst ;      IplImage *ImageRe;      IplImage *ImageIm;      IplImage *Image;      IplImage *ImageDst;      double m,M;      double scale;      double shift;  IplImage* workImg = cvLoadImage("fft.tif",0);      //src = workImg;       //if(workImg->nChannels==3)  //  OnColorToGray();      src=cvCreateImage(cvGetSize(workImg),IPL_DEPTH_64F,workImg->nChannels);  //源图像       //cvCloneImage(workImg,&src);  src = cvCloneImage(workImg);    cvFlip(src);      Fourier = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,2);      dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,2);      ImageRe = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);      ImageIm = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);      Image = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);      ImageDst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);      fft2(src,Fourier);                  //傅里叶变换       fft2shift(Fourier, Image);          //中心化       cvDFT(Fourier,dst,CV_DXT_INV_SCALE);//实现傅里叶逆变换,并对结果进行缩放       cvSplit(dst,ImageRe,ImageIm,0,0);      cvNamedWindow("源图像",0);      cvShowImage("源图像",src);                   //对数组每个元素平方并存储在第二个参数中       cvPow(ImageRe,ImageRe,2);                     cvPow(ImageIm,ImageIm,2);      cvAdd(ImageRe,ImageIm,ImageRe,NULL);      cvPow(ImageRe,ImageRe,0.5);      cvMinMaxLoc(ImageRe,&m,&M,NULL,NULL);      scale = 255/(M - m);      shift = -m * scale;      //将shift加在ImageRe各元素按比例缩放的结果上,存储为ImageDst       cvConvertScale(ImageRe,ImageDst,scale,shift);      cvNamedWindow("傅里叶谱",0);      cvShowImage("傅里叶谱",Image);      cvNamedWindow("傅里叶逆变换",0);      cvShowImage("傅里叶逆变换",ImageDst);      //释放图像       cvWaitKey(0);      cvReleaseImage(&src);      cvReleaseImage(&Image);      cvReleaseImage(&ImageIm);      cvReleaseImage(&ImageRe);      cvReleaseImage(&Fourier);      cvReleaseImage(&dst);      cvReleaseImage(&ImageDst);  }


0 0
原创粉丝点击