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

2025-05-27 0 71

本文实例讲述了C++实现二维图形傅里叶变换的方法。有一定的借鉴价值。分享给大家供大家参考。

具体代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

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

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 C++实现二维图形的傅里叶变换 https://www.kuaiidc.com/75845.html

相关文章

发表评论
暂无评论