Go to the documentation of this file.00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00112 #include "lbp.h"
00113 #include "mathop.h"
00114 #include "string.h"
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 static void
00172 _vl_lbp_init_uniform(VlLbp * self)
00173 {
00174 int i, j ;
00175
00176
00177 self->dimension = 58 ;
00178
00179
00180 for (i = 0 ; i < 256 ; ++i) {
00181 self->mapping[i] = 57 ;
00182 }
00183
00184
00185 self->mapping[0x00] = 56 ;
00186 self->mapping[0xff] = 56 ;
00187
00188
00189 for (i = 0 ; i < 8 ; ++i) {
00190 for (j = 1 ; j <= 7 ; ++j) {
00191 int ip ;
00192 int unsigned string ;
00193 if (self->transposed) {
00194 ip = (- i + 2 - (j - 1) + 16) % 8 ;
00195 } else {
00196 ip = i ;
00197 }
00198
00199
00200 string = (1 << j) - 1 ;
00201 string <<= ip ;
00202 string = (string | (string >> 8)) & 0xff ;
00203
00204 self->mapping[string] = i * 7 + (j-1) ;
00205 }
00206 }
00207 }
00208
00209
00210
00217 VlLbp *
00218 vl_lbp_new(VlLbpMappingType type, vl_bool transposed)
00219 {
00220 VlLbp * self = vl_malloc(sizeof(VlLbp)) ;
00221 if (self == NULL) {
00222 vl_set_last_error(VL_ERR_ALLOC, NULL) ;
00223 return NULL ;
00224 }
00225 self->transposed = transposed ;
00226 switch (type) {
00227 case VlLbpUniform: _vl_lbp_init_uniform(self) ; break ;
00228 default: exit(1) ;
00229 }
00230 return self ;
00231 }
00232
00237 void
00238 vl_lbp_delete(VlLbp * self) {
00239 vl_free(self) ;
00240 }
00241
00248 VL_EXPORT vl_size vl_lbp_get_dimension(VlLbp * self)
00249 {
00250 return self->dimension ;
00251 }
00252
00253
00254
00269 VL_EXPORT void
00270 vl_lbp_process (VlLbp * self,
00271 float * features,
00272 float * image, vl_size width, vl_size height,
00273 vl_size cellSize)
00274 {
00275 vl_size cwidth = width / cellSize;
00276 vl_size cheight = height / cellSize ;
00277 vl_size cstride = cwidth * cheight ;
00278 vl_size cdimension = vl_lbp_get_dimension(self) ;
00279 vl_index x,y,cx,cy,k,bin ;
00280
00281 #define at(u,v) (*(image + width * (v) + (u)))
00282 #define to(u,v,w) (*(features + cstride * (w) + cwidth * (v) + (u)))
00283
00284
00285 memset(features, 0, sizeof(float)*cdimension*cstride) ;
00286
00287
00288 for (y = 1 ; y < (signed)height - 1 ; ++y) {
00289 float wy1 = (y + 0.5f) / (float)cellSize - 0.5f ;
00290 int cy1 = (int) vl_floor_f(wy1) ;
00291 int cy2 = cy1 + 1 ;
00292 float wy2 = wy1 - (float)cy1 ;
00293 wy1 = 1.0f - wy2 ;
00294 if (cy1 >= (signed)cheight) continue ;
00295
00296 for (x = 1 ; x < (signed)width - 1; ++x) {
00297 float wx1 = (x + 0.5f) / (float)cellSize - 0.5f ;
00298 int cx1 = (int) vl_floor_f(wx1) ;
00299 int cx2 = cx1 + 1 ;
00300 float wx2 = wx1 - (float)cx1 ;
00301 wx1 = 1.0f - wx2 ;
00302 if (cx1 >= (signed)cwidth) continue ;
00303
00304 {
00305 int unsigned bitString = 0 ;
00306 float center = at(x,y) ;
00307 if(at(x+1,y+0) > center) bitString |= 0x1 << 0;
00308 if(at(x+1,y+1) > center) bitString |= 0x1 << 1;
00309 if(at(x+0,y+1) > center) bitString |= 0x1 << 2;
00310 if(at(x-1,y+1) > center) bitString |= 0x1 << 3;
00311 if(at(x-1,y+0) > center) bitString |= 0x1 << 4;
00312 if(at(x-1,y-1) > center) bitString |= 0x1 << 5;
00313 if(at(x+0,y-1) > center) bitString |= 0x1 << 6;
00314 if(at(x+1,y-1) > center) bitString |= 0x1 << 7;
00315 bin = self->mapping[bitString] ;
00316 }
00317
00318 if ((cx1 >= 0) & (cy1 >=0)) {
00319 to(cx1,cy1,bin) += wx1 * wy1;
00320 }
00321 if ((cx2 < (signed)cwidth) & (cy1 >=0)) {
00322 to(cx2,cy1,bin) += wx2 * wy1 ;
00323 }
00324 if ((cx1 >= 0) & (cy2 < (signed)cheight)) {
00325 to(cx1,cy2,bin) += wx1 * wy2 ;
00326 }
00327 if ((cx2 < (signed)cwidth) & (cy2 < (signed)cheight)) {
00328 to(cx2,cy2,bin) += wx2 * wy2 ;
00329 }
00330 }
00331 }
00332
00333
00334 for (cy = 0 ; cy < (signed)cheight ; ++cy) {
00335 for (cx = 0 ; cx < (signed)cwidth ; ++ cx) {
00336 float norm = 0 ;
00337 for (k = 0 ; k < (signed)cdimension ; ++k) {
00338 norm += features[k * cstride] ;
00339 }
00340 norm = sqrtf(norm) + 1e-10f; ;
00341 for (k = 0 ; k < (signed)cdimension ; ++k) {
00342 features[k * cstride] = sqrtf(features[k * cstride]) / norm ;
00343 }
00344 features += 1 ;
00345 }
00346 }
00347 }