OpenCV实现傅里叶变换

[cpp]  view plain copy
  1. <span style="font-size:18px;">#include <stdio.h>  
  2. #include <cv.h>  
  3. #include <cxcore.h>  
  4. #include <highgui.h>  
  5.   
  6.   
  7. /************************************************************************** 
  8. //傅里叶变换 
  9. //src IPL_DEPTH_8U 
  10. //dst IPL_DEPTH_64F 
  11. /**************************************************************************/  
  12.   
  13.   
  14. void fft2(IplImage *src, IplImage *dst)  
  15. {    
  16.     IplImage *image_Re = 0, *image_Im = 0, *Fourier = 0; //实部、虚部  
  17.   
  18.   
  19.     image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);  //实部  
  20.   
  21.   
  22.     image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);  //虚部  
  23.   
  24.   
  25.     Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 2);//2 channels (image_Re, image_Im)  
  26.   
  27.   
  28.     cvConvertScale(src, image_Re, 1, 0);// Real part conversion from u8 to 64f (double)  
  29.   
  30.   
  31.     cvZero(image_Im);// Imaginary part (zeros)  
  32.   
  33.   
  34.     cvMerge(image_Re, image_Im, 0, 0, Fourier);// Join real and imaginary parts and stock them in Fourier image  
  35.   
  36.   
  37.     cvDFT(Fourier, dst, CV_DXT_FORWARD);// Application of the forward Fourier transform  
  38.   
  39.   
  40.     cvReleaseImage(&image_Re);  
  41.     cvReleaseImage(&image_Im);  
  42.     cvReleaseImage(&Fourier);  
  43. }  
  44.   
  45.   
  46. /************************************************************************** 
  47. //中心化 
  48. //src IPL_DEPTH_64F 
  49. //dst IPL_DEPTH_8U 
  50. **************************************************************************/  
  51. void fft2shift(IplImage *src, IplImage *dst)  
  52. {  
  53.     IplImage *image_Re = 0, *image_Im = 0;  
  54.     int nRow, nCol, i, j, cy, cx;  
  55.     double scale, shift, tmp13, tmp24;  
  56.   
  57.   
  58.     image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);  
  59.   
  60.   
  61.     image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_64F, 1);  
  62.     cvSplit( src, image_Re, image_Im, 0, 0 );  
  63.   
  64.   
  65.     //具体原理见冈萨雷斯数字图像处理p123  
  66.     // Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)  
  67.     //计算傅里叶谱  
  68.     cvPow( image_Re, image_Re, 2.0);  
  69.     cvPow( image_Im, image_Im, 2.0);  
  70.     cvAdd( image_Re, image_Im, image_Re);  
  71.     cvPow( image_Re, image_Re, 0.5 );  
  72.   
  73.   
  74.     //对数变换以增强灰度级细节(这种变换使以窄带低灰度输入图像值映射一宽带输出值,具体可见冈萨雷斯数字图像处理p62)  
  75.     // Compute log(1 + Mag);  
  76.     cvAddS( image_Re, cvScalar(1.0), image_Re ); // 1 + Mag  
  77.     cvLog( image_Re, image_Re ); // log(1 + Mag)  
  78.   
  79.   
  80.     //Rearrange the quadrants of Fourier image so that the origin is at the image center  
  81.     nRow = src->height; nCol = src->width;  
  82.     cx = nCol/2; cy = nRow/2; // image center  
  83.   
  84.   
  85.     //CV_IMAGE_ELEM为OpenCV定义的宏,用来读取图像的像素值,这一部分就是进行中心变换  
  86.     for( j = 0; j < cy; j++ ){  
  87.         for( i = 0; i < cx; i++ ){  
  88.             //中心化,将整体份成四块进行对角交换  
  89.             tmp13 = CV_IMAGE_ELEM( image_Re, double, j, i);  
  90.             CV_IMAGE_ELEM( image_Re, double, j, i) = CV_IMAGE_ELEM(image_Re, double, j+cy, i+cx);  
  91.             CV_IMAGE_ELEM( image_Re, double, j+cy, i+cx) = tmp13;  
  92.   
  93.   
  94.             tmp24 = CV_IMAGE_ELEM( image_Re, double, j, i+cx);  
  95.             CV_IMAGE_ELEM( image_Re, double, j, i+cx) =CV_IMAGE_ELEM( image_Re, double, j+cy, i);  
  96.             CV_IMAGE_ELEM( image_Re, double, j+cy, i) = tmp24;  
  97.         }  
  98.     }  
  99.     //归一化处理将矩阵的元素值归一为[0,255]  
  100.     //[(f(x,y)-minVal)/(maxVal-minVal)]*255  
  101.     double minVal = 0, maxVal = 0;  
  102.     // Localize minimum and maximum values  
  103.     cvMinMaxLoc( image_Re, &minVal, &maxVal );  
  104.     // Normalize image (0 - 255) to be observed as an u8 image  
  105.     scale = 255/(maxVal - minVal);  
  106.     shift = -minVal * scale;  
  107.     cvConvertScale(image_Re, dst, scale, shift);  
  108.     cvReleaseImage(&image_Re);  
  109.     cvReleaseImage(&image_Im);  
  110.   
  111.   
  112. }  
  113.   
  114.   
  115. /***********************************************************************/  
  116. int main()  
  117. {  
  118.     IplImage *src;          //源图像  
  119.     IplImage *Fourier;   //傅里叶系数  
  120.     IplImage *dst ;  
  121.   
  122.   
  123.     IplImage *ImageRe;  
  124.     IplImage *ImageIm;  
  125.   
  126.   
  127.     IplImage *Image;  
  128.     IplImage *ImageDst;  
  129.   
  130.   
  131.     double m,M;  
  132.     double scale;  
  133.     double shift;  
  134.     src = cvLoadImage("C:\\Users\\freeboy1015\\Desktop\\学习资料\\例图\\lena.jpg",0);   //加载源图像,第二个参数表示将输入的图片转为单信道   
  135.     Fourier = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,2);  
  136.     dst = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,2);  
  137.     ImageRe = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);  
  138.     ImageIm = cvCreateImage(cvGetSize(src),IPL_DEPTH_64F,1);  
  139.     Image = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);  
  140.     ImageDst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);  
  141.     fft2(src,Fourier);                  //傅里叶变换  
  142.     fft2shift(Fourier, Image);          //中心化  
  143.     cvDFT(Fourier,dst,CV_DXT_INV_SCALE);//实现傅里叶逆变换,并对结果进行缩放  
  144.     cvSplit(dst,ImageRe,ImageIm,0,0);  
  145.   
  146.   
  147.     cvNamedWindow("源图像",0);  
  148.     cvShowImage("源图像",src);               
  149.     //对数组每个元素平方并存储在第二个参数中  
  150.     cvPow(ImageRe,ImageRe,2);                 
  151.     cvPow(ImageIm,ImageIm,2);  
  152.     cvAdd(ImageRe,ImageIm,ImageRe,NULL);  
  153.     cvPow(ImageRe,ImageRe,0.5);  
  154.     cvMinMaxLoc(ImageRe,&m,&M,NULL,NULL);  
  155.     scale = 255/(M - m);  
  156.     shift = -m * scale;  
  157.     //将shift加在ImageRe各元素按比例缩放的结果上,存储为ImageDst  
  158.     cvConvertScale(ImageRe,ImageDst,scale,shift);  
  159.   
  160.   
  161.     cvNamedWindow("傅里叶谱",0);  
  162.     cvShowImage("傅里叶谱",Image);  
  163.     cvNamedWindow("傅里叶逆变换",0);  
  164.     cvShowImage("傅里叶逆变换",ImageDst);  
  165.   
  166.   
  167.     cvWaitKey(0);  
  168.   
  169.   
  170.     cvReleaseImage(&src);  
  171.     cvReleaseImage(&Image);  
  172.     cvReleaseImage(&ImageIm);  
  173.     cvReleaseImage(&ImageRe);  
  174.     cvReleaseImage(&Fourier);  
  175.     cvReleaseImage(&dst);  
  176.     cvReleaseImage(&ImageDst);  
  177.         cvDestroyAllWindows();  
  178.     return 0;  
  179. }</span> 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值