opencv学习:二维浮点数离散傅里叶变换及其扩展边界优化
来源:互联网 发布:交换机端口灯不亮 编辑:程序博客网 时间:2024/06/14 16:13
opencv中提供了傅里叶变换函数cvDFT,执行二维浮点数离散傅里叶变换的代码如下:
void fft2(const IplImage* src, IplImage* dst){ //实部、虚部 IplImage *image_Re = 0, *image_Im = 0, *Fourier = 0; image_Re = cvCreateImage(cvGetSize(src), IPL_DEPTH_32F, 1); //实部 image_Im = cvCreateImage(cvGetSize(src), IPL_DEPTH_32F, 1); //虚部 Fourier = cvCreateImage(cvGetSize(src), IPL_DEPTH_32F, 2); //二通道图像 //将实部从8u转换为32f cvConvertScale(src, image_Re); // 虚部置零 cvZero(image_Im); //将实部与虚部合并到Fourier中 cvMerge(image_Re, image_Im, 0, 0, Fourier); // 进行正向离散傅里叶变换 cvDFT(Fourier, dst, CV_DXT_FORWARD); cvReleaseImage(&image_Re); cvReleaseImage(&image_Im); cvReleaseImage(&Fourier); }
将图像中心移到原点:
void cvShiftDFT(CvArr* src, CvArr* dst){//定义变量 CvMat * tmp; CvMat q1stub, q2stub; CvMat q3stub, q4stub; CvMat d1stub, d2stub; CvMat d3stub, d4stub; CvMat * q1, * q2, * q3, * q4; CvMat * d1, * d2, * d3, * d4;//获取源图像和目标图像的尺寸 CvSize size = cvGetSize(src); CvSize dst_size = cvGetSize(dst); int cx, cy;//若源图像和目标图像的尺寸不一致,抛出异常错误 if(dst_size.width != size.width || dst_size.height != size.height){ cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes", __FILE__, __LINE__ ); }//若源和目标为同一指针,则创建临时矩阵变量 if(src==dst){ tmp = cvCreateMat(size.height/2, size.width/2, cvGetElemType(src)); } cx = size.width/2; cy = size.height/2; // 图像中心//分别获取第一、二、三、四象限的子图像 q1 = cvGetSubRect( src, &q1stub, cvRect(0,0,cx, cy) ); q2 = cvGetSubRect( src, &q2stub, cvRect(cx,0,cx,cy) ); q3 = cvGetSubRect( src, &q3stub, cvRect(cx,cy,cx,cy) ); q4 = cvGetSubRect( src, &q4stub, cvRect(0,cy,cx,cy) ); d1 = cvGetSubRect( src, &d1stub, cvRect(0,0,cx,cy) ); d2 = cvGetSubRect( src, &d2stub, cvRect(cx,0,cx,cy) ); d3 = cvGetSubRect( src, &d3stub, cvRect(cx,cy,cx,cy) ); d4 = cvGetSubRect( src, &d4stub, cvRect(0,cy,cx,cy) );/*** 若源与目标不一致* 则直接将源图像的第一、二、三、四象限对应复制到目标图像的第三、四、一、二象限* 否则,直接交换一三象限、二四象限**/ if(src!=dst){ if( !CV_ARE_TYPES_EQ( q1, d1 )){ cvError( CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", __FILE__, __LINE__ ); } cvCopy(q3, d1, 0); cvCopy(q4, d2, 0); cvCopy(q1, d3, 0); cvCopy(q2, d4, 0); } else{ cvCopy(q3, tmp, 0); cvCopy(q1, q3, 0); cvCopy(tmp, q1, 0); cvCopy(q4, tmp, 0); cvCopy(q2, q4, 0); cvCopy(tmp, q2, 0); }}
以上代码参考了richel_zhang的博客和opencv教程基础篇。
cvDFT函数执行时的效率与图像尺寸有关,当图像的宽高都为2的指数幂时,将可利用快速傅里叶变换,运算时间为O(NlogN), 否则为O(N^2),故为了提高运算效率,需要提前将待处理图像的尺寸扩展为2的指数幂大小。
opencv中提供了函数cvGetOptimalDFTSize可以获取最优傅里叶变换尺寸,再结合扩展边界函数copyMakeBorder将源图像尺寸扩展。
代码如下:
void getOptimalDFTSize(const IplImage* src, CvSize& size){size.width = cvGetOptimalDFTSize(src->width);size.height = cvGetOptimalDFTSize(src->height);}IplImage* border(const IplImage* src, CvSize size){IplImage* borderImg = cvCreateImage(size, src->depth, src->nChannels);copyMakeBorder(cv::cvarrToMat(src), cv::cvarrToMat(borderImg),0,size.height-src->height, 0, size.width-src->width,cv::BORDER_CONSTANT);return borderImg;}void border_fft2(const IplImage* src, IplImage* dst){//计算最优DFT尺寸CvSize size;getOptimalDFTSize(src, size);border_fft2(src, dst, size);//调用函数扩展边界并做傅里叶变换}void border_fft2(const IplImage* src, IplImage* dst, CvSize size){IplImage* bordersrc = border(src, size);//扩展边界fft2(bordersrc, dst);//二维傅里叶变换cvReleaseImage(&bordersrc);//释放内存}
版权所有,转载请注明出处。
0 0
- opencv学习:二维浮点数离散傅里叶变换及其扩展边界优化
- opencv学习-core-离散傅里叶变换
- OpenCV学习离散傅里叶变换(DFT)
- OpenCV学习笔记(六)离散傅里叶变换
- OpenCV中对图像进行二维离散傅里叶变换
- opencv之离散傅里叶变换
- Opencv离散傅里叶变换
- OpenCV之离散傅里叶变换
- opencv:离散傅里叶变换
- C++ opencv 离散傅里叶变换
- C++实现二维离散傅里叶变换
- Opencv基础学习二:图片的离散傅里叶变换
- 基础学习笔记之opencv(15):离散傅里叶变换
- opencv 2.x学习笔记(十四)离散傅里叶变换
- opencv学习(6)图像离散傅里叶变换的实现过程
- OpenCV学习笔记(八):图像的离散傅里叶变换
- opencv学习实现简单的图像离散傅里叶变换
- 5.opencv之离散傅里叶变换
- 有关inflater.inflate函数的总结笔记
- pairs
- ubuntu一些准备工作
- 保护系统的方法
- mysql和sqlserver中查看当前库中所有表和字段信息
- opencv学习:二维浮点数离散傅里叶变换及其扩展边界优化
- Cent0S下使用LVS+KeepLive进行负载均衡及高可用web服务器(何志雄)
- Eclipse编程区域主题添加教程Color和Theme
- 【转载】会话COOKIE? 持久COOKIE?
- 尽量减少HTTP请求个数——须权衡
- 修改SA 密码 无法设置主体sa 15535 SQLServer2008
- mount命令详解
- 一次心路的旅行2 —— DAY2,长沙
- 原语组装和光栅化