开源中文网

您的位置: 首页 > 编程开发 > C++语言编程 > 正文

C++实现二维图形的傅里叶变换

来源: 网络整理  作者: 佚名

本文实例讲述了C++实现二维图形的傅里叶变换的方法。有一定的借鉴价值。分享给大家供大家参考。
具体代码如下:
 
// Fourier.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "math.h"
#include <cv.h>
#include <highgui.h>
#include "cxcore.h"

int main(int argc, char* argv[])
{
IplImage *img;
IplImage *simg;

CvMat *mat_R;
CvMat *mat_I;
CvMat *mat_SRC;
CvMat *mat_Row;
CvMat *mat_Col;
CvMat *dst;
CvMat *dst_R;
CvMat *dst_I;
CvMat *dst_Row;
CvMat *dst_Col;
int i,j,k;
double temp;
int height,width,step,channels;

//载入一幅图片
img=cvLoadImage("c:\\1.bmp",0);

//mat_R初始化
mat_R=cvCreateMat(img->height,img->width,CV_64FC1);
//mat_I初始化
mat_I=cvCreateMat(img->height,img->width,CV_64FC1);
//mat_SRC初始化
mat_SRC=cvCreateMat(img->height,img->width,CV_64FC2);
//将图片数据存入mat_R(实部)
cvConvert(img,mat_R);
//将虚部初始化为零
cvZero(mat_I);
//合并实部、虚部
cvMerge(mat_R,mat_I,NULL,NULL,mat_SRC);
//创建双通道double类型数组
dst=cvCreateMat(img->height,img->width,CV_64FC2);
dst_R=cvCreateMat(img->height,img->width,CV_64FC1);
dst_I=cvCreateMat(img->height,img->width,CV_64FC1);
//为循环变量赋值
height=img->height;
width=img->width;
channels=2;
step=channels*width;
//局部变量,值为正一或负一
int check;
//将输入数据乘以(-1)^(i+j),用于中心化
for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
  check=(i+j)%2>0?1:-1;
  for(k=0;k<channels;k++)
  {
  mat_SRC->data.db[j*step+i*channels+k]=check*mat_SRC->data.db[j*step+i*channels+k];
  }
}
}
//创建一个mat用于临时存储一行数据
CvMat mat_Header=cvMat(4,4,CV_64FC2);
mat_Row=cvCreateMat(1,width,CV_64FC2);
mat_Col=cvCreateMat(1,height,CV_64FC2);
//创建一个dst用于临时存储一行数据
dst_Row=cvCreateMat(1,width,CV_64FC2);
dst_Col=cvCreateMat(height,1,CV_64FC2);
//为循环变量赋值
height=img->height;
width=img->width;
channels=2;
step=channels*width;
//行的傅里叶变换
for(j=0;j<height;j++)
{
//取得第j行数据
mat_Row=cvGetRow(mat_SRC,&mat_Header,j);
//正向傅里叶变换
cvDFT(mat_Row,dst_Row,CV_DXT_FORWARD);
//执行循环,赋值到dst
for(i=0;i<width;i++)
{
  for(k=0;k<channels;k++)
  {
  dst->data.db[j*step+i*channels+k]=dst_Row->data.db[i*channels+k];
  }
}
}

//列的傅里叶变换
for(i=0;i<width;i++)
{
//取得第i列
mat_Col=cvGetCol(dst,&mat_Header,i);
  
//正向傅里叶变换
cvDFT(mat_Col,dst_Col,CV_DXT_FORWARD);
//执行循环,赋值到dst
for(j=0;j<height;j++)
{
  for(k=0;k<channels;k++)
  {
  dst->data.db[j*step+i*channels+k]=dst_Col->data.db[j*channels+k];
  }
}
}
 
//分成两个矩阵
cvSplit(dst,dst_R,dst_I,NULL,NULL);

//创建临时指针指向dst_R,dst_I
double *pR,*pI;
pR=(double *)dst_R->data.ptr;
pI=(double *)dst_I->data.ptr;
//创建一张用于显示的图像
simg=cvCreateImage(cvGetSize(img),8,1);
//为循环变量赋值
height=simg->height;
width=simg->width;
channels=1;
step=channels*width;

for(j=0;j<height;j++)
{
for(i=0;i<width;i++)
{
  for(k=0;k<channels;k++)
  {
  temp=pR[j*step+i*channels+k]*pR[j*step+i*channels+k]+pI[j*step+i*channels+k]*pI[j*step+i*channels+k];
  temp=temp/(height*width);
  simg->imageData[j*step+i*channels+k]=sqrt(temp);
  }
}
}

cvNamedWindow("Mar",CV_WINDOW_AUTOSIZE);
cvShowImage("Mar",simg);
cvWaitKey(0);
 
cvReleaseMat(&mat_R);
cvReleaseMat(&mat_I);
cvReleaseMat(&mat_SRC);
//cvReleaseMat(&mat_Row);//这里无法正常释放,有待解决
//cvReleaseMat(&mat_Col);
cvReleaseMat(&dst);
cvReleaseMat(&dst_R);
cvReleaseMat(&dst_I);
cvReleaseImage(&img);
cvReleaseImage(&simg);
return 0;
}
感兴趣的朋友可以调试运行一下本文实例,程序美中不足的是会有内存泄漏,主要是mat_Row,mat_Col,dst_Row,dst_Col,有能力的读者可以对此进行修改与完善。相信会有新的收获。

Tags:二维 C++ 图形
关于开源中文网 - 联系我们 - 广告服务 - 网站地图 - 版权声明