看到一篇文章关于Gabor滤波器的文章,有感,遂记录一下。
一.Gabor 滤波器简介(部分资料来自维基百科)
在图像处理领域,Gabor滤波器是一个用于边缘检测的线性滤波器。Gabor滤波器的频率和方向表示接近人类视觉系统对于频率和方向的表示,并且它们常备用于纹理表示和描述。在空域,一个2维的Gabor滤波器是一个正弦平面波和高斯核函数的乘积。Gabor滤波器是自相似的,也就是说,所有Gabor滤波器都可以从一个母小波经过膨胀和旋转产生。实际应用中,Gabor滤波器可以在频域的不同尺度,不同方向上提取相关特征。
二.Gabor滤波器公式化定义

公式中:
λ:正弦函数波长;
θ:Gabor核函数的方向
ψ:相位偏移
σ:高斯函数的标准差
γ: 空间的宽高比(这个没太理解)
四.Gabor 滤波器opencv实现代码
1
CGaborFilter::CGaborFilter(
float dLambda,
float dTheta,
float dRatio_S2L,
float dGamma,
float dPhi)
2
{
3
Lambda = dLambda;
4
Theta = dTheta;
5
sigma = dLambda*dRatio_S2L;
6
Gamma = dGamma;
7
Phi = dPhi;
8
m_pGaborFilter = NULL;
9
bParam = 1;
10
}
11
12
13
CGaborFilter::~CGaborFilter(
void)
14
{
15
cvReleaseMat(&m_pGaborFilter);
16
}
17
18
void CGaborFilter::Init()
19
{
20
float dtmp;
21
int itmp;
22
if(is_param() == 0)
23
{
24
printf("The parameters are not enough!");
25
}
26
else
27
{
28
dtmp = sqrt(48*pow(sigma,2)+1);
29
itmp = cvRound(dtmp);
30
if(itmp%2 == 0)
31
itmp ++;
32
GaborWindow.height = GaborWindow.width = 16;
33
bInit = 1;
34
35
create_kernel();
36
}
37
}
38
39
void CGaborFilter::Init(
float dSigma,
float dTheta,
float dPhi)
40
{
41
float dtmp;
42
int itmp;
43
44
sigma = dSigma;
45
Theta = dTheta;
46
Phi = dPhi;
47
Gamma = GAMMA;
48
Lambda = sigma/RATIO_S2L;
49
bParam = 1;
50
51
dtmp = sqrt(24*pow(sigma,2));
52
itmp = cvRound(dtmp);
53
if(itmp%2 == 0)
54
itmp ++;
55
GaborWindow.height = GaborWindow.width = itmp;
56
bInit = 1;
57
58
create_kernel();
59
}
60
61
void CGaborFilter::Init(
float dLambda,
float dTheta,
float dPhi,
float dGamma)
62
{
63
float dtmp;
64
int itmp;
65
66
Lambda = dLambda;
67
Theta = dTheta;
68
Phi = dPhi;
69
Gamma = dGamma;
70
sigma = Lambda * RATIO_S2L;
71
bParam = 1;
72
73
dtmp = sqrt(24*pow(sigma,2));
74
itmp = cvRound(dtmp);
75
if(itmp%2 == 0)
76
itmp ++;
77
GaborWindow.height = GaborWindow.width = itmp;
78
bInit = 1;
79
80
create_kernel();
81
}
82
83
void CGaborFilter::create_kernel()
84
{
85
float tmp1,tmp2,xtmp,ytmp,re;
86
int i,j,x,y;
87
88
if(is_init() == 0)
89
printf("The parameters haven't been initialed!");
90
91
92
else{
93
94
95
m_pGaborFilter = cvCreateMat(GaborWindow.height,GaborWindow.width,CV_32FC1);
96
for(i= 0; i< GaborWindow.height; i++)
97
for(j = 0; j< GaborWindow.width; j++)
98
{
99
x = j - GaborWindow.width/2;
100
y = i - GaborWindow.height/2;
101
102
103
xtmp = (float)x*cos(Theta) - (float)y*sin(Theta);
104
ytmp = (float)x*sin(Theta) + (float)y*cos(Theta);
105
106
tmp1 = exp(-(pow(xtmp,2)+pow(ytmp*Gamma,2))/(2*pow(sigma,2)));
107
tmp2 = cos(2*PI*xtmp/Lambda + Phi);
108
// int p=sizeof(float);
109
re = tmp1*tmp2;
110
cvSetReal2D((CvMat*)m_pGaborFilter,i,j,re);
111
112
}
113
bKernel = 1;
114
}
115
}
116
117
IplImage * CGaborFilter::get_Image()
118
{
119
if(is_kernel() == 0)
120
{
121
printf("The filter hasn't bee created!");
122
}
123
else
124
{
125
IplImage *pImg = cvCreateImage(GaborWindow,IPL_DEPTH_32F,1);
126
IplImage *pImgU8 = cvCreateImage(GaborWindow,IPL_DEPTH_8U,1);
127
CvMat * pMat = cvCreateMat(GaborWindow.height,GaborWindow.width,CV_32FC1);
128
129
cvCopy(m_pGaborFilter,pImg);
130
//pImg->imageData = (char *)pMat->data;
131
cvNormalize((IplImage*)pImg, (IplImage*)pImg,0,255,CV_MINMAX,NULL);
132
cvConvertScaleAbs(pImg,pImgU8,1,0);
133
return pImgU8;
134
}
135
}
136
137
IplImage * CGaborFilter::do_filter(
const IplImage * src)
138
{
139
if(is_kernel()==false)
140
{
141
printf("The Gabor Kernel has not been created!");
142
}
143
else{
144
145
IplImage *pDestImage = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
146
// IplImage * pGaborImage = get_Imge();
147
// CvMat GaborKernel = cvMat(pGaborImage->height,pGaborImage->width,CV_8U,pGaborImage->imageData);
148
IplImage *tmpImg = cvCloneImage(src);
149
IplImage *tmpGrayImg = cvCreateImage(cvSize(src->width,src->height),IPL_DEPTH_8U,1);
150
151
if(tmpImg->nChannels != 1)
152
{
153
cvCvtColor(tmpImg,tmpGrayImg,CV_BGR2GRAY);
154
}
155
else
156
{
157
cvReleaseImage(&tmpGrayImg);
158
tmpGrayImg = tmpImg;
159
}
160
CvMat * pGaborKernel = get_Mat();
161
162
cvFilter2D(tmpGrayImg,pDestImage,pGaborKernel,cvPoint((GaborWindow.width-1)/2,(GaborWindow.height-1)/2));
163
164
cvReleaseImage(&tmpImg);
165
return pDestImage;
166
}
167
}

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

159

160

161

162

163

164

165

166

167
