-
Notifications
You must be signed in to change notification settings - Fork 2
/
feature_descriptor_histogram.c
205 lines (165 loc) · 4.45 KB
/
feature_descriptor_histogram.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
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
#include "header.h"
#include "proto.h"
double ***feature_descriptor_histogram(
int width,
int height,
double *image,
int inp_i,
int inp_j,
double ori,
double feature_sigma,
int descr_width,
int hist_nbr
)
/*
descr_width is the numbr of row/cols of the descriptor array
hist_nbr is the size of the histogram stored
for each cell of the descriptor array
*/
{
double pi= acos(-1);
double pi2= pi*2;
double descriptor_sigma_factor;
double ***hist_arr;
int hist_i;
int hist_j;
double cos_t;
double sin_t;
double bins_per_rad;
double exp_denom;
double spacing;
int radius;
int i;
int j;
double j_rot;
double i_rot;
double descr_i_dbl;
double descr_j_dbl;
double hist_ind_dbl;
double grad_mag;
double grad_ori;
double weight;
int err_flag;
double sigma;
double radius_dbl;
hist_arr= (double ***)calloc(descr_width,sizeof(double **));
for ( hist_i= 0 ; hist_i< descr_width ; hist_i++ ) {
hist_arr[hist_i]= (double **)calloc(descr_width,sizeof(double *));
for ( hist_j= 0 ; hist_j< descr_width ; hist_j++ ) {
hist_arr[hist_i][hist_j]= (double *)calloc(hist_nbr,sizeof(double));
}
}
descriptor_sigma_factor= 3.0;
cos_t= cos(ori);
sin_t= sin(ori);
bins_per_rad= (double)hist_nbr/pi2;
sigma= 0.5*(double)descr_width;
exp_denom= 2*sigma*sigma;
spacing= descriptor_sigma_factor*feature_sigma;
radius_dbl= spacing * sqrt(2) * ((double)descr_width+1) * 0.5;
radius= (int)(radius_dbl+0.5);
for ( i= -radius ; i<= radius ; i++ ) {
for ( j= -radius ; j<= radius ; j++ ) {
/*
Rotate the sample location
so that the sample is in the coordinate system of the feature
(j_rot,i_rot) is the coordinate of the sample
in the coordinate system of the feature
*/
j_rot= j*cos_t - i*sin_t;
i_rot= j*sin_t + i*cos_t;
/*
Divide by the spacing,
which is the width/height of the cells of the descriptor array,
to get the index into that array
*/
j_rot/= spacing;
i_rot/= spacing;
/*
Adjust the index
so that it's w/r to top left corner of the descriptor array
*/
descr_i_dbl= i_rot + (double)descr_width/2;
descr_j_dbl= j_rot + (double)descr_width/2;
/*
Subtract 0.5
*/
descr_i_dbl-= 0.5;
descr_j_dbl-= 0.5;
/*
Check if rotated sample now in descriptor array index coordinates
is physically in the descriptor window
*/
if ( descr_i_dbl > -1.0 && descr_i_dbl < descr_width &&
descr_j_dbl > -1.0 && descr_j_dbl < descr_width ) {
/*
Rotated sample is in the descriptor
*/
/*
Compute the gradient magnitude and orientation
of the sample using the unrotated coordinates
*/
err_flag= feature_gradient_magnitude_orientation(
width,
height,
image,
inp_i+i,
inp_j+j,
&grad_mag,
&grad_ori
);
if ( err_flag == 1 ) {
/*
Could not compute the magnitude and orientation of the gradient
*/
/*
Do nothing!
*/
continue;
}
/*
Recall that the orientation returned is between -pi and +pi
*/
/*
Make it to be between 0 and 2pi
*/
if ( grad_ori < 0 )
grad_ori+= pi2;
/*
The gradient orientation must be w/r to the feature orientation
*/
grad_ori-= ori;
/*
Make sure the gradient orientation is still between 0 and 2pi
*/
while (grad_ori < 0.0 )
grad_ori+= pi2;
while (grad_ori >= pi2 )
grad_ori-= pi2;
/*
Compute index of gradient orientation into the histogram
*/
hist_ind_dbl= grad_ori*bins_per_rad;
/*
Compute the weight
to be given to the gradient magnitude
*/
weight= exp(-(j_rot*j_rot+i_rot*i_rot)/exp_denom);
/*
Add the gradient magnitude to the descriptor array
using trilinear interpolation
*/
feature_descriptor_histogram_interpolate(
hist_arr,
descr_i_dbl,
descr_j_dbl,
hist_ind_dbl,
grad_mag*weight,
descr_width,
hist_nbr
);
}
}
}
return hist_arr;
}