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

sift.c

Go to the documentation of this file.
00001 
00007 /* AUTORIGHTS
00008 Copyright 2007 (c) Andrea Vedaldi and Brian Fulkerson
00009 
00010 This file is part of VLFeat, available in the terms of the GNU
00011 General Public License version 2.
00012 */
00013 
00340 #include "sift.h"
00341 #include "imop.h"
00342 #include "mathop.h"
00343 
00344 #include <assert.h>
00345 #include <stdlib.h>
00346 #include <string.h>
00347 #include <math.h>
00348 #include <stdio.h>
00349 
00351 #define VL_SIFT_BILINEAR_ORIENTATIONS 1
00352 
00353 #define EXPN_SZ  256          
00354 #define EXPN_MAX 25.0         
00355 double expn_tab [EXPN_SZ+1] ; 
00357 #define log2(x) (log(x)/VL_LOG_OF_2)
00358 
00370 VL_INLINE double
00371 fast_expn (double x)
00372 {
00373   double a,b,r ;
00374   int i ;
00375   assert(0 <= x && x <= EXPN_MAX) ;
00376 
00377   x *= EXPN_SZ / EXPN_MAX ;
00378   i = vl_floor_d (x) ;
00379   r = x - i ;
00380   a = expn_tab [i    ] ;
00381   b = expn_tab [i + 1] ;
00382   return a + r * (b - a) ;
00383 }
00384 
00390 VL_INLINE void
00391 fast_expn_init ()
00392 {
00393   int k  ;
00394   for(k = 0 ; k < EXPN_SZ + 1 ; ++ k) {
00395     expn_tab [k] = exp (- (double) k * (EXPN_MAX / EXPN_SZ)) ;
00396   }
00397 }
00398 
00415 static void 
00416 copy_and_upsample_rows 
00417 (vl_sift_pix       *dst, 
00418  vl_sift_pix const *src, int width, int height)
00419 {
00420   int x, y ;
00421   vl_sift_pix a, b ;
00422 
00423   for(y = 0 ; y < height ; ++y) {
00424     b = a = *src++ ;
00425     for(x = 0 ; x < width - 1 ; ++x) {
00426       b = *src++ ;
00427       *dst = a ;             dst += height ;
00428       *dst = 0.5 * (a + b) ; dst += height ;
00429       a = b ;
00430     }
00431     *dst = b ; dst += height ;
00432     *dst = b ; dst += height ;
00433     dst += 1 - width * 2 * height ;
00434   }  
00435 }
00436 
00454 static void 
00455 copy_and_downsample
00456 (vl_sift_pix       *dst, 
00457  vl_sift_pix const *src, 
00458  int width, int height, int d)
00459 {
00460   int x, y ;
00461 
00462   d = 1 << d ; /* d = 2^d */
00463   for(y = 0 ; y < height ; y+=d) {
00464     vl_sift_pix const * srcrowp = src + y * width ;    
00465     for(x = 0 ; x < width - (d-1) ; x+=d) {     
00466       *dst++ = *srcrowp ;
00467       srcrowp += d ;
00468     }
00469   }
00470 }
00471 
00491 VL_EXPORT
00492 VlSiftFilt *
00493 vl_sift_new (int width, int height,
00494              int noctaves, int nlevels,
00495              int o_min)
00496 {
00497   VlSiftFilt *f = vl_malloc (sizeof(VlSiftFilt)) ;
00498 
00499   int w   = VL_SHIFT_LEFT (width,  -o_min) ;
00500   int h   = VL_SHIFT_LEFT (height, -o_min) ;
00501   int nel = w * h ;
00502 
00503   /* negative value O => calculate max. value */
00504   if (noctaves < 0) {
00505     noctaves = VL_MAX (floor (log2 (VL_MIN(width, height))) - o_min - 3, 1) ;
00506   }
00507 
00508   f-> width   = width ;
00509   f-> height  = height ;
00510   f-> O       = noctaves ;
00511   f-> S       = nlevels ;
00512   f-> o_min   = o_min ;
00513   f-> s_min   = -1 ;
00514   f-> s_max   = nlevels + 1 ;
00515   f-> o_cur   = o_min ;
00516 
00517   f-> temp    = vl_malloc (sizeof(vl_sift_pix) * nel    ) ;
00518   f-> octave  = vl_malloc (sizeof(vl_sift_pix) * nel 
00519                         * (f->s_max - f->s_min + 1)  ) ;
00520   f-> dog     = vl_malloc (sizeof(vl_sift_pix) * nel 
00521                         * (f->s_max - f->s_min    )  ) ;
00522   f-> grad    = vl_malloc (sizeof(vl_sift_pix) * nel * 2 
00523                         * (f->s_max - f->s_min    )  ) ;
00524 
00525   f-> sigman  = 0.5 ;
00526   f-> sigma0  = 1.6 * pow (2.0, 1.0 / nlevels) ;      
00527   f-> sigmak  =       pow (2.0, 1.0 / nlevels) ;
00528   f-> dsigma0 = f->sigma0 * sqrt (1.0 - 1.0 / (f->sigmak*f->sigmak)) ;
00529 
00530   /*
00531   VL_PRINTF ("sigman = %g\n", f-> sigman) ;
00532   VL_PRINTF ("sigma0 = %g\n", f-> sigma0) ;
00533   */
00534 
00535   f-> octave_width  = 0 ;
00536   f-> octave_height = 0 ;
00537 
00538   f-> keys     = 0 ;
00539   f-> nkeys    = 0 ;
00540   f-> keys_res = 0 ;
00541 
00542   f-> peak_thresh = 0.0 ;
00543   f-> edge_thresh = 10.0 ;
00544   f-> norm_thresh = 0.0 ;
00545   f-> magnif      = 3.0 ;
00546 
00547   f-> grad_o  = o_min - 1 ;
00548 
00549   /* initialize fast_expn stuff */
00550   fast_expn_init () ;
00551 
00552   return f ;
00553 }
00554 
00563 VL_EXPORT
00564 void
00565 vl_sift_delete (VlSiftFilt* f)
00566 {
00567   if(f) {
00568     if(f-> keys   ) vl_free (f-> keys   ) ;
00569     if(f-> grad   ) vl_free (f-> grad   ) ;
00570     if(f-> dog    ) vl_free (f-> dog    ) ;
00571     if(f-> octave ) vl_free (f-> octave ) ;
00572     if(f-> temp   ) vl_free (f-> temp   ) ;
00573     vl_free (f) ;
00574   }
00575 }
00576 
00593 VL_EXPORT
00594 int
00595 vl_sift_process_first_octave (VlSiftFilt *f, vl_sift_pix const *im)
00596 {
00597   int o, s, h, w ;
00598   double sa, sb ;
00599   vl_sift_pix *octave ;
00600   
00601   /* shortcuts */
00602   vl_sift_pix *temp   = f-> temp ;
00603   int width           = f-> width ;
00604   int height          = f-> height ;
00605   int o_min           = f-> o_min ;
00606   int s_min           = f-> s_min ;
00607   int s_max           = f-> s_max ;
00608   double sigma0       = f-> sigma0 ;
00609   double sigmak       = f-> sigmak ;
00610   double sigman       = f-> sigman ;
00611   double dsigma0      = f-> dsigma0 ; 
00612 
00613   /* restart from the first */
00614   f->o_cur = o_min ;
00615   f->nkeys = 0 ;
00616   w = f-> octave_width  = VL_SHIFT_LEFT(f->width,  - f->o_cur) ;
00617   h = f-> octave_height = VL_SHIFT_LEFT(f->height, - f->o_cur) ;
00618 
00619   /* is there at least one octave? */
00620   if (f->O == 0)
00621     return VL_ERR_EOF ;
00622 
00623   /* ------------------------------------------------------------------
00624    *                     Compute the first sublevel of the first octave
00625    * --------------------------------------------------------------- */
00626   
00627   /* 
00628    * If the first octave has negative index, we upscale the image; if
00629    * the first octave has positive index, we downscale the image; if
00630    * the first octave has index zero, we just copy the image.
00631    */
00632   
00633   octave = vl_sift_get_octave (f, s_min) ;
00634   
00635   if (o_min < 0) {
00636     /* double once */
00637     copy_and_upsample_rows (temp,   im,   width,      height) ;
00638     copy_and_upsample_rows (octave, temp, height, 2 * width ) ;
00639 
00640     /* double more */
00641     for(o = -1 ; o > o_min ; --o) {
00642       copy_and_upsample_rows (temp, octave, 
00643                               width << -o,      height << -o ) ; 
00644       copy_and_upsample_rows (octave, temp,   
00645                               width << -o, 2 * (height << -o)) ; 
00646     }        
00647   } 
00648   else if (o_min > 0) {
00649     /* downsample */
00650     copy_and_downsample (octave, im, width, height, o_min) ;
00651   } 
00652   else {
00653     /* direct copy */
00654     memcpy(octave, im, sizeof(vl_sift_pix) * width * height) ;
00655   }
00656   
00657   /* 
00658    * Here we adjust the smoothing of the first level of the octave.
00659    * The input image is assumed to have nominal smoothing equal to
00660    * f->simgan.
00661    */
00662   
00663   sa = sigma0 * pow (sigmak,   s_min) ;
00664   sb = sigman * pow (2.0,    - o_min) ;
00665 
00666   if (sa > sb) {
00667     double sd = sqrt (sa*sa - sb*sb) ;
00668     vl_imsmooth_f (octave, temp, octave, w, h, sd) ;
00669   }
00670   
00671   /* -----------------------------------------------------------------
00672    *                                          Compute the first octave
00673    * -------------------------------------------------------------- */
00674   
00675   for(s = s_min + 1 ; s <= s_max ; ++s) {
00676     double sd = dsigma0 * pow (sigmak, s) ;
00677     vl_imsmooth_f (vl_sift_get_octave(f, s    ), temp, 
00678                    vl_sift_get_octave(f, s - 1), w, h, sd) ;
00679   }
00680   
00681   return VL_ERR_OK ;
00682 }
00683 
00699 VL_EXPORT
00700 int
00701 vl_sift_process_next_octave (VlSiftFilt *f)
00702 {
00703 
00704   int s, h, w, s_best ;
00705   double sa, sb ;
00706   vl_sift_pix *octave, *pt ;
00707   
00708   /* shortcuts */
00709   vl_sift_pix *temp   = f-> temp ;
00710   int O               = f-> O ;
00711   int S               = f-> S ;
00712   int o_min           = f-> o_min ;
00713   int s_min           = f-> s_min ;
00714   int s_max           = f-> s_max ;
00715   double sigma0       = f-> sigma0 ;
00716   double sigmak       = f-> sigmak ;
00717   double dsigma0      = f-> dsigma0 ; 
00718 
00719   /* is there another octave ? */
00720   if (f->o_cur == o_min + O - 1)
00721     return VL_ERR_EOF ;
00722 
00723   /* retrieve base */
00724   s_best = VL_MIN(s_min + S, s_max) ;
00725   w      = vl_sift_get_octave_width  (f) ;
00726   h      = vl_sift_get_octave_height (f) ;
00727   pt     = vl_sift_get_octave        (f, s_best) ;
00728   octave = vl_sift_get_octave        (f, s_min) ;
00729 
00730   /* next octave */
00731   copy_and_downsample (octave, pt, w, h, 1) ;
00732 
00733   f-> o_cur            += 1 ;
00734   f-> nkeys             = 0 ;
00735   w = f-> octave_width  = VL_SHIFT_LEFT(f->width,  - f->o_cur) ;
00736   h = f-> octave_height = VL_SHIFT_LEFT(f->height, - f->o_cur) ;
00737   
00738   sa = sigma0 * powf (sigmak, s_min     ) ;
00739   sb = sigma0 * powf (sigmak, s_best - S) ;
00740 
00741   if (sa > sb) {
00742     double sd = sqrt (sa*sa - sb*sb) ;
00743     vl_imsmooth_f (octave, temp, octave, w, h, sd) ;
00744   }
00745 
00746   /* ------------------------------------------------------------------
00747    *                                                        Fill octave
00748    * --------------------------------------------------------------- */
00749   
00750   for(s = s_min + 1 ; s <= s_max ; ++s) {
00751     double sd = dsigma0 * pow (sigmak, s) ;
00752     vl_imsmooth_f (vl_sift_get_octave(f, s    ), temp, 
00753                    vl_sift_get_octave(f, s - 1), w, h, sd) ;
00754   }
00755 
00756   return VL_ERR_OK ;
00757 }
00758 
00769 VL_EXPORT
00770 void
00771 vl_sift_detect (VlSiftFilt * f)
00772 {  
00773   vl_sift_pix* dog   = f-> dog ;
00774   int          s_min = f-> s_min ;
00775   int          s_max = f-> s_max ;
00776   int          w     = f-> octave_width ;
00777   int          h     = f-> octave_height ;
00778   double       te    = f-> edge_thresh ;
00779   double       tp    = f-> peak_thresh ;
00780   
00781   int const    xo    = 1 ;      /* x-stride */
00782   int const    yo    = w ;      /* y-stride */
00783   int const    so    = w * h ;  /* s-stride */
00784 
00785   double       xper  = pow (2.0, f->o_cur) ;
00786 
00787   int x, y, s, i, ii, jj ;
00788   vl_sift_pix *pt, v ;
00789   VlSiftKeypoint *k ;
00790 
00791   /* clear current list */
00792   f-> nkeys = 0 ;
00793     
00794   /* compute difference of gaussian (DoG) */  
00795   pt = f-> dog ;
00796   for (s = s_min ; s <= s_max - 1 ; ++s) {
00797     vl_sift_pix* src_a = vl_sift_get_octave (f, s    ) ;
00798     vl_sift_pix* src_b = vl_sift_get_octave (f, s + 1) ;
00799     vl_sift_pix* end_a = src_a + w * h ;
00800     while (src_a != end_a) {
00801       *pt++ = *src_b++ - *src_a++ ;
00802     }
00803   }
00804   
00805   /* -----------------------------------------------------------------
00806    *                                          Find local maxima of DoG
00807    * -------------------------------------------------------------- */
00808 
00809   /* start from dog [1,1,s_min+1] */
00810   pt  = dog + xo + yo + so ;
00811   
00812   for(s = s_min + 1 ; s <= s_max - 2 ; ++s) {
00813     for(y = 1 ; y < h - 1 ; ++y) {
00814       for(x = 1 ; x < w - 1 ; ++x) {          
00815         v = *pt ;
00816                
00817 #define CHECK_NEIGHBORS(CMP,SGN)                    \
00818         ( v CMP ## = SGN 0.8 * tp &&                \
00819           v CMP *(pt + xo) &&                       \
00820           v CMP *(pt - xo) &&                       \
00821           v CMP *(pt + so) &&                       \
00822           v CMP *(pt - so) &&                       \
00823           v CMP *(pt + yo) &&                       \
00824           v CMP *(pt - yo) &&                       \
00825                                                     \
00826           v CMP *(pt + yo + xo) &&                  \
00827           v CMP *(pt + yo - xo) &&                  \
00828           v CMP *(pt - yo + xo) &&                  \
00829           v CMP *(pt - yo - xo) &&                  \
00830                                                     \
00831           v CMP *(pt + xo      + so) &&             \
00832           v CMP *(pt - xo      + so) &&             \
00833           v CMP *(pt + yo      + so) &&             \
00834           v CMP *(pt - yo      + so) &&             \
00835           v CMP *(pt + yo + xo + so) &&             \
00836           v CMP *(pt + yo - xo + so) &&             \
00837           v CMP *(pt - yo + xo + so) &&             \
00838           v CMP *(pt - yo - xo + so) &&             \
00839                                                     \
00840           v CMP *(pt + xo      - so) &&             \
00841           v CMP *(pt - xo      - so) &&             \
00842           v CMP *(pt + yo      - so) &&             \
00843           v CMP *(pt - yo      - so) &&             \
00844           v CMP *(pt + yo + xo - so) &&             \
00845           v CMP *(pt + yo - xo - so) &&             \
00846           v CMP *(pt - yo + xo - so) &&             \
00847           v CMP *(pt - yo - xo - so) )
00848         
00849         if (CHECK_NEIGHBORS(>,+) || 
00850             CHECK_NEIGHBORS(<,-) ) {
00851           
00852           /* make room for more keypoints */
00853           if (f->nkeys >= f->keys_res) {
00854             f->keys_res += 500 ;
00855             if (f->keys) {
00856               f->keys = vl_realloc (f->keys,
00857                                     f->keys_res * 
00858                                     sizeof(VlSiftKeypoint)) ;
00859             } else {
00860               f->keys = vl_malloc (f->keys_res * 
00861                                    sizeof(VlSiftKeypoint)) ;
00862             }
00863           }
00864 
00865           k = f->keys + (f->nkeys ++) ;
00866           
00867           k-> ix = x ;
00868           k-> iy = y ;
00869           k-> is = s ;
00870         }                 
00871         pt += 1 ;
00872       }
00873       pt += 2 ;
00874     }
00875     pt += 2 * yo ;
00876   }
00877   
00878   /* -----------------------------------------------------------------
00879    *                                               Refine local maxima
00880    * -------------------------------------------------------------- */
00881 
00882   /* this pointer is used to write the keypoints back */
00883   k = f->keys ;
00884 
00885   for (i = 0 ; i < f->nkeys ; ++i) {
00886         
00887     int x = f-> keys [i] .ix ;
00888     int y = f-> keys [i] .iy ;
00889     int s = f-> keys [i]. is ;
00890     
00891     double Dx=0,Dy=0,Ds=0,Dxx=0,Dyy=0,Dss=0,Dxy=0,Dxs=0,Dys=0 ;
00892     double A [3*3], b [3] ;
00893     
00894     int dx = 0 ;
00895     int dy = 0 ;
00896     
00897     int iter, i, j ;
00898     
00899     for (iter = 0 ; iter < 5 ; ++iter) {
00900       
00901       x += dx ;
00902       y += dy ;
00903       
00904       pt = dog 
00905         + xo * x
00906         + yo * y
00907         + so * (s - s_min) ;
00908 
00910 #define at(dx,dy,ds) (*( pt + (dx)*xo + (dy)*yo + (ds)*so))
00911 
00913 #define Aat(i,j)     (A[(i)+(j)*3])    
00914       
00915       /* compute the gradient */
00916       Dx = 0.5 * (at(+1,0,0) - at(-1,0,0)) ;
00917       Dy = 0.5 * (at(0,+1,0) - at(0,-1,0));
00918       Ds = 0.5 * (at(0,0,+1) - at(0,0,-1)) ;
00919       
00920       /* compute the Hessian */
00921       Dxx = (at(+1,0,0) + at(-1,0,0) - 2.0 * at(0,0,0)) ;
00922       Dyy = (at(0,+1,0) + at(0,-1,0) - 2.0 * at(0,0,0)) ;
00923       Dss = (at(0,0,+1) + at(0,0,-1) - 2.0 * at(0,0,0)) ;
00924       
00925       Dxy = 0.25 * ( at(+1,+1,0) + at(-1,-1,0) - at(-1,+1,0) - at(+1,-1,0) ) ;
00926       Dxs = 0.25 * ( at(+1,0,+1) + at(-1,0,-1) - at(-1,0,+1) - at(+1,0,-1) ) ;
00927       Dys = 0.25 * ( at(0,+1,+1) + at(0,-1,-1) - at(0,-1,+1) - at(0,+1,-1) ) ;
00928       
00929       /* solve linear system ....................................... */
00930       Aat(0,0) = Dxx ;
00931       Aat(1,1) = Dyy ;
00932       Aat(2,2) = Dss ;
00933       Aat(0,1) = Aat(1,0) = Dxy ;
00934       Aat(0,2) = Aat(2,0) = Dxs ;
00935       Aat(1,2) = Aat(2,1) = Dys ;
00936       
00937       b[0] = - Dx ;
00938       b[1] = - Dy ;
00939       b[2] = - Ds ;
00940       
00941       /* Gauss elimination */
00942       for(j = 0 ; j < 3 ; ++j) {        
00943         double maxa    = 0 ;
00944         double maxabsa = 0 ;
00945         int    maxi    = -1 ;
00946         double tmp ;
00947         
00948         /* look for the maximally stable pivot */
00949         for (i = j ; i < 3 ; ++i) {
00950           double a    = Aat (i,j) ;
00951           double absa = vl_abs_d (a) ;
00952           if (absa > maxabsa) {
00953             maxa    = a ;
00954             maxabsa = absa ;
00955             maxi    = i ;
00956           }
00957         }
00958         
00959         /* if singular give up */
00960         if (maxabsa < 1e-10f) {
00961           b[0] = 0 ;
00962           b[1] = 0 ;
00963           b[2] = 0 ;
00964           break ;
00965         }
00966         
00967         i = maxi ;
00968         
00969         /* swap j-th row with i-th row and normalize j-th row */
00970         for(jj = j ; jj < 3 ; ++jj) {
00971           tmp = Aat(i,jj) ; Aat(i,jj) = Aat(j,jj) ; Aat(j,jj) = tmp ;
00972           Aat(j,jj) /= maxa ;
00973         }
00974         tmp = b[j] ; b[j] = b[i] ; b[i] = tmp ;
00975         b[j] /= maxa ;
00976         
00977         /* elimination */
00978         for (ii = j+1 ; ii < 3 ; ++ii) {
00979           double x = Aat(ii,j) ;
00980           for (jj = j ; jj < 3 ; ++jj) {
00981             Aat(ii,jj) -= x * Aat(j,jj) ;                
00982           }
00983           b[ii] -= x * b[j] ;
00984         }
00985       }
00986       
00987       /* backward substitution */
00988       for (i = 2 ; i > 0 ; --i) {
00989         double x = b[i] ;
00990         for (ii = i-1 ; ii >= 0 ; --ii) {
00991           b[ii] -= x * Aat(ii,i) ;
00992         }
00993       }
00994 
00995       /* .......................................................... */      
00996       /* If the translation of the keypoint is big, move the keypoint
00997        * and re-iterate the computation. Otherwise we are all set.
00998        */
00999 
01000       dx= ((b[0] >  0.6 && x < w - 2) ?  1 : 0)
01001         + ((b[0] < -0.6 && x > 1    ) ? -1 : 0) ;
01002       
01003       dy= ((b[1] >  0.6 && y < h - 2) ?  1 : 0)
01004         + ((b[1] < -0.6 && y > 1    ) ? -1 : 0) ;
01005             
01006       if (dx == 0 && dy == 0) break ;
01007     }
01008         
01009     /* check threshold and other conditions */
01010     {
01011       double val   = at(0,0,0) 
01012         + 0.5 * (Dx * b[0] + Dy * b[1] + Ds * b[2]) ; 
01013       double score = (Dxx+Dyy)*(Dxx+Dyy) / (Dxx*Dyy - Dxy*Dxy) ; 
01014       double xn = x + b[0] ;
01015       double yn = y + b[1] ;
01016       double sn = s + b[2] ;
01017 
01018       vl_bool good = 
01019         vl_abs_d (val)  > tp                  &&
01020         score           < (te+1)*(te+1)/te    &&          
01021         score           >= 0                  &&
01022         vl_abs_d (b[0]) <  1.5                &&         
01023         vl_abs_d (b[1]) <  1.5                &&         
01024         vl_abs_d (b[2]) <  1.5                &&
01025         xn              >= 0                  &&         
01026         xn              <= w - 1              &&         
01027         yn              >= 0                  &&         
01028         yn              <= h - 1              &&         
01029         sn              >= s_min              &&     
01030         sn              <= s_max ;
01031 
01032       if (good) {                       
01033         k-> o     = f->o_cur ;
01034         k-> ix    = x ;
01035         k-> iy    = y ;
01036         k-> is    = s ;
01037         k-> s     = sn ;
01038         k-> x     = xn * xper ;
01039         k-> y     = yn * xper ;
01040         k-> sigma = f->sigma0 * pow (2.0, sn/f->S) * xper ;        
01041         ++ k ;
01042       }
01043 
01044     } /* done checking */
01045   } /* next keypoint to refine */
01046 
01047   /* update keypoint count */
01048   f-> nkeys = k - f->keys ;
01049 }
01050 
01051 
01064 static void
01065 update_gradient (VlSiftFilt *f)
01066 { 
01067   int       s_min = f->s_min ;
01068   int       s_max = f->s_max ;
01069   int       w     = vl_sift_get_octave_width  (f) ;
01070   int       h     = vl_sift_get_octave_height (f) ;
01071   int const xo    = 1 ;
01072   int const yo    = w ;
01073   int const so    = h * w ;
01074   int y, s ;
01075 
01076   if (f->grad_o == f->o_cur) return ;
01077   
01078   for (s  = s_min + 1 ; 
01079        s <= s_max - 2 ; ++ s) {    
01080 
01081     vl_sift_pix *src, *end, *grad, gx, gy ;
01082 
01083 #define SAVE_BACK                                                       \
01084     *grad++ = vl_fast_sqrt_f (gx*gx + gy*gy) ;                          \
01085     *grad++ = vl_mod_2pi_f   (vl_fast_atan2_f (gy, gx) + 2*VL_PI) ;     \
01086     ++src ;                                                             \
01087     
01088     src  = vl_sift_get_octave (f,s) ;
01089     grad = f->grad + 2 * so * (s - s_min -1) ;
01090     
01091     /* first first row */
01092     gx = src[+xo] - src[0] ;
01093     gy = src[+yo] - src[0] ;
01094     SAVE_BACK ;
01095 
01096     /* middle first row */
01097     end = (src - 1) + w - 1 ;
01098     while (src < end) {
01099       gx = 0.5 * (src[+xo] - src[-xo]) ;
01100       gy =        src[+yo] - src[0] ;
01101       SAVE_BACK ;
01102     }
01103     
01104     /* first first row */
01105     gx = src[0]   - src[-xo] ;
01106     gy = src[+yo] - src[0] ;
01107     SAVE_BACK ;
01108     
01109     for (y = 1 ; y < h -1 ; ++y) {
01110 
01111       /* first middle row */
01112       gx =        src[+xo] - src[0] ;
01113       gy = 0.5 * (src[+yo] - src[-yo]) ;
01114       SAVE_BACK ;
01115 
01116       /* middle middle row */
01117       end = (src - 1) + w - 1 ;
01118       while (src < end) {
01119         gx = 0.5 * (src[+xo] - src[-xo]) ;
01120         gy = 0.5 * (src[+yo] - src[-yo]) ;
01121         SAVE_BACK ;
01122       }
01123       
01124       /* last middle row */
01125       gx =        src[0]   - src[-xo] ;
01126       gy = 0.5 * (src[+yo] - src[-yo]) ;
01127       SAVE_BACK ;
01128     }
01129 
01130     /* first last row */
01131     gx = src[+xo] - src[0] ;
01132     gy = src[  0] - src[-yo] ;
01133     SAVE_BACK ;
01134     
01135     /* middle last row */
01136     end = (src - 1) + w - 1 ;
01137     while (src < end) {
01138       gx = 0.5 * (src[+xo] - src[-xo]) ;
01139       gy =        src[0]   - src[-yo] ;
01140       SAVE_BACK ;
01141     }
01142     
01143     /* last last row */
01144     gx = src[0]   - src[-xo] ;
01145     gy = src[0]   - src[-yo] ;
01146     SAVE_BACK ;
01147   }  
01148   f->grad_o = f->o_cur ;
01149 }
01150 
01175 VL_EXPORT
01176 int
01177 vl_sift_calc_keypoint_orientations (VlSiftFilt *f, 
01178                                     double angles [4],
01179                                     VlSiftKeypoint const *k)
01180 {
01181   double const winf   = 1.5 ;
01182   double       xper   = pow (2.0, f->o_cur) ;
01183 
01184   int          w      = f-> octave_width ;
01185   int          h      = f-> octave_height ;
01186   int const    xo     = 2 ;         /* x-stride */
01187   int const    yo     = 2 * w ;     /* y-stride */
01188   int const    so     = 2 * w * h ; /* s-stride */
01189   double       x      = k-> x     / xper ;
01190   double       y      = k-> y     / xper ;
01191   double       sigma  = k-> sigma / xper ;
01192 
01193   int          xi     = (int) (x + 0.5) ; 
01194   int          yi     = (int) (y + 0.5) ;
01195   int          si     = k-> is ;
01196 
01197   double const sigmaw = winf * sigma ;
01198   int          W      = VL_MAX(floor (3.0 * sigmaw), 1) ;
01199 
01200   int          nangles= 0 ;
01201 
01202   enum {nbins = 36} ;
01203 
01204   double hist [nbins], maxh ;
01205   vl_sift_pix const * pt ;
01206   int xs, ys, iter, i ;
01207   
01208   /* skip if the keypoint octave is not current */
01209   if(k->o != f->o_cur)
01210     return 0 ;
01211   
01212   /* skip the keypoint if it is out of bounds */
01213   if(xi < 0            || 
01214      xi > w - 1        || 
01215      yi < 0            || 
01216      yi > h - 1        || 
01217      si < f->s_min + 1 || 
01218      si > f->s_max - 2  ) {
01219     return 0 ;
01220   }
01221   
01222   /* make gradient up to date */
01223   update_gradient (f) ;
01224 
01225   /* clear histogram */
01226   memset (hist, 0, sizeof(double) * nbins) ;
01227   
01228   /* compute orientation histogram */
01229   pt = f-> grad + xo*xi + yo*yi + so*(si - f->s_min - 1) ;
01230 
01231 #undef  at
01232 #define at(dx,dy) (*(pt + xo * (dx) + yo * (dy)))
01233 
01234   /*
01235   for(ys  =  VL_MAX (- W - 1, 1 - yi    ) ; 
01236       ys <=  VL_MIN (+ W + 1, h - 2 - yi) ; ++ys) {
01237     
01238     for(xs  = VL_MAX (- W - 1, 1 - xi    ) ; 
01239     xs <= VL_MIN (+ W + 1, w - 2 - xi) ; ++xs) {*/
01240 
01241   for(ys  =  VL_MAX (- W,       - yi) ; 
01242       ys <=  VL_MIN (+ W, h - 1 - yi) ; ++ys) {
01243     
01244     for(xs  = VL_MAX (- W,       - xi) ; 
01245         xs <= VL_MIN (+ W, w - 1 - xi) ; ++xs) {
01246 
01247       
01248       double dx = (double)(xi + xs) - x;
01249       double dy = (double)(yi + ys) - y;
01250       double r2 = dx*dx + dy*dy ;
01251       double wgt, mod, ang, fbin ;
01252 
01253       /* limit to a circular window */
01254       if (r2 >= W*W + 0.6) continue ;
01255 
01256       wgt  = fast_expn (r2 / (2*sigmaw*sigmaw)) ;
01257       mod  = *(pt + xs*xo + ys*yo    ) ;
01258       ang  = *(pt + xs*xo + ys*yo + 1) ;
01259       fbin = nbins * ang / (2 * VL_PI) ;
01260        
01261 #if defined(VL_SIFT_BILINEAR_ORIENTATIONS)
01262       {
01263         int    bin  = vl_floor_d (fbin - 0.5) ;
01264         double rbin = fbin - bin - 0.5 ;
01265         hist [(bin + nbins) % nbins] += (1 - rbin) * mod * wgt ;
01266         hist [(bin + 1    ) % nbins] += (    rbin) * mod * wgt ;
01267       }
01268 #else
01269       {
01270         int    bin  = vl_floor_d (fbin) ;
01271         bin = vl_floor_d (nbins * ang / (2*VL_PI)) ;
01272         hist [(bin) % nbins] += mod * wgt ;        
01273       }
01274 #endif
01275       
01276     } /* for xs */
01277   } /* for ys */
01278 
01279   /* smooth histogram */
01280   for (iter = 0; iter < 6; iter ++) {
01281     double prev  = hist [nbins - 1] ;
01282     double first = hist [0] ;
01283     int i ;
01284     for (i = 0; i < nbins - 1; i++) {
01285       double newh = (prev + hist[i] + hist[(i+1) % nbins]) / 3.0;
01286       prev = hist[i] ;
01287       hist[i] = newh ;
01288     }
01289     hist[i] = (prev + hist[i] + first) / 3.0 ;
01290   }
01291   
01292   /* find the histogram maximum */
01293   maxh = 0 ;
01294   for (i = 0 ; i < nbins ; ++i) 
01295     maxh = VL_MAX (maxh, hist [i]) ;
01296 
01297   /* find peaks within 80% from max */
01298   nangles = 0 ;
01299   for(i = 0 ; i < nbins ; ++i) {
01300     double h0 = hist [i] ;
01301     double hm = hist [(i - 1 + nbins) % nbins] ;
01302     double hp = hist [(i + 1 + nbins) % nbins] ;
01303     
01304     /* is this a peak? */
01305     if (h0 > 0.8*maxh && h0 > hm && h0 > hp) {
01306       
01307       /* quadratic interpolation */
01308       double di = - 0.5 * (hp - hm) / (hp + hm - 2 * h0) ; 
01309       double th = 2 * VL_PI * (i + di + 0.5) / nbins ;      
01310       angles [ nangles++ ] = th ;
01311       if( nangles == 4 )
01312         goto enough_angles ;
01313     }
01314   }
01315  enough_angles:
01316   return nangles ;
01317 }
01318 
01319 
01327 VL_INLINE vl_sift_pix
01328 normalize_histogram 
01329 (vl_sift_pix *begin, vl_sift_pix *end)
01330 {
01331   vl_sift_pix* iter ;
01332   vl_sift_pix  norm = 0.0 ;
01333 
01334   for (iter = begin ; iter != end ; ++ iter)
01335     norm += (*iter) * (*iter) ;
01336 
01337   norm = vl_fast_sqrt_f (norm) + VL_EPSILON_F ;
01338 
01339   for (iter = begin; iter != end ; ++ iter)
01340     *iter /= norm ;
01341 
01342   return norm;
01343 }
01344 
01377 VL_EXPORT
01378 void               
01379 vl_sift_calc_raw_descriptor (VlSiftFilt const *f,
01380                              vl_sift_pix const* grad,
01381                              vl_sift_pix *descr,
01382                              int width, int height,
01383                              double x, double y, 
01384                              double sigma,
01385                              double angle0)
01386 {
01387   double const magnif = f-> magnif ;
01388   int const    NBO    = 8 ;
01389   int const    NBP    = 4 ;
01390 
01391   int          w      = width ;
01392   int          h      = height ;
01393   int const    xo     = 2 ;         /* x-stride */
01394   int const    yo     = 2 * w ;     /* y-stride */
01395   
01396   int          xi     = (int) (x + 0.5) ; 
01397   int          yi     = (int) (y + 0.5) ;
01398   
01399   double const st0    = sin (angle0) ;
01400   double const ct0    = cos (angle0) ;
01401   double const SBP    = magnif * sigma + VL_EPSILON_D ;
01402   int    const W      = floor
01403     (sqrt(2.0) * SBP * (NBP + 1) / 2.0 + 0.5) ;
01404   
01405   int const binto = 1 ;          /* bin theta-stride */
01406   int const binyo = NBO * NBP ;  /* bin y-stride */
01407   int const binxo = NBO ;        /* bin x-stride */
01408   
01409   int bin, dxi, dyi ;
01410   vl_sift_pix const *pt ; 
01411   vl_sift_pix       *dpt ;
01412   
01413   /* check bounds */
01414   if(xi    <  0               || 
01415      xi    >= w               || 
01416      yi    <  0               || 
01417      yi    >= h -    1        )
01418     return ;
01419   
01420   /* clear descriptor */
01421   memset (descr, 0, sizeof(vl_sift_pix) * NBO*NBP*NBP) ;
01422   
01423   /* Center the scale space and the descriptor on the current keypoint. 
01424    * Note that dpt is pointing to the bin of center (SBP/2,SBP/2,0).
01425    */
01426   pt  = grad + xi*xo + yi*yo ;
01427   dpt = descr + (NBP/2) * binyo + (NBP/2) * binxo ;
01428 
01429 #undef atd
01430 #define atd(dbinx,dbiny,dbint) *(dpt + (dbint)*binto + (dbiny)*binyo + (dbinx)*binxo)
01431   
01432   /*
01433    * Process pixels in the intersection of the image rectangle
01434    * (1,1)-(M-1,N-1) and the keypoint bounding box.
01435    */
01436   for(dyi =  VL_MAX (- W, 1 - yi    ) ; 
01437       dyi <= VL_MIN (+ W, h - yi - 2) ; ++ dyi) {
01438     
01439     for(dxi =  VL_MAX (- W, 1 - xi    ) ; 
01440         dxi <= VL_MIN (+ W, w - xi - 2) ; ++ dxi) {
01441 
01442       /* retrieve */
01443       vl_sift_pix mod   = *( pt + dxi*xo + dyi*yo + 0 ) ;
01444       vl_sift_pix angle = *( pt + dxi*xo + dyi*yo + 1 ) ;
01445       vl_sift_pix theta = vl_mod_2pi_f (angle - angle0) ;
01446       
01447       /* fractional displacement */
01448       vl_sift_pix dx = xi + dxi - x;
01449       vl_sift_pix dy = yi + dyi - y;
01450       
01451       /* get the displacement normalized w.r.t. the keypoint
01452          orientation and extension */
01453       vl_sift_pix nx = ( ct0 * dx + st0 * dy) / SBP ;
01454       vl_sift_pix ny = (-st0 * dx + ct0 * dy) / SBP ; 
01455       vl_sift_pix nt = NBO * theta / (2 * VL_PI) ;
01456       
01457       /* Get the Gaussian weight of the sample. The Gaussian window
01458        * has a standard deviation equal to NBP/2. Note that dx and dy
01459        * are in the normalized frame, so that -NBP/2 <= dx <=
01460        * NBP/2. */
01461       vl_sift_pix const wsigma = NBP/2 ;
01462       vl_sift_pix win = fast_expn 
01463         ((nx*nx + ny*ny)/(2.0 * wsigma * wsigma)) ;
01464       
01465       /* The sample will be distributed in 8 adjacent bins.
01466          We start from the ``lower-left'' bin. */
01467       int         binx = vl_floor_f (nx - 0.5) ;
01468       int         biny = vl_floor_f (ny - 0.5) ;
01469       int         bint = vl_floor_f (nt) ;
01470       vl_sift_pix rbinx = nx - (binx + 0.5) ;
01471       vl_sift_pix rbiny = ny - (biny + 0.5) ;
01472       vl_sift_pix rbint = nt - bint ;
01473       int         dbinx ;
01474       int         dbiny ;
01475       int         dbint ;
01476       
01477       /* Distribute the current sample into the 8 adjacent bins*/
01478       for(dbinx = 0 ; dbinx < 2 ; ++dbinx) {
01479         for(dbiny = 0 ; dbiny < 2 ; ++dbiny) {
01480           for(dbint = 0 ; dbint < 2 ; ++dbint) {
01481             
01482             if (binx + dbinx >= - (NBP/2) &&
01483                 binx + dbinx <    (NBP/2) &&
01484                 biny + dbiny >= - (NBP/2) &&
01485                 biny + dbiny <    (NBP/2) ) {
01486               vl_sift_pix weight = win 
01487                 * mod 
01488                 * vl_abs_f (1 - dbinx - rbinx)
01489                 * vl_abs_f (1 - dbiny - rbiny)
01490                 * vl_abs_f (1 - dbint - rbint) ;
01491               
01492               atd(binx+dbinx, biny+dbiny, (bint+dbint) % NBO) += weight ;
01493             }
01494           }            
01495         }
01496       }
01497     }  
01498   }
01499 
01500   /* Standard SIFT descriptors are normalized, truncated and normalized again */
01501   if(1) {
01502 
01503     /* Normalize the histogram to L2 unit length. */        
01504     vl_sift_pix norm = normalize_histogram (descr, descr + NBO*NBP*NBP) ;
01505 
01506     /* Set the descriptor to zero if it is lower than our norm_threshold */
01507     if(f-> norm_thresh && norm < f-> norm_thresh) {
01508         for(bin = 0; bin < NBO*NBP*NBP ; ++ bin)
01509             descr [bin] = 0;
01510     }
01511     else {
01512     
01513       /* Truncate at 0.2. */
01514       for(bin = 0; bin < NBO*NBP*NBP ; ++ bin) {
01515         if (descr [bin] > 0.2) descr [bin] = 0.2;
01516       }
01517       
01518       /* Normalize again. */
01519       normalize_histogram (descr, descr + NBO*NBP*NBP) ;
01520     }
01521   }
01522 }
01523 
01524 
01541 VL_EXPORT
01542 void
01543 vl_sift_calc_keypoint_descriptor (VlSiftFilt *f,
01544                                   vl_sift_pix *descr,
01545                                   VlSiftKeypoint const* k,
01546                                   double angle0)
01547 {
01548   /* 
01549      The SIFT descriptor is a three dimensional histogram of the
01550      position and orientation of the gradient.  There are NBP bins for
01551      each spatial dimension and NBO bins for the orientation dimension,
01552      for a total of NBP x NBP x NBO bins.
01553      
01554      The support of each spatial bin has an extension of SBP = 3sigma
01555      pixels, where sigma is the scale of the keypoint.  Thus all the
01556      bins together have a support SBP x NBP pixels wide. Since
01557      weighting and interpolation of pixel is used, the support extends
01558      by another half bin. Therefore, the support is a square window of
01559      SBP x (NBP + 1) pixels. Finally, since the patch can be
01560      arbitrarily rotated, we need to consider a window 2W += sqrt(2) x
01561      SBP x (NBP + 1) pixels wide.
01562   */      
01563   
01564   double const magnif      = f-> magnif ;
01565   int const    NBO         = 8 ;
01566   int const    NBP         = 4 ;
01567 
01568   double       xper        = pow (2.0, f->o_cur) ;
01569 
01570   int          w           = f-> octave_width ;
01571   int          h           = f-> octave_height ;
01572   int const    xo          = 2 ;         /* x-stride */
01573   int const    yo          = 2 * w ;     /* y-stride */
01574   int const    so          = 2 * w * h ; /* s-stride */
01575   double       x           = k-> x     / xper ;
01576   double       y           = k-> y     / xper ;
01577   double       sigma       = k-> sigma / xper ;
01578 
01579   int          xi          = (int) (x + 0.5) ; 
01580   int          yi          = (int) (y + 0.5) ;
01581   int          si          = k-> is ;
01582 
01583   double const st0         = sin (angle0) ;
01584   double const ct0         = cos (angle0) ;
01585   double const SBP         = magnif * sigma ;
01586   int    const W           = floor
01587     (sqrt(2.0) * SBP * (NBP + 1) / 2.0 + 0.5) ;
01588 
01589   int const binto = 1 ;          /* bin theta-stride */
01590   int const binyo = NBO * NBP ;  /* bin y-stride */
01591   int const binxo = NBO ;        /* bin x-stride */
01592 
01593   int bin, dxi, dyi ;
01594   vl_sift_pix const *pt ; 
01595   vl_sift_pix       *dpt ;
01596   
01597   /* check bounds */
01598   if(k->o  != f->o_cur        ||
01599      xi    <  0               || 
01600      xi    >= w               || 
01601      yi    <  0               || 
01602      yi    >= h -    1        ||
01603      si    <  f->s_min + 1    ||
01604      si    >  f->s_max - 2     )
01605     return ;
01606   
01607   /* synchronize gradient buffer */
01608   update_gradient (f) ;
01609 
01610   /* VL_PRINTF("W = %d ; magnif = %g ; SBP = %g\n", W,magnif,SBP) ; */
01611 
01612   /* clear descriptor */
01613   memset (descr, 0, sizeof(vl_sift_pix) * NBO*NBP*NBP) ;
01614 
01615   /* Center the scale space and the descriptor on the current keypoint. 
01616    * Note that dpt is pointing to the bin of center (SBP/2,SBP/2,0).
01617    */
01618   pt  = f->grad + xi*xo + yi*yo + (si - f->s_min - 1)*so ;
01619   dpt = descr + (NBP/2) * binyo + (NBP/2) * binxo ;
01620      
01621 #undef atd
01622 #define atd(dbinx,dbiny,dbint) *(dpt + (dbint)*binto + (dbiny)*binyo + (dbinx)*binxo)
01623       
01624   /*
01625    * Process pixels in the intersection of the image rectangle
01626    * (1,1)-(M-1,N-1) and the keypoint bounding box.
01627    */
01628   for(dyi =  VL_MAX (- W, 1 - yi    ) ; 
01629       dyi <= VL_MIN (+ W, h - yi - 2) ; ++ dyi) {
01630 
01631     for(dxi =  VL_MAX (- W, 1 - xi    ) ; 
01632         dxi <= VL_MIN (+ W, w - xi - 2) ; ++ dxi) {
01633       
01634       /* retrieve */
01635       vl_sift_pix mod   = *( pt + dxi*xo + dyi*yo + 0 ) ;
01636       vl_sift_pix angle = *( pt + dxi*xo + dyi*yo + 1 ) ;
01637       vl_sift_pix theta = vl_mod_2pi_f (angle - angle0) ;
01638       
01639       /* fractional displacement */
01640       vl_sift_pix dx = xi + dxi - x;
01641       vl_sift_pix dy = yi + dyi - y;
01642       
01643       /* get the displacement normalized w.r.t. the keypoint
01644          orientation and extension */
01645       vl_sift_pix nx = ( ct0 * dx + st0 * dy) / SBP ;
01646       vl_sift_pix ny = (-st0 * dx + ct0 * dy) / SBP ; 
01647       vl_sift_pix nt = NBO * theta / (2 * VL_PI) ;
01648       
01649       /* Get the Gaussian weight of the sample. The Gaussian window
01650        * has a standard deviation equal to NBP/2. Note that dx and dy
01651        * are in the normalized frame, so that -NBP/2 <= dx <=
01652        * NBP/2. */
01653       vl_sift_pix const wsigma = NBP/2 ;
01654       vl_sift_pix win = fast_expn 
01655         ((nx*nx + ny*ny)/(2.0 * wsigma * wsigma)) ;
01656       
01657       /* The sample will be distributed in 8 adjacent bins.
01658          We start from the ``lower-left'' bin. */
01659       int         binx = vl_floor_f (nx - 0.5) ;
01660       int         biny = vl_floor_f (ny - 0.5) ;
01661       int         bint = vl_floor_f (nt) ;
01662       vl_sift_pix rbinx = nx - (binx + 0.5) ;
01663       vl_sift_pix rbiny = ny - (biny + 0.5) ;
01664       vl_sift_pix rbint = nt - bint ;
01665       int         dbinx ;
01666       int         dbiny ;
01667       int         dbint ;
01668       
01669       /* Distribute the current sample into the 8 adjacent bins*/
01670       for(dbinx = 0 ; dbinx < 2 ; ++dbinx) {
01671         for(dbiny = 0 ; dbiny < 2 ; ++dbiny) {
01672           for(dbint = 0 ; dbint < 2 ; ++dbint) {
01673             
01674             if (binx + dbinx >= - (NBP/2) &&
01675                 binx + dbinx <    (NBP/2) &&
01676                 biny + dbiny >= - (NBP/2) &&
01677                 biny + dbiny <    (NBP/2) ) {
01678               vl_sift_pix weight = win 
01679                 * mod 
01680                 * vl_abs_f (1 - dbinx - rbinx)
01681                 * vl_abs_f (1 - dbiny - rbiny)
01682                 * vl_abs_f (1 - dbint - rbint) ;
01683               
01684               atd(binx+dbinx, biny+dbiny, (bint+dbint) % NBO) += weight ;
01685             }
01686           }            
01687         }
01688       }
01689     }  
01690   }
01691 
01692   /* Standard SIFT descriptors are normalized, truncated and normalized again */
01693   if(1) {
01694 
01695     /* Normalize the histogram to L2 unit length. */        
01696     vl_sift_pix norm = normalize_histogram (descr, descr + NBO*NBP*NBP) ;
01697 
01698     /* Set the descriptor to zero if it is lower than our norm_threshold */
01699     if(f-> norm_thresh && norm < f-> norm_thresh) {
01700         for(bin = 0; bin < NBO*NBP*NBP ; ++ bin)
01701             descr [bin] = 0;
01702     }
01703     else {
01704     
01705       /* Truncate at 0.2. */
01706       for(bin = 0; bin < NBO*NBP*NBP ; ++ bin) {
01707         if (descr [bin] > 0.2) descr [bin] = 0.2;
01708       }
01709     
01710       /* Normalize again. */
01711       normalize_histogram (descr, descr + NBO*NBP*NBP) ;
01712     }
01713   }
01714 
01715 }
01716 
01730 VL_EXPORT
01731 void
01732 vl_sift_keypoint_init (VlSiftFilt const *f,
01733                        VlSiftKeypoint *k, 
01734                        double x,
01735                        double y,
01736                        double sigma)
01737 {
01738 
01739   /*
01740     The formula linking the keypoint scale sigma to the octave and
01741     scale index is
01742 
01743     (1) sigma(o,s) = sigma0 2^(o+s/S)
01744 
01745     for which
01746     
01747     (2) o + s/S = log2 sigma/sigma0 == phi.
01748 
01749     In addition to the scale index s (which can be fractional due to
01750     scale interpolation) a keypoint has an integer scale index is too
01751     (which is the index of the scale level where it was detected in
01752     the DoG scale space). We have the constraints:
01753  
01754     - o and is are integer
01755 
01756     - is is in the range [smin+1, smax-2  ]
01757 
01758     - o  is in the range [omin,   omin+O-1]
01759 
01760     - is = rand(s) most of the times (but not always, due to the way s
01761       is obtained by quadratic interpolation of the DoG scale space).
01762 
01763     Depending on the values of smin and smax, often (2) has multiple
01764     solutions is,o that satisfy all constraints.  In this case we
01765     choose the one with biggest index o (this saves a bit of
01766     computation).
01767 
01768     DETERMINING THE OCTAVE INDEX O
01769 
01770     From (2) we have o = phi - s/S and we want to pick the biggest
01771     possible index o in the feasible range. This corresponds to
01772     selecting the smallest possible index s. We write s = is + ds
01773     where in most cases |ds|<.5 (but in general |ds|<1). So we have
01774 
01775        o = phi - s/S,   s = is + ds ,   |ds| < .5 (or |ds| < 1).
01776 
01777     Since is is in the range [smin+1,smax-2], s is in the range
01778     [smin+.5,smax-1.5] (or [smin,smax-1]), the number o is an integer
01779     in the range phi+[-smax+1.5,-smin-.5] (or
01780     phi+[-smax+1,-smin]). Thus the maximum value of o is obtained for
01781     o = floor(phi-smin-.5) (or o = floor(phi-smin)).
01782 
01783     Finally o is clamped to make sure it is contained in the feasible
01784     range.
01785 
01786     DETERMINING THE SCALE INDEXES S AND IS
01787 
01788     Given o we can derive is by writing (2) as
01789 
01790       s = is + ds = S(phi - o).
01791 
01792     We then take is = round(s) and clamp its value to be in the
01793     feasible range.
01794   */
01795 
01796   int    o, ix, iy, is ;
01797   double s, phi, xper ;
01798 
01799   phi = log2 (sigma / f->sigma0) ;
01800   o   = vl_floor_d (phi -  ((double) f->s_min + 0.5) / f->S) ;
01801   o   = VL_MIN (o, f->o_min + f->O - 1) ;
01802   o   = VL_MAX (o, f->o_min           ) ;
01803   s   = f->S * (phi - o) ;
01804 
01805   is  = (int)(s + 0.5) ;
01806   is  = VL_MIN(is, f->s_max - 2) ;
01807   is  = VL_MAX(is, f->s_min + 1) ;
01808   
01809   xper = pow (2.0, o) ;
01810   ix   = (int)(x / xper + 0.5) ;
01811   iy   = (int)(y / xper + 0.5) ;
01812   
01813   k -> o  = o ;
01814 
01815   k -> ix = ix ;
01816   k -> iy = iy ;
01817   k -> is = is ;
01818 
01819   k -> x = x ;
01820   k -> y = y ;
01821   k -> s = s ;
01822   
01823   k->sigma = sigma ;
01824   
01825   /*
01826   VL_PRINTF ("k.ix     = %d\n", ix) ;
01827   VL_PRINTF ("k.iy     = %d\n", iy) ;
01828   VL_PRINTF ("k.is     = %d\n", is) ;
01829   VL_PRINTF ("k.o      = %d\n", o ) ;
01830   VL_PRINTF ("k.s      = %g\n", s ) ;
01831   VL_PRINTF ("k.x      = %g\n", x ) ;
01832   VL_PRINTF ("k.y      = %g\n", y ) ;
01833   VL_PRINTF ("k.sigma  = %g\n", sigma) ;
01834   */
01835 }
Copyright © 2008 Andrea Vedaldi and Brian Fulkerson