VLFeat.org

API docs

  • Home
    • Download and Install
    • API docs
    • Matlab docs
    • About VLFeat
  • Tutorials
    • SIFT
    • MSER
    • IKM
    • HIKM
    • AIB
    • Utils
  • Main Page
  • Related Pages
  • Data Structures
  • Files
  • Examples

dhog.c

Go to the documentation of this file.
00001 
00007 /* AUTORIGHTS */
00008 
00009 #include "dhog.h"
00010 #include "pgm.h"
00011 #include "mathop.h"
00012 #include "imopv.h"
00013 #include <math.h>
00014 #include <string.h>
00015 
00016 int const NBP = 4 ;
00017 int const NBO = 8 ;
00018 
00019 
00105 VL_INLINE float
00106 normalize_histogram 
00107 (float *begin, float *end)
00108 {
00109   float* iter ;
00110   float  norm = 0.0 ;
00111   
00112   for (iter = begin ; iter != end ; ++ iter)
00113     norm += (*iter) * (*iter) ;
00114   
00115   norm = vl_fast_sqrt_f (norm) + VL_EPSILON_F ;
00116   
00117   for (iter = begin; iter != end ; ++ iter)
00118     *iter /= norm ;
00119   
00120   return norm;
00121 }
00122 
00133 VL_EXPORT
00134 VlDhogFilter* 
00135 vl_dhog_new (int width, int height, int sampling_step, int bin_size)
00136 {
00137   int t ;
00138   VlDhogFilter* f = vl_malloc (sizeof(VlDhogFilter)) ;
00139   
00140   f-> width   = width ;
00141   f-> height  = height ;
00142   f-> dwidth  = (width  - 1 - (NBP - 1)*bin_size) / sampling_step + 1;
00143   f-> dheight = (height - 1 - (NBP - 1)*bin_size) / sampling_step + 1;
00144   f-> nkeys  = f->dwidth * f->dheight ;
00145   f-> sampling_step = sampling_step ;
00146   f-> bin_size = bin_size ;
00147 
00148   f-> descr = vl_malloc (sizeof(float) * 128 * f->nkeys) ;
00149   f-> keys  = vl_malloc (sizeof(VlDhogKeypoint) * f->nkeys) ;
00150   f-> tmp   = vl_malloc (sizeof(float) * f->width * f->height) ;
00151   f-> tmp2  = vl_malloc (sizeof(float) * f->width * f->height) ;
00152   f-> hist  = vl_malloc (sizeof(float*) * NBO) ;
00153   for (t = 0 ; t < NBO ; ++t) {
00154     f->hist [t] = vl_malloc (sizeof(float) * f->width * f->height) ;
00155   }
00156   return f ;
00157 }
00158 
00164 VL_EXPORT
00165 void
00166 vl_dhog_delete (VlDhogFilter *f)
00167 {
00168   if (f) {
00169     int t ;
00170     if (f->hist) {      
00171       for (t = 0 ; t < NBO ; ++t)
00172         if (f->hist[t]) vl_free (f->hist[t]) ;
00173       vl_free (f->hist) ;
00174     }
00175     if (f->tmp2) vl_free (f->tmp2) ;
00176     if (f->tmp) vl_free (f->tmp) ;
00177     if (f->descr) vl_free (f->keys) ;
00178     if (f->descr) vl_free (f->descr) ;
00179     vl_free(f) ;
00180   }
00181 }
00182 
00190 float * _vl_dhog_new_kernel (VlDhogFilter *f, int i)
00191 {
00192   int filt_len = 2*f->bin_size - 1 ;
00193   float * ker = vl_malloc (sizeof(float) * filt_len) ;
00194   float delta = f->bin_size * (NBP / 2.0f - (i + 0.5)) ;
00195   float * kerit = ker ;
00196   float sigma = (NBP * f->bin_size) / 2.0f ;
00197   int k ;
00198   
00199   for (k  = - f->bin_size + 1 ;
00200        k <= + f->bin_size - 1 ;
00201        ++ k) {
00202     float z = (k - delta) / sigma ;
00203     *kerit++ = (1.0f - fabsf(k) / f->bin_size) * 
00204       ((i >= 0) ? expf(-0.5f * z*z) : 1.0f) ;
00205   }
00206   return ker ;
00207 }
00208 
00214 VL_INLINE 
00215 void _vl_dhog_with_gaussian_window (VlDhogFilter* f)
00216 {
00217   int binx, biny, bint, centx, centy ;
00218   float *xker, *yker ;
00219   int W = f->bin_size - 1 ;
00220     
00221   for (biny = 0 ; biny < NBP ; ++biny) {
00222     yker = _vl_dhog_new_kernel(f, biny) ;
00223     
00224     for (binx = 0 ; binx < NBP ; ++binx) {
00225       xker = _vl_dhog_new_kernel(f, binx) ;
00226       
00227       for (bint = 0 ; bint < NBO ; ++bint) {
00228         float *dst = f->descr + binx * NBO + biny * (NBP*NBO) + bint ;
00229         float *src = f->tmp ;
00230         
00231         vl_imconvcol_vf (f->tmp2, f->height,
00232                          f->hist [bint], f->width, f->height, f->width,
00233                          yker, -W, +W, 1,
00234                          VL_PAD_BY_CONTINUITY|VL_TRANSPOSE) ;
00235         
00236         vl_imconvcol_vf (f->tmp, f->width,
00237                          f->tmp2, f->height, f->width, f->height,
00238                          xker, -W, +W, 1,
00239                          VL_PAD_BY_CONTINUITY|VL_TRANSPOSE) ;
00240         
00241         {
00242           int A = f->bin_size * (NBP - 1) ;
00243           int d = f->sampling_step ;
00244           
00245           for (centy = 0 ;
00246                centy <= (f->height - 1 - A) / d ;
00247                ++ centy) {
00248             for (centx = 0 ;
00249                  centx <= (f->width - 1 - A) / d ;
00250                  ++ centx) {
00251               *dst = src [(centx + f->width*centy)*d +
00252                           (binx + f->width*biny)*f->bin_size] ;
00253               dst += NBP*NBP*NBO ;
00254             }
00255           }
00256         }
00257       } /* for t */
00258       vl_free (xker) ;
00259     } /* for x */
00260     vl_free (yker) ;
00261   } /* for biny */  
00262 }
00263 
00269 VL_INLINE 
00270 void _vl_dhog_with_flat_window (VlDhogFilter* f)
00271 {
00272   int binx, biny, bint, centx, centy ;
00273 /*  float *ker = _vl_dhog_new_kernel(f, -1);*/
00274   int W = f->bin_size - 1 ;
00275     
00276   for (bint = 0 ; bint < NBO ; ++bint) {
00277 
00278     /*
00279     vl_imconvcol_vf (f->tmp2, f->height,
00280                      f->hist [bint], f->width, f->height, f->width,
00281                      ker, -W, +W, 1,
00282                      VL_PAD_BY_CONTINUITY|VL_TRANSPOSE) ;
00283     
00284     vl_imconvcol_vf (f->tmp, f->width,
00285                      f->tmp2, f->height, f->width, f->height,
00286                      ker, -W, +W, 1,
00287                      VL_PAD_BY_CONTINUITY|VL_TRANSPOSE) ;
00288     */
00289     
00290     vl_imconvcoltri_vf (f->tmp2, f->height,
00291                         f->hist [bint], f->width, f->height, f->width,
00292                         W, 1,
00293                         VL_PAD_BY_CONTINUITY|VL_TRANSPOSE) ;
00294     
00295     vl_imconvcoltri_vf (f->tmp, f->width,
00296                         f->tmp2, f->height, f->width, f->height,
00297                         W, 1,
00298                         VL_PAD_BY_CONTINUITY|VL_TRANSPOSE) ;
00299     
00300     
00301     for (biny = 0 ; biny < NBP ; ++biny) {
00302       for (binx = 0 ; binx < NBP ; ++binx) {
00303         
00304         float *dst = f->descr + binx * NBO + biny * (NBP*NBO) + bint ;
00305         float *src = f->tmp ;
00306         int A = f->bin_size * (NBP - 1) ;
00307         int d = f->sampling_step ;
00308         
00309         for (centy = 0 ;
00310              centy <= (f->height - 1 - A) / d ;
00311              ++ centy) {
00312           for (centx = 0 ;
00313                centx <= (f->width - 1 - A) / d ;
00314                ++ centx) {
00315             *dst = src [(centx + f->width*centy)*d +
00316                         (binx + f->width*biny)*f->bin_size] ;
00317             dst += NBP*NBP*NBO ;
00318           } /* centx */
00319         } /* centy */
00320       } /* binx */
00321     } /* biny */
00322   } /* bint */
00323 /*  vl_free (ker) ;*/
00324 }
00325 
00335 void vl_dhog_process (VlDhogFilter* f, float const* im, vl_bool fast)
00336 {
00337   int t, x, y ;
00338 
00339   /* clear integral images */
00340   for (t = 0 ; t < NBO ; ++t)
00341     memset (f->hist[t], 0, f->width*f->height*sizeof(float)) ;
00342   
00343 #undef at
00344 #define at(u,v) (im[(v)*f->width+(u)])
00345   
00346   /*  */
00347   for (y = 0 ; y < f->height ; ++y) {
00348     for (x = 0 ; x < f->width ; ++x) {      
00349       float gx, gy ;
00350       float angle, mod, nt, rbint ;
00351       int bint ;
00352       
00353       /* y derivative */
00354       if (y == 0) {
00355         gy = at(x,y+1) - at(x,y) ;
00356       } else if (y == f->height-1) {
00357         gy = at(x,y) - at(x,y-1) ;
00358       } else {
00359         gy = 0.5f*(at(x,y+1) - at(x,y-1)) ;
00360       }
00361       
00362       /* x derivative */
00363       if (x == 0) {
00364         gx = at(x+1,y) - at(x,y) ;
00365       } else if (x == f->width-1) {
00366         gx = at(x,y) - at(x-1,y) ;
00367       } else {
00368         gx = 0.5f*(at(x+1,y) - at(x-1,y)) ;
00369       }
00370       
00371       /* angle and modulus */
00372       angle = vl_fast_atan2_f (gy,gx) ;
00373       mod = vl_fast_sqrt_f (gx*gx + gy*gy) ;
00374             
00375       /* quantize angle */
00376       nt = vl_mod_2pi_f (angle) * (NBO / (2*VL_PI)) ;
00377       bint = vl_floor_f (nt) ;
00378       rbint = nt - bint ;
00379       
00380       /* write it back */
00381       f->hist[bint%NBO]    [x + y * f->width] += (1 - rbint) * mod ;      
00382       f->hist[(bint+1)%NBO][x + y * f->width] += rbint * mod ;
00383     }
00384   }
00385 
00386   if (fast) {
00387     _vl_dhog_with_flat_window(f) ;
00388   } else {
00389     _vl_dhog_with_gaussian_window(f) ;
00390   }
00391   
00392   {
00393     VlDhogKeypoint* k = f->keys ;
00394     int centx, centy, bint ;
00395     int A = f->bin_size * (NBP - 1) ;
00396     double A_ = f->bin_size * (NBP - 1) / 2.0f ;
00397     int d = f->sampling_step ;
00398     float *dpt = f->descr ;
00399     
00400     for (centy = 0 ;
00401          centy <= (f->height - 1 - A) / d ;
00402          ++ centy) {
00403       for (centx = 0 ;
00404            centx <= (f->width - 1 - A) / d ;
00405            ++ centx) {
00406         k->x = centx*d + A_ ;
00407         k->y = centy*d + A_ ;
00408         
00409         k->norm = normalize_histogram (dpt, dpt + NBP*NBP*NBO) ;
00410         for(bint = 0; bint < NBO*NBP*NBP ; ++ bint) {
00411           if (dpt[bint] > 0.2f) dpt[bint] = 0.2f ;
00412         }
00413         k->norm *= normalize_histogram (dpt, dpt + NBP*NBP*NBO) ;
00414         ++ k ;
00415         dpt += NBP*NBP*NBO ;
00416       } /* centx */
00417     } /* centy */
00418   }
00419 }
00420   
Copyright © 2008 Andrea Vedaldi and Brian Fulkerson