- 论坛徽章:
- 14
|
从网上Google了一些傅立叶变换的代码,千篇一律,方法一样,错误也一样。
凭猜测和调试,整改了一番,贴于此地留个存档。但可能我的理解仍然有错误,因此仅供参考- #include <cv.h>
- #include <highgui.h>
- // 1.将图片im扩展到最佳傅立叶变换尺寸作为实部,并上一个全零的虚部,得到复数image_Cp
- // 2.将image_Cp作傅立叶变换,分解成实部和虚部分别显示
- // 3.将作过傅立叶变换的image_Cp做反向傅立叶变换,分解成实部和虚部分别显示
- // 4.从第三步得到的image_Cp中的实部中抠出im,应当和第一步中im是一样的
- int main()
- {
- const char* filename = "D:\\sources\\cpp001\\1.jpg";
- //const char* filename = "D:\\sources\\cpp001\\IMG_0988.JPG";
- IplImage* im = cvLoadImage( filename, CV_LOAD_IMAGE_GRAYSCALE );
- cvShowImage( "1", im );
- // 获取傅立叶变换的最佳尺寸(大于等于原先尺寸)
- int dft_h = cvGetOptimalDFTSize( im->height );
- int dft_w = cvGetOptimalDFTSize( im->width );
- if( dft_h<=0 || dft_w<=0 )
- {
- cvReleaseImage( &im );
- return 0;
- }
- IplImage* image_Re = cvCreateImage( cvSize(dft_w,dft_h), IPL_DEPTH_64F, 1 );
- IplImage* image_Im = cvCreateImage( cvSize(dft_w,dft_h), IPL_DEPTH_64F, 1 );
- CvMat* image_Cp = cvCreateMat( dft_h, dft_w, CV_64FC2 );
- {
- // 将 im 拷贝到 image_Re 中,剩余部分置零
- if( dft_w > im->width || dft_h > im->height )
- cvZero( image_Re );
- CvMat tmp;
- cvGetSubRect( image_Re, &tmp, cvRect(0,0,im->width,im->height) );
- cvScale( im, &tmp, 1.0, 0.0 );
- // 将 image_Im 置零
- cvZero( image_Im );
- // 将 image_Re 和 image_Im 合并成 image_Cp
- cvMerge( image_Re, image_Im, NULL, NULL, image_Cp );
- }
- // 傅立叶变换
- cvDFT( image_Cp, image_Cp, CV_DXT_FORWARD, im->height );
- // 分解 image_Cp 的实部和虚部
- cvSplit( image_Cp, image_Re, image_Im, 0, 0 );
- //// test
- //cvZero( image_Re );
- //cvMerge( image_Re, image_Im, NULL, NULL, image_Cp );
- // 显示实部
- double Min, Max;
- cvMinMaxLoc( image_Re, &Min, &Max, NULL, NULL, NULL );
- cvScale( image_Re, image_Re, 1.0/(Max-Min), -Min/(Max-Min) );
- cvShowImage( "2R", image_Re );
- // 显示虚部
- cvMinMaxLoc( image_Im, &Min, &Max, NULL, NULL, NULL );
- cvScale( image_Im, image_Im, 1.0/(Max-Min), -Min/(Max-Min) );
- cvShowImage( "2I", image_Im );
- //// 显示 log( 1 + (R^2+I^2)^0.5 )
- //cvPow( image_Re, image_Re, 2.0);
- //cvPow( image_Im, image_Im, 2.0);
- //cvAdd( image_Re, image_Im, image_Re, NULL);
- //cvPow( image_Re, image_Re, 0.5 );
- //cvAddS( image_Re, cvScalarAll(1.0), image_Re, NULL );
- //cvLog( image_Re, image_Re );
- //cvMinMaxLoc(image_Re, &Min, &Max, NULL, NULL, NULL );
- //cvScale(image_Re, image_Re, 1.0/(Max-Min), -Min/(Max-Min) );
- //cvShowImage("1X", image_Re);
- // 反向傅立叶变换
- cvDFT( image_Cp, image_Cp, CV_DXT_INVERSE_SCALE, im->height );
- // 分解 image_Cp 的实部和虚部
- cvSplit( image_Cp, image_Re, image_Im, 0, 0 );
- // 将实部还原为im格式,按理应当和原先im的数据一致
- CvMat tmp;
- cvGetSubRect( image_Re, &tmp, cvRect(0,0,im->width,im->height) );
- cvScale( &tmp, im, 1.0, 0.0 );
- cvShowImage( "4", im );
- // 实部
- cvMinMaxLoc( image_Re, &Min, &Max, NULL, NULL, NULL );
- cvScale( image_Re, image_Re, 1.0/(Max-Min), -Min/(Max-Min) );
- cvShowImage( "3R", image_Re );
- // 虚部
- cvMinMaxLoc( image_Im, &Min, &Max, NULL, NULL, NULL );
- cvScale( image_Im, image_Im, 1.0/(Max-Min), -Min/(Max-Min) );
- cvShowImage( "3I", image_Im );
- cvWaitKey();
- cvReleaseMat( &image_Cp );
- cvReleaseImage( &image_Re );
- cvReleaseImage( &image_Im );
- cvReleaseImage( &im );
- cvDestroyAllWindows( );
- return 0;
- }
复制代码 |
|