forked from xkck/Gabor-Feature
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGabor.cpp
360 lines (294 loc) · 8.47 KB
/
Gabor.cpp
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#include "Gabor.h"
enum convtype
{
full,
same,
valid
};
/*
*@函数名: conv2
*@功能: 卷积运算
*@参数: const Mat &img 原图片
const Mat ikernel 卷积核
convtype type 卷积类型
*@返回值: Mat 矩阵卷积后的结果
*@作者: xkck
*@日期: 2016-1-7
*---------------------------------------
*时间 修改人 修改者
*---------------------------------------
**/
Mat conv2(const Mat &img, const Mat ikernel, convtype type)
{
Mat dest;
Mat kernel;
flip(ikernel,kernel,-1);
Mat source = img;
if(type == full)
{
source = Mat();
int additionalRows = kernel.rows-1, additionalCols = kernel.cols-1;
copyMakeBorder(img, source, (additionalRows+1)/2, additionalRows/2, (additionalCols+1)/2, additionalCols/2, BORDER_CONSTANT, Scalar(0));
}
Point anchor(kernel.cols - kernel.cols/2 - 1, kernel.rows - kernel.rows/2 - 1);
int borderMode = BORDER_CONSTANT;
filter2D(source, dest, img.depth(), kernel, anchor, 0, borderMode);
if(type == valid)
{
dest = dest.colRange((kernel.cols-1)/2, dest.cols - kernel.cols/2).rowRange((kernel.rows-1)/2, dest.rows - kernel.rows/2);
}
return dest;
}
/*
*@函数名: MakeGaborKernal
*@功能: 生成所有Gabor核
*@参数:
*@返回值: void
*@作者: xkck
*@日期: 2016-1-7
*---------------------------------------
*时间 修改人 修改者
*---------------------------------------
**/
void Gabor::MakeAllGaborKernal()
{
int n=0;
for(int v=0;v<V;v++)
{
for(int u=0;u<U;u++)
{
MakeGaborKernal(ke_w,ke_h,u,v,GaborReal[v*8+u],GaborImg[v*8+u]);
}
}
}
/*
*@函数名: MakeGaborKernal
*@功能: 生成固定方向与固定尺度的Gabor核
*@参数: int ke_h 核函数的高度
int ke_w 核函数的宽度
int u Gabor的尺度
int v Gabor的方向
Mat &GaborReal Gabor的实部
Mat &GaborImg Gabor的虚部
*@返回值: Mat 返回的Gabor特征
*@作者: xkck
*@日期: 2016-1-7
*---------------------------------------
*时间 修改人 修改者
*---------------------------------------
**/
void Gabor::MakeGaborKernal(int ke_h,int ke_w,int u,int v,Mat &GaborReal,Mat &GaborImg)
{
int HarfH=ke_h/2;
int HarfW=ke_w/2;
double Qu=CV_PI*u/8;
double sqsigma=m_sigma*m_sigma;
double Kv=m_kmax/(pow(m_f,v));
double postmean=exp(-sqsigma/2);
GaborReal.create(HarfH+HarfW+1,HarfH+HarfW+1,CV_32FC1);
GaborImg.create(HarfH+HarfW+1,HarfH+HarfW+1,CV_32FC1);
float *ptr_real=NULL;
float *ptr_img=NULL;
for(int j=-HarfH;j<=HarfH;j++)
{
ptr_real=GaborReal.ptr<float>(j+HarfH);
ptr_img=GaborImg.ptr<float>(j+HarfH);
for(int i=-HarfW;i<=HarfW;i++)
{
double tmp1=exp(-(Kv*Kv*(j*j+i*i)/(2*sqsigma)));
double tmp2=cos(Kv*cos(Qu)*i+Kv*sin(Qu)*j)-postmean;
double tmp3=sin(Kv*cos(Qu)*i+Kv*sin(Qu)*j);
ptr_real[i+HarfW]=Kv*Kv*tmp1*tmp2/sqsigma;
ptr_img[i+HarfW]=Kv*Kv*tmp1*tmp3/sqsigma;
}
}
}
/*
*@函数名: Gabor_T_Fast1
*@功能: 获取固定核函数的Gabor特征
*@参数: Mat &src 原图---彩色图片
int ds_h 下采样的高度
int ds_w 下采样的宽度
Mat kel_GR[Gabor_num] 固定核函数的实部
Mat kel_GI[Gabor_num] 固定核函数的虚部
*@返回值: Mat 返回的Gabor特征
*@作者: xkck
*@日期: 2016-1-7
*---------------------------------------
*时间 修改人 修改者
*---------------------------------------
**/
Mat Gabor::Gabor_T_Fast1(Mat &src,int ds_h,int ds_w,Mat kel_GR[Gabor_num],Mat kel_GI[Gabor_num])
{
Mat feature;
Mat feature1;
for(int i=0;i<Gabor_num;i++)
{
Mat feat_real_part;
Mat feat_img_part;
Mat feat_mode_part;
feat_real_part=conv2(src,kel_GR[i],same);
feat_img_part=conv2(src,kel_GI[i],same);
multiply(feat_real_part,feat_real_part,feat_real_part);
multiply(feat_img_part,feat_img_part,feat_img_part);
add(feat_real_part,feat_img_part,feat_mode_part);
sqrt(feat_mode_part,feat_mode_part);
Mat tmp2;
Mat tmp3;
resize(feat_mode_part,tmp2,Size(ds_w,ds_h));
tmp3=tmp2.reshape(1,1);
float mean=0;
float std=0;
float sum1=0;
float sum2=0;
for(int j=0;j<tmp3.cols;j++)
{
sum1+=tmp3.at<float>(0,j);
}
mean=sum1/(tmp3.cols);
for(int j=0;j<tmp3.cols;j++)
{
sum2+= pow((tmp3.at<float>(0,j)-mean),2);
}
sum2/=tmp3.cols;
std=sqrt(sum2);
subtract(tmp3,mean,tmp3);
divide(tmp3,std,tmp3);
feature.push_back(tmp3);
}
feature1=feature.reshape(1,1);
return feature1;
}
/*
*@函数名: Gabor_T_Fast2
*@功能: 获取固定核函数的Gabor均值与方差二维特征
*@参数: Mat &src 原图---彩色图片
int ds_h 下采样的高度
int ds_w 下采样的宽度
Mat kel_GR[Gabor_num] 固定核函数的实部
Mat kel_GI[Gabor_num] 固定核函数的虚部
double* feature 特征值
*@返回值: Mat 返回的Gabor特征
*@作者: xkck
*@日期: 2016-1-7
*---------------------------------------
*时间 修改人 修改者
*---------------------------------------
**/
int Gabor::Gabor_T_Fast2(Mat &src,int ds_h,int ds_w,Mat kel_GR[Gabor_num],Mat kel_GI[Gabor_num],double* feature)
{
vector<float> featureTmp;
for(int i=0;i<Gabor_num;i++)
{
Mat feat_real_part;
Mat feat_img_part;
Mat feat_mode_part;
feat_real_part=conv2(src,kel_GR[i],same);
feat_img_part=conv2(src,kel_GI[i],same);
multiply(feat_real_part,feat_real_part,feat_real_part);
multiply(feat_img_part,feat_img_part,feat_img_part);
add(feat_real_part,feat_img_part,feat_mode_part);
sqrt(feat_mode_part,feat_mode_part);
Mat tmp2;
Mat tmp3;
//使用双线性插值法,使feat_mode_part宽高调整到(ds_w,ds_h)
resize(feat_mode_part,tmp2,Size(ds_w,ds_h));
tmp3=tmp2.reshape(1,1);
//求均值mean和方差std
float mean=0;
float std=0;
float sum1=0;
float sum2=0;
for(int j=0;j<tmp3.cols;j++)
{
sum1+=tmp3.at<float>(0,j);
}
mean=sum1/(tmp3.cols);
for(int j=0;j<tmp3.cols;j++)
{
sum2+= pow((tmp3.at<float>(0,j)-mean),2);
}
sum2/=tmp3.cols;
std=sqrt(sum2);
featureTmp.push_back(mean);
featureTmp.push_back(std);
}
for(size_t i=0; i<featureTmp.size(); ++i)
{
*(feature+i) = featureTmp.at(i);
}
return 0;
}
/*
*@函数名: Create_GaborF
*@功能: 获取Gabor特征
*@参数: Mat &src 原图---彩色图片
*@返回值: Mat 返回的Gabor特征
*@作者: xkck
*@日期: 2016-1-7
@说明:
*---------------------------------------
*时间 修改人 修改者
*---------------------------------------
**/
Mat Gabor::Create_GaborF(Mat &src)
{
MakeAllGaborKernal();
Mat feature;
double tmp1=ke_w/2;
double tmp2=ke_h/2;
int radius_w =(int)floor(tmp1);
int radius_h =(int)floor(tmp2);
int center_w = radius_w+1;
int center_h = radius_h+1;
int step=5;
Mat kel_GR[Gabor_num],kel_GI[Gabor_num];
int t1=center_h-radius_h+step;
int t2=center_h+radius_h-step;
int t3=center_w-radius_w+step;
int t4=center_w+radius_w-step;
for(int m=0;m<Gabor_num;m++){
kel_GR[m]=GaborReal[m](Range(t1-1,t2),Range(t3-1,t4));
kel_GI[m]=GaborImg[m](Range(t1-1,t2),Range(t3-1,t4));
}
feature=Gabor_T_Fast1(src,ds_h,ds_w,kel_GR,kel_GI);
return feature;
}
/*
*@函数名: getGaborMeanAndVarianceFeature
*@功能: 获取Gabor的均值与方差二维特征
*@参数: Mat &src 原图---彩色图片
double* feature 特征
*@返回值:
0 特征获取成功
-1 特征获取失败
*@作者: xkck
*@日期: 2016-1-7
@说明:
*---------------------------------------
*时间 修改人 修改者
*---------------------------------------
**/
int Gabor::getGaborMeanAndVarianceFeature(Mat &src,double* feature)
{
MakeAllGaborKernal();
double tmp1=ke_w/2;
double tmp2=ke_h/2;
int radius_w =(int)floor(tmp1);
int radius_h =(int)floor(tmp2);
int center_w = radius_w+1;
int center_h = radius_h+1;
int step=5;
Mat kel_GR[Gabor_num],kel_GI[Gabor_num];
int t1=center_h-radius_h+step;
int t2=center_h+radius_h-step;
int t3=center_w-radius_w+step;
int t4=center_w+radius_w-step;
for(int m=0;m<Gabor_num;m++)
{
kel_GR[m]=GaborReal[m](Range(t1-1,t2),Range(t3-1,t4));
kel_GI[m]=GaborImg[m](Range(t1-1,t2),Range(t3-1,t4));
}
Gabor_T_Fast2(src,ds_h,ds_w,kel_GR,kel_GI,feature);
return 0;
}