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,有能力的读者可以对此进行修改与完善。相信会有新的收获。

以上是 C++实现二维图形的傅里叶变换 的全部内容, 来源链接: utcz.com/z/337804.html

回到顶部