vl_siftdescriptor.c
Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00009 All rights reserved.
00010 
00011 This file is part of the VLFeat library and is made available under
00012 the terms of the BSD license (see the COPYING file).
00013 */
00014 
00015 #include <mexutils.h>
00016 #include <vl/mathop.h>
00017 #include <vl/sift.h>
00018 
00019 #include <math.h>
00020 #include <assert.h>
00021 
00022 /* option codes */
00023 enum {
00024   opt_magnif,
00025   opt_float_descriptors,
00026   opt_norm_thresh,
00027   opt_verbose
00028 } ;
00029 
00030 /* options */
00031 vlmxOption  options [] = {
00032   {"Magnif",           1,   opt_magnif            },
00033   {"Verbose",          0,   opt_verbose           },
00034   {"FloatDescriptors", 0,   opt_float_descriptors },
00035   {"NormThresh",       1,   opt_norm_thresh       },
00036   {0,              0,   0                         }
00037 } ;
00038 
00052 VL_INLINE void
00053 transpose_descriptor (vl_sift_pix* dst, vl_sift_pix* src)
00054 {
00055   int const BO = 8 ;  /* number of orientation bins */
00056   int const BP = 4 ;  /* number of spatial bins     */
00057   int i, j, t ;
00058 
00059   for (j = 0 ; j < BP ; ++j) {
00060     int jp = BP - 1 - j ;
00061     for (i = 0 ; i < BP ; ++i) {
00062       int o  = BO * i + BP*BO * j  ;
00063       int op = BO * i + BP*BO * jp ;
00064       dst [op] = src[o] ;
00065       for (t = 1 ; t < BO ; ++t)
00066         dst [BO - t + op] = src [t + o] ;
00067     }
00068   }
00069 }
00070 
00075 void
00076 mexFunction(int nout, mxArray *out[],
00077             int nin, const mxArray *in[])
00078 {
00079   enum {IN_GRAD=0,IN_FRAMES,IN_END} ;
00080   enum {OUT_DESCRIPTORS} ;
00081 
00082   int                verbose = 0 ;
00083   int                opt ;
00084   int                next = IN_END ;
00085   mxArray const     *optarg ;
00086 
00087   mxArray           *grad_array ;
00088   vl_sift_pix       *grad ;
00089   int                M, N ;
00090 
00091   vl_bool            floatDescriptors = 0 ;
00092   double             magnif = -1 ;
00093   double             norm_thresh = -1 ;
00094   double            *ikeys = 0 ;
00095   int                nikeys = 0 ;
00096 
00097   int i,j ;
00098 
00099   VL_USE_MATLAB_ENV ;
00100 
00101   /* -----------------------------------------------------------------
00102    *                                               Check the arguments
00103    * -------------------------------------------------------------- */
00104 
00105   if (nin < 2) {
00106     mexErrMsgTxt("Two arguments required.") ;
00107   } else if (nout > 1) {
00108     mexErrMsgTxt("Too many output arguments.");
00109   }
00110 
00111   if (mxGetNumberOfDimensions (in[IN_GRAD])    != 3              ||
00112       mxGetClassID            (in[IN_GRAD])    != mxSINGLE_CLASS ||
00113       mxGetDimensions         (in[IN_GRAD])[0] != 2              ) {
00114     mexErrMsgTxt("GRAD must be a 2xMxN matrix of class SINGLE.") ;
00115   }
00116 
00117   if (!vlmxIsMatrix(in[IN_FRAMES], 4, -1)) {
00118     mexErrMsgTxt("FRAMES must be a 4xN matrix.") ;
00119   }
00120   nikeys = mxGetN (in[IN_FRAMES]) ;
00121   ikeys  = mxGetPr(in[IN_FRAMES]) ;
00122 
00123   while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00124     switch (opt) {
00125 
00126       case opt_verbose :
00127         ++ verbose ;
00128         break ;
00129 
00130       case opt_magnif :
00131         if (!vlmxIsPlainScalar(optarg) || (magnif = *mxGetPr(optarg)) < 0) {
00132           mexErrMsgTxt("MAGNIF must be a non-negative scalar.") ;
00133         }
00134         break ;
00135 
00136       case opt_float_descriptors :
00137         floatDescriptors = 1 ;
00138         break ;
00139 
00140       case opt_norm_thresh :
00141         if (!vlmxIsPlainScalar(optarg) || (norm_thresh = *mxGetPr(optarg)) < 0) {
00142           mexErrMsgTxt("NORMTHRESH must be a non-negative scalar.") ;
00143         }
00144         break ;
00145 
00146       default :
00147         abort() ;
00148     }
00149   }
00150 
00151   grad_array = mxDuplicateArray(in[IN_GRAD]) ;
00152   grad = (vl_sift_pix*) mxGetData (grad_array) ;
00153   M    = mxGetDimensions(in[IN_GRAD])[1] ;
00154   N    = mxGetDimensions(in[IN_GRAD])[2] ;
00155 
00156   /* transpose angles */
00157   for (i = 1 ; i < 2*M*N ; i+=2) {
00158     grad [i] = VL_PI/2 - grad [i] ;
00159   }
00160 
00161   /* -----------------------------------------------------------------
00162    *                                                            Do job
00163    * -------------------------------------------------------------- */
00164   {
00165     VlSiftFilt * filt = 0 ;
00166     void * descr = 0 ;
00167 
00168     /* create a filter to process the image */
00169     filt = vl_sift_new (M, N, -1, -1, 0) ;
00170 
00171     if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ;
00172     if (norm_thresh >= 0) vl_sift_set_norm_thresh (filt, norm_thresh) ;
00173     if (verbose) {
00174       mexPrintf("vl_siftdescriptor: filter settings:\n") ;
00175       mexPrintf("vl_siftdescriptor:   magnif                = %g\n",
00176                 vl_sift_get_magnif (filt)) ;
00177       mexPrintf("vl_siftdescriptor:   num of frames         = %d\n",
00178                 nikeys) ;
00179       mexPrintf("vl_siftdescriptor:   float descriptor      = %d\n",
00180                 floatDescriptors) ;
00181       mexPrintf("vl_siftdescriptor:   norm thresh           = %g\n",
00182                 vl_sift_get_norm_thresh (filt));
00183     }
00184 
00185     {
00186       mwSize dims [2] ;
00187       dims [0] = 128 ;
00188       dims [1] = nikeys ;
00189       out[OUT_DESCRIPTORS]= mxCreateNumericArray
00190         (2, dims,
00191          floatDescriptors ? mxSINGLE_CLASS : mxUINT8_CLASS,
00192          mxREAL) ;
00193       descr = mxGetData(out[OUT_DESCRIPTORS]) ;
00194     }
00195 
00196     /* ...............................................................
00197      *                                             Process each octave
00198      * ............................................................ */
00199     for (i = 0 ; i < nikeys ; ++i) {
00200       vl_sift_pix  buf [128], rbuf [128] ;
00201 
00202       double y  = *ikeys++ - 1 ;
00203       double x  = *ikeys++ - 1 ;
00204       double s  = *ikeys++ ;
00205       double th = VL_PI / 2 - *ikeys++ ;
00206 
00207       vl_sift_calc_raw_descriptor (filt,
00208                                    grad,
00209                                    buf,
00210                                    M, N,
00211                                    x, y, s, th) ;
00212 
00213       transpose_descriptor (rbuf, buf) ;
00214 
00215       if (! floatDescriptors) {
00216         vl_uint8 * descr_ = descr ;
00217         for (j = 0 ; j < 128 ; ++j) {
00218           float x = 512.0F * rbuf [j] ;
00219           x = (x < 255.0F) ? x : 255.0F ;
00220           *descr_++ = (vl_uint8) (x) ;
00221         }
00222         descr = descr_ ;
00223       } else {
00224         float * descr_ = descr ;
00225         for (j = 0 ; j < 128 ; ++j) {
00226           *descr_++ = 512.0F * rbuf [j] ;
00227         }
00228         descr = descr_ ;
00229       }
00230     }
00231     /* cleanup */
00232     mxDestroyArray (grad_array) ;
00233     vl_sift_delete (filt) ;
00234   } /* job done */
00235 }


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51