Esempio n. 1
0
/** @brief MEX driver entry point 
 **/
void mexFunction (int nout, mxArray * out[], int nin, const mxArray * in[])
{
  enum {IN_TREE = 0, IN_DATA, IN_END} ;
  enum {OUT_ASGN = 0} ;
  vl_uint8 const *data; 

  int             opt ;
  int             next = IN_END ;
  mxArray const  *optarg ;
  
  int N = 0 ;
  int method_type = VL_IKM_LLOYD ;
  int verb = 0 ;
  
  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */
  if (nin < 2)
    mexErrMsgTxt ("At least two arguments required.");
  else if (nout > 1)
    mexErrMsgTxt ("Too many output arguments.");
  
  if (mxGetClassID (in[IN_DATA]) != mxUINT8_CLASS) {
    mexErrMsgTxt ("DATA must be of class UINT8");
  }
  
  N = mxGetN (in[IN_DATA]);   /* n of elements */
  data = (vl_uint8 *) mxGetPr (in[IN_DATA]);
  
  while ((opt = uNextOption(in, nin, options, &next, &optarg)) >= 0) {
    char buf [1024] ;
    
    switch (opt) {
      
    case opt_verbose :
      ++ verb ;
      break ;
      
    case opt_method :
      if (!uIsString (optarg, -1)) {
        mexErrMsgTxt("'Method' must be a string.") ;        
      }
      if (mxGetString (optarg, buf, sizeof(buf))) {
        mexErrMsgTxt("Option argument too long.") ;
      }
      if (strcmp("lloyd", buf) == 0) {
        method_type = VL_IKM_LLOYD ;
      } else if (strcmp("elkan", buf) == 0) {
        method_type = VL_IKM_ELKAN ;
      } else {
        mexErrMsgTxt("Unknown cost type.") ;
      }
      
      break ;
      
    default :
      assert(0) ;
      break ;
    }
  }

  /* -----------------------------------------------------------------
   *                                                        Do the job
   * -------------------------------------------------------------- */

  {
    VlHIKMTree *tree ;
    vl_uint  *ids  ;
    int j;
    int depth ;

    tree  = matlab_to_hikm (in[IN_TREE], method_type) ;
    depth = vl_hikm_get_depth (tree) ;

    if (verb) {
      mexPrintf("hikmeanspush: ndims: %d K: %d depth: %d\n",
                vl_hikm_get_ndims (tree), 
                vl_hikm_get_K (tree),
                depth) ;
    }
    
    out[OUT_ASGN] = mxCreateNumericMatrix (depth, N, mxUINT32_CLASS, mxREAL) ;
    ids = mxGetData (out[OUT_ASGN]) ;

    vl_hikm_push   (tree, ids, data, N) ;    
    vl_hikm_delete (tree) ;
    
    for (j = 0 ; j < N*depth ; j++) ids [j] ++ ;
  }
}
void
mexFunction(int nout, mxArray *out[], 
            int nin, const mxArray *in[])
{
  enum {IN_GRAD=0,IN_FRAMES,IN_END} ;
  enum {OUT_DESCRIPTORS} ;

  int                verbose = 0 ;
  int                opt ;
  int                next = IN_END ;
  mxArray const     *optarg ;
     
  mxArray           *grad_array ;
  vl_sift_pix       *grad ;
  int                M, N ;

  double             magnif = -1 ;
  double            *ikeys = 0 ;
  int                nikeys = 0 ;

  int i,j ;
  
  VL_USE_MATLAB_ENV ;
  
  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 2) {
    mexErrMsgTxt("Two arguments required.") ;
  } else if (nout > 1) {
    mexErrMsgTxt("Too many output arguments.");
  }
  
  if (mxGetNumberOfDimensions (in[IN_GRAD])    != 3              ||
      mxGetClassID            (in[IN_GRAD])    != mxSINGLE_CLASS ||
      mxGetDimensions         (in[IN_GRAD])[0] != 2              ) {
    mexErrMsgTxt("GRAD must be a 2xMxN matrix of class SINGLE.") ;
  }

  if (!uIsRealMatrix(in[IN_FRAMES], 4, -1)) {
    mexErrMsgTxt("FRAMES must be a 4xN matrix.") ;
  }
  nikeys = mxGetN (in[IN_FRAMES]) ;
  ikeys  = mxGetPr(in[IN_FRAMES]) ;
  
  while ((opt = uNextOption(in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
        
      case opt_verbose :
        ++ verbose ;
        break ;
        
      case opt_magnif :
        if (!uIsRealScalar(optarg) || (magnif = *mxGetPr(optarg)) < 0) {
          mexErrMsgTxt("MAGNIF must be a non-negative scalar.") ;
        }
        break ;
        
      default :
        assert(0) ;
        break ;
    }
  }
  
  grad_array = mxDuplicateArray(in[IN_GRAD]) ;  
  grad = (vl_sift_pix*) mxGetData (grad_array) ;
  M    = mxGetDimensions(in[IN_GRAD])[1] ;
  N    = mxGetDimensions(in[IN_GRAD])[2] ;

  /* transpose angles */
  for (i = 1 ; i < 2*M*N ; i+=2) {
    grad [i] = VL_PI/2 - grad [i] ;
  }

  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  {
    VlSiftFilt *filt = 0 ;    
    vl_uint8   *descr = 0 ;

    /* create a filter to process the image */
    filt = vl_sift_new (M, N, -1, -1, 0) ;
    
    if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ;
    
    if (verbose) {    
      mexPrintf("siftdescriptor: filter settings:\n") ;
      mexPrintf("siftdescriptor:   magnif                = %g\n",
                vl_sift_get_magnif (filt)) ;
      mexPrintf("siftdescriptor:   num of frames         = %d\n",
                nikeys) ;
    }

    {
      mwSize dims [2] ;
      dims [0] = 128 ;
      dims [1] = nikeys ;
      out[OUT_DESCRIPTORS]= mxCreateNumericArray 
        (2, dims, mxUINT8_CLASS,  mxREAL) ;
      descr = mxGetData(out[OUT_DESCRIPTORS]) ;
    }
    
    /* ...............................................................
     *                                             Process each octave
     * ............................................................ */
    for (i = 0 ; i < nikeys ; ++i) {
      vl_sift_pix  buf [128], rbuf [128] ;

      double y  = *ikeys++ - 1 ;
      double x  = *ikeys++ - 1 ;
      double s  = *ikeys++ ;
      double th = VL_PI / 2 - *ikeys++ ;

      vl_sift_calc_raw_descriptor (filt, 
                                   grad, 
                                   buf,
                                   M, N,
                                   x, y, s, th) ;
      
      transpose_descriptor (rbuf, buf) ;
      
      for (j = 0 ; j < 128 ; ++j) {
        double x = 512.0 * rbuf [j] ;
        x = (x < 255.0) ? x : 255.0 ;
        *descr++ = (vl_uint8) (x) ;
      }
    }    
    /* cleanup */
    mxDestroyArray (grad_array) ;
    vl_sift_delete (filt) ;
  } /* job done */    
}
Esempio n. 3
0
/** @brief MEX entry point */
void
mexFunction(int nout, mxArray *out[], 
            int nin, const mxArray *in[])
{
  enum {IN_I = 0, 
        IN_END } ;
  enum {OUT_SEEDS = 0, 
        OUT_FRAMES } ;
  
  int             verbose = 0 ;
  int             opt ;
  int             next = IN_END ;
  mxArray const  *optarg ;

  /* algorithm parameters */ 
  double   delta         = -1 ;
  double   max_area      = -1 ;
  double   min_area      = -1 ;
  double   max_variation = -1 ; 
  double   min_diversity = -1 ;

  int nel ;              
  int ndims ;            
  mwSize const* dims ; 
     
  vl_mser_pix const *data ; 

  VL_USE_MATLAB_ENV ;
  
  /** -----------------------------------------------------------------
   **                                               Check the arguments
   ** -------------------------------------------------------------- */
  
  if (nin < 1) {
    mexErrMsgTxt("At least one input argument is required.") ;
  }
  
  if (nout > 2) {
    mexErrMsgTxt("Too many output arguments.");
  }
  
  if(mxGetClassID(in[IN_I]) != mxUINT8_CLASS) {
    mexErrMsgTxt("I must be of class UINT8") ;
  }

  /* get dimensions */
  nel   = mxGetNumberOfElements(in[IN_I]) ;
  ndims = mxGetNumberOfDimensions(in[IN_I]) ;
  dims  = mxGetDimensions(in[IN_I]) ;
  data  = mxGetData(in[IN_I]) ;

  while ((opt = uNextOption(in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {

    case opt_verbose :
      ++ verbose ;
      break ;

    case opt_delta :
      if (!uIsRealScalar(optarg) || (delta = *mxGetPr(optarg)) < 0) {
        mexErrMsgTxt("'Delta' must be non-negative.") ;
      }
      break ;

    case opt_max_area : 
      if (!uIsRealScalar(optarg)            || 
          (max_area = *mxGetPr(optarg)) < 0 ||
          max_area > 1) {
        mexErrMsgTxt("'MaxArea' must be in the range [0,1].") ;
      }
      break ;

    case opt_min_area : 
      if (!uIsRealScalar(optarg)            || 
          (min_area = *mxGetPr(optarg)) < 0 ||
          min_area > 1) {
        mexErrMsgTxt("'MinArea' must be in the range [0,1].") ;
      }
      break ;

    case opt_max_variation : 
      if (!uIsRealScalar(optarg)           || 
          (max_variation = *mxGetPr(optarg)) < 0) {
        mexErrMsgTxt("'MaxVariation' must be non negative.") ;
      }
      break ;

    case opt_min_diversity : 
      if (!uIsRealScalar(optarg)                 || 
          (min_diversity = *mxGetPr(optarg)) < 0 ||
           min_diversity > 1.0) {
        mexErrMsgTxt("'MinDiversity' must be in the [0,1] range.") ;
      }
      break ;
      
      
    default :
        assert(0) ;
        break ;
    }
  }

  /* -----------------------------------------------------------------
   *                                                     Run algorithm
   * -------------------------------------------------------------- */
  {
    VlMserFilt        *filt ;    
    vl_uint     const *regions ;
    float       const *frames ;    
    int                i, j, nregions, nframes, dof ;    
    mwSize             odims [2] ;
    double            *pt ;
    
    /* new filter */
    {
      int * vlDims = mxMalloc(sizeof(int) * ndims) ;
      for (i = 0 ; i < ndims ; ++i) vlDims [i] = dims [i] ;
      filt = vl_mser_new (ndims, vlDims) ;
      mxFree(vlDims) ;
    }

    if (!filt) {
      mexErrMsgTxt("Could not create an MSER filter.") ;
    }
    
    if (delta         >= 0) vl_mser_set_delta          (filt, (vl_mser_pix) delta) ;
    if (max_area      >= 0) vl_mser_set_max_area       (filt, max_area) ;
    if (min_area      >= 0) vl_mser_set_min_area       (filt, min_area) ;
    if (max_variation >= 0) vl_mser_set_max_variation  (filt, max_variation) ;
    if (min_diversity >= 0) vl_mser_set_min_diversity  (filt, min_diversity) ;

    if (verbose) {
      mexPrintf("mser: parameters:\n") ;
      mexPrintf("mser:   delta         = %d\n", vl_mser_get_delta         (filt)) ;
      mexPrintf("mser:   max_area      = %g\n", vl_mser_get_max_area      (filt)) ;
      mexPrintf("mser:   min_area      = %g\n", vl_mser_get_min_area      (filt)) ;
      mexPrintf("mser:   max_variation = %g\n", vl_mser_get_max_variation (filt)) ;
      mexPrintf("mser:   min_diversity = %g\n", vl_mser_get_min_diversity (filt)) ;
    }
    
    /* process the image */
    vl_mser_process (filt, data) ;
    
    /* save regions back to array */
    nregions         = vl_mser_get_regions_num (filt) ;
    regions          = vl_mser_get_regions     (filt) ;
    odims [0]        = nregions ;
    out [OUT_SEEDS] = mxCreateNumericArray (1, odims, mxDOUBLE_CLASS,mxREAL) ;
    pt               = mxGetPr (out [OUT_SEEDS]) ;

    for (i = 0 ; i < nregions ; ++i) 
      pt [i] = regions [i] + 1 ;

    /* optionally compute and save ellipsoids */
    if (nout > 1) {
      vl_mser_ell_fit (filt) ;
      
      nframes = vl_mser_get_ell_num (filt) ;
      dof     = vl_mser_get_ell_dof (filt) ;
      frames  = vl_mser_get_ell     (filt) ;
      
      odims [0] = dof ;
      odims [1] = nframes ;
      
      out [OUT_FRAMES] = mxCreateNumericArray (2, odims, mxDOUBLE_CLASS, mxREAL) ;
      pt               = mxGetPr (out [OUT_FRAMES]) ;
      
      for (i = 0 ; i < nframes ; ++i) {
        for (j = 0 ; j < dof ; ++j) {
          pt [i * dof + j] = frames [i * dof + j] + ((j < ndims)?1.0:0.0) ;
        }
      }
    }

    if (verbose) {
      VlMserStats const* s = vl_mser_get_stats (filt) ;
      int tot = s-> num_extremal ;

      mexPrintf("mser: statistics:\n") ;
      mexPrintf("mser: %d extremal regions of which\n", tot) ;

#define REMAIN(test,num)                                                \
      mexPrintf("mser:  %5d (%7.3g %% of previous) " test "\n",         \
                tot-(num),100.0*(double)(tot-(num))/(tot+VL_EPSILON_D)) ; \
      tot -= (num) ;
      
      REMAIN("maximally stable,", s-> num_unstable    ) ;
      REMAIN("stable enough,",    s-> num_abs_unstable) ;
      REMAIN("small enough,",     s-> num_too_big     ) ;
      REMAIN("big enough,",       s-> num_too_small   ) ;
      REMAIN("diverse enough.",    s-> num_duplicates  ) ;
      
    }

    /* cleanup */
    vl_mser_delete (filt) ;
  }
}
/* driver */
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_X=0,IN_C,IN_END} ;
  enum {OUT_ASGN=0} ;
  vl_uint*     asgn ;
  vl_ikm_acc*  centers ;
  vl_uint8* data ;

  int M,N,j,K=0 ;

  int             opt ;
  int             next = IN_END ;
  mxArray const  *optarg ;

  int method_type = VL_IKM_LLOYD ;
  int verb = 0 ;

  VlIKMFilt *ikmf ;

  VL_USE_MATLAB_ENV ;

  /** -----------------------------------------------------------------
   **                                               Check the arguments
   ** -------------------------------------------------------------- */
  
  if (nin < 2) {
    mexErrMsgTxt("At least two arguments required.") ;
  } else if (nout > 2) {
    mexErrMsgTxt("Too many output arguments.") ;
  }
  
  if(mxGetClassID(in[IN_X]) != mxUINT8_CLASS) {
    mexErrMsgTxt("X must be of class UINT8") ;
  }
  
  if(mxGetClassID(in[IN_C]) != mxINT32_CLASS) {
    mexErrMsgTxt("C must be of class INT32") ;
  }
  
  M = mxGetM(in[IN_X]) ;  /* n of components */
  N = mxGetN(in[IN_X]) ;  /* n of elements */
  K = mxGetN(in[IN_C]) ;  /* n of centers */
  
  if( mxGetM(in[IN_C]) != M ) {
    mexErrMsgTxt("DATA and CENTERS must have the same number of columns.") ;
  }
  
  while ((opt = uNextOption(in, nin, options, &next, &optarg)) >= 0) {
    char buf [1024] ;
    
    switch (opt) {
      
    case opt_verbose :
      ++ verb ;
      break ;
            
    case opt_method :
      if (!uIsString (optarg, -1)) {
        mexErrMsgTxt("'Method' must be a string.") ;        
      }
      if (mxGetString (optarg, buf, sizeof(buf))) {
        mexErrMsgTxt("Option argument too long.") ;
      }
      if (strcmp("lloyd", buf) == 0) {
        method_type = VL_IKM_LLOYD ;
      } else if (strcmp("elkan", buf) == 0) {
        method_type = VL_IKM_ELKAN ;
      } else {
        mexErrMsgTxt("Unknown cost type.") ;
      }
      
      break ;
      
    default :
      assert(0) ;
      break ;
    }
  }
  
  /** -----------------------------------------------------------------
   **                                               Check the arguments
   ** -------------------------------------------------------------- */
  
  if (verb) {
    char const * method_name = 0 ;
    switch (method_type) {
    case VL_IKM_LLOYD: method_name = "Lloyd" ; break ;
    case VL_IKM_ELKAN: method_name = "Elkan" ; break ;
    default :
      assert (0) ;
    }
    mexPrintf("ikmeanspush: Method = %s\n", method_name) ;
    mexPrintf("ikmeanspush: ndata  = %d\n", N) ;
  }

  out[OUT_ASGN] = mxCreateNumericMatrix (1, N, mxUINT32_CLASS, mxREAL) ;

  data    = (vl_uint8*) mxGetData (in[IN_X]) ;
  centers = (vl_ikm_acc*)  mxGetData (in[IN_C]) ;
  asgn    = (vl_uint*)     mxGetData (out[OUT_ASGN]) ;
  ikmf    = vl_ikm_new (method_type) ;
  
  vl_ikm_set_verbosity  (ikmf, verb) ;
  vl_ikm_init           (ikmf, centers, M, K) ;
  vl_ikm_push           (ikmf, asgn, data, N) ;
  
  /* adjust for MATLAB indexing */
  for(j = 0 ; j < N ; ++j) ++ asgn[j] ;

  vl_ikm_delete (ikmf) ;
}
Esempio n. 5
0
void
mexFunction(int nout, mxArray *out[], 
            int nin, const mxArray *in[])
{
  enum {IN_I=0,IN_END} ;
  enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ;

  int                verbose = 0 ;
  int                opt ;
  int                next = IN_END ;
  mxArray const     *optarg ;
     
  vl_sift_pix const *data ;
  int                M, N ;

  int                O     = - 1 ;
  int                S     =   3 ;
  int                o_min =   0 ; 

  double             edge_thresh = -1 ;
  double             peak_thresh = -1 ;
  double             norm_thresh = -1 ;

  mxArray           *ikeys_array = 0 ;
  double            *ikeys = 0 ;
  int                nikeys = -1 ;
  vl_bool            force_orientations = 0 ;

  VL_USE_MATLAB_ENV ;
 
  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < 1) {
    mexErrMsgTxt("One argument required.") ;
  } else if (nout > 2) {
    mexErrMsgTxt("Too many output arguments.");
  }
  
  if (mxGetNumberOfDimensions (in[IN_I]) != 2              ||
      mxGetClassID            (in[IN_I]) != mxSINGLE_CLASS  ) {
    mexErrMsgTxt("I must be a matrix of class SINGLE") ;
  }
  
  data = (vl_sift_pix*) mxGetData (in[IN_I]) ;
  M    = mxGetM (in[IN_I]) ;
  N    = mxGetN (in[IN_I]) ;
  
  while ((opt = uNextOption(in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {

    case opt_verbose :
      ++ verbose ;
      break ;

    case opt_octaves :
      if (!uIsRealScalar(optarg) || (O = (int) *mxGetPr(optarg)) < 0) {
        mexErrMsgTxt("'Octaves' must be a positive integer.") ;
      }
      break ;
      
    case opt_levels :
      if (! uIsRealScalar(optarg) || (S = (int) *mxGetPr(optarg)) < 1) {
        mexErrMsgTxt("'Levels' must be a positive integer.") ;
      }
      break ;
      
    case opt_first_octave :
      if (!uIsRealScalar(optarg)) {
        mexErrMsgTxt("'FirstOctave' must be an integer") ;
      }
      o_min = (int) *mxGetPr(optarg) ;
      break ;

    case opt_edge_thresh :
      if (!uIsRealScalar(optarg) || (edge_thresh = *mxGetPr(optarg)) < 1) {
        mexErrMsgTxt("'EdgeThresh' must be not smaller than 1.") ;
      }
      break ;

    case opt_peak_thresh :
      if (!uIsRealScalar(optarg) || (peak_thresh = *mxGetPr(optarg)) < 0) {
        mexErrMsgTxt("'PeakThresh' must be a non-negative real.") ;
      }
      break ;

    case opt_norm_thresh :
      if (!uIsRealScalar(optarg) || (norm_thresh = *mxGetPr(optarg)) < 0) {
        mexErrMsgTxt("'NormThresh' must be a non-negative real.") ;
      }
      break ;

    case opt_frames :
      if (!uIsRealMatrix(optarg, 4, -1)) {
        mexErrMsgTxt("'Frames' must be a 4 x N matrix.x") ;
      }
      ikeys_array = mxDuplicateArray (optarg) ;
      nikeys      = mxGetN (optarg) ;
      ikeys       = mxGetPr (ikeys_array) ;
      if (! check_sorted (ikeys, nikeys)) {
        qsort (ikeys, nikeys, 4 * sizeof(double), korder) ;
      }
      break ;
      
    case opt_orientations :
      force_orientations = 1 ;
      break ;
      
    default :
      assert(0) ;
      break ;
    }
  }
  
  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  {
    VlSiftFilt        *filt ;    
    vl_bool            first ;
    double            *frames = 0 ;
    vl_uint8          *descr  = 0 ;
    int                nframes = 0, reserved = 0, i,j,q ;
    
    /* create a filter to process the image */
    filt = vl_sift_new (M, N, O, S, o_min) ;

    if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ;
    if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ;
    if (norm_thresh >= 0) vl_sift_set_norm_thresh (filt, norm_thresh) ;
    
    if (verbose) {    
      mexPrintf("siftmx: filter settings:\n") ;
      mexPrintf("siftmx:   octaves      (O)     = %d\n", 
                vl_sift_get_octave_num   (filt)) ;
      mexPrintf("siftmx:   levels       (S)     = %d\n",
                vl_sift_get_level_num    (filt)) ;
      mexPrintf("siftmx:   first octave (o_min) = %d\n", 
                vl_sift_get_octave_first (filt)) ;
      mexPrintf("siftmx:   edge thresh           = %g\n",
                vl_sift_get_edge_thresh   (filt)) ;
      mexPrintf("siftmx:   peak thresh           = %g\n",
                vl_sift_get_peak_thresh   (filt)) ;
      mexPrintf("siftmx:   norm thresh           = %g\n",
                vl_sift_get_norm_thresh   (filt)) ;
      mexPrintf((nikeys >= 0) ? 
                "siftmx: will source frames? yes (%d)\n" :
                "siftmx: will source frames? no\n", nikeys) ;
      mexPrintf("siftmx: will force orientations? %s\n",
                force_orientations ? "yes" : "no") ;      
    }
    
    /* ...............................................................
     *                                             Process each octave
     * ............................................................ */
    i     = 0 ;
    first = 1 ;
    while (true) {
      int                   err ;
      VlSiftKeypoint const *keys  = 0 ;
      int                   nkeys = 0 ;
      
      if (verbose) {
        mexPrintf ("siftmx: processing octave %d\n",
                   vl_sift_get_octave_index (filt)) ;
      }

      /* Calculate the GSS for the next octave .................... */
      if (first) {
        err   = vl_sift_process_first_octave (filt, data) ;
        first = 0 ;
      } else {
        err   = vl_sift_process_next_octave  (filt) ;
      }        

      if (err) break ;
      
      if (verbose > 1) {
        printf("siftmx: GSS octave %d computed\n",
               vl_sift_get_octave_index (filt));
      }

      /* Run detector ............................................. */
      if (nikeys < 0) {
        vl_sift_detect (filt) ;
        
        keys  = vl_sift_get_keypoints     (filt) ;
        nkeys = vl_sift_get_keypoints_num (filt) ;
        i     = 0 ;
        
        if (verbose > 1) {
          printf ("siftmx: detected %d (unoriented) keypoints\n", nkeys) ;
        }
      } else {
        nkeys = nikeys ;
      }

      /* For each keypoint ........................................ */
      for (; i < nkeys ; ++i) {
        double                angles [4] ;
        int                   nangles ;
        VlSiftKeypoint        ik ;
        VlSiftKeypoint const *k ;

        /* Obtain keypoint orientations ........................... */
        if (nikeys >= 0) {
          vl_sift_keypoint_init (filt, &ik, 
                                 ikeys [4 * i + 1] - 1,
                                 ikeys [4 * i + 0] - 1,
                                 ikeys [4 * i + 2]) ;
          
          if (ik.o != vl_sift_get_octave_index (filt)) {
            break ;
          }

          k = &ik ;
          
          /* optionally compute orientations too */
          if (force_orientations) {
            nangles = vl_sift_calc_keypoint_orientations 
              (filt, angles, k) ;            
          } else {
            angles [0] = VL_PI / 2 - ikeys [4 * i + 3] ;
            nangles    = 1 ;
          }
        } else {
          k = keys + i ;
          nangles = vl_sift_calc_keypoint_orientations 
            (filt, angles, k) ;
        }

        /* For each orientation ................................... */
        for (q = 0 ; q < nangles ; ++q) {
          vl_sift_pix  buf [128] ;
          vl_sift_pix rbuf [128] ;

          /* compute descriptor (if necessary) */
          if (nout > 1) {
            vl_sift_calc_keypoint_descriptor 
              (filt, buf, k, angles [q]) ;
            transpose_descriptor (rbuf, buf) ;
          }

          /* make enough room for all these keypoints and more */
          if (reserved < nframes + 1) {
            reserved += 2 * nkeys ;
            frames = mxRealloc (frames, 4 * sizeof(double) * reserved) ;
            if (nout > 1) {
              descr  = mxRealloc (descr,  128 * sizeof(double) * reserved) ;
            }
          }

          /* Save back with MATLAB conventions. Notice tha the input
           * image was the transpose of the actual image. */
          frames [4 * nframes + 0] = k -> y + 1 ;
          frames [4 * nframes + 1] = k -> x + 1 ;
          frames [4 * nframes + 2] = k -> sigma ;
          frames [4 * nframes + 3] = VL_PI / 2 - angles [q] ;
          
          if (nout > 1) {
            for (j = 0 ; j < 128 ; ++j) {
              double x = 512.0 * rbuf [j] ;
              x = (x < 255.0) ? x : 255.0 ;
              descr [128 * nframes + j] = (vl_uint8) (x) ;
            }
          }

          ++ nframes ;
        } /* next orientation */
      } /* next keypoint */
    } /* next octave */
    
    if (verbose) {
      mexPrintf ("siftmx: found %d keypoints\n", nframes) ;
    }

    /* ...............................................................
     *                                                       Save back
     * ............................................................ */

    {
      int dims [2] ;
      
      /* create an empty array */
      dims [0] = 0 ;
      dims [1] = 0 ;      
      out[OUT_FRAMES] = mxCreateNumericArray 
        (2, dims, mxDOUBLE_CLASS, mxREAL) ;

      /* set array content to be the frames buffer */
      dims [0] = 4 ;
      dims [1] = nframes ;
      mxSetDimensions (out[OUT_FRAMES], dims, 2) ;
      mxSetPr         (out[OUT_FRAMES], frames) ;
      
      if (nout > 1) {
        
        /* create an empty array */
        dims [0] = 0 ;
        dims [1] = 0 ;
        out[OUT_DESCRIPTORS]= mxCreateNumericArray 
          (2, dims, mxUINT8_CLASS,  mxREAL) ;
        
        /* set array content to be the descriptors buffer */
        dims [0] = 128 ;
        dims [1] = nframes ;
        mxSetDimensions (out[OUT_DESCRIPTORS], dims, 2) ;
        mxSetData       (out[OUT_DESCRIPTORS], descr) ;
      }
    }
    
    /* cleanup */
    vl_sift_delete (filt) ;
    
    if (ikeys_array) 
      mxDestroyArray(ikeys_array) ;

  } /* end: do job */
}
Esempio n. 6
0
/* driver */
void
mexFunction(int nout, mxArray *out[], 
            int nin, const mxArray *in[])
{

  typedef int  unsigned data_t ; 

  /*  mxClassID data_class = mxINT8_CLASS ;*/
  enum {IN_S1,IN_S2} ;
  enum {OUT_D=0} ;
  int L,N1,N2 ;
  int sparse = 0 ;
  void const * s1_pt ;
  void const * s2_pt ;
  mxClassID data_class ;
  mxClassID acc_class ;
  mwSize dims [2] ; 
  
  /* for option parsing */
  bool           self = 1 ;      /* called with one numeric argument? */
  int            norm = opt_L2 ; /* type of norm to be computed       */
  int            opt ;
  int            next = 1 ;
  mxArray const *optarg ;

  /** -----------------------------------------------------------------
   **                                               Check the arguments
   ** -------------------------------------------------------------- */
  
  if (nout > 1) {
    mexErrMsgTxt("Too many output arguments.");
  }

  if (nin < 1) {
    mexErrMsgTxt("At leat one argument required.") ;    
  }
  
  if(! mxIsNumeric(in[IN_S1])) {
    mexErrMsgTxt ("X must be numeric") ;
  }
  
  if (nin >= 2 && mxIsNumeric(in[IN_S2])) {
    self = 0 ;
    next = 2 ;
  }

  sparse = mxIsSparse(in[IN_S1]) ;
  
  if (sparse && nin >=2 && mxIsNumeric(in[IN_S2])) {
    if (! mxIsSparse(in[IN_S2])) {
      mexErrMsgTxt ("X and Y must be either both full or sparse.") ;
    }
  }

  while ((opt = uNextOption(in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
    case opt_LINF :
    case opt_L2 :
    case opt_L1 :
    case opt_L0 :
    case opt_CHI2 :
    case opt_HELL :

    case opt_KL2 :
    case opt_KL1 :
    case opt_KCHI2 :
    case opt_KHELL :

    case opt_MIN :
      norm = opt ;
      break ;

    default: 
      assert(0) ;
    }
  }
    
  data_class = mxGetClassID(in[IN_S1]) ;
  if ((!self) && data_class != mxGetClassID(in[IN_S2])) {
    mexErrMsgTxt("X and Y must have the same numeric class") ;
  }

  assert ((! sparse) || (data_class == mxDOUBLE_CLASS)) ;
  
  L  = mxGetM(in[IN_S1]) ; 
  N1 = mxGetN(in[IN_S1]) ;
  N2 = self ?  N1 : mxGetN(in[IN_S2]) ;
  
  dims[0] = N1 ; 
  dims[1] = N2 ;
  
  if ((!self) && L != mxGetM(in[IN_S2])) {
    mexErrMsgTxt("X and Y must have the same number of rows") ;
  }
  
  s1_pt = mxGetData(in[IN_S1]) ; 
  s2_pt = self ? s1_pt : mxGetData(in[IN_S2]) ;
  
#define DISPATCH_CLASS(NORM, DC,AC)                                     \
  case mx ## DC ## _CLASS :                                             \
    acc_class = mx ## AC ## _CLASS ;                                    \
  out[OUT_D] = mxCreateNumericArray(2,dims,acc_class,mxREAL) ;          \
  dist ## NORM ## _ ## DC ## _ ## AC                                    \
    ( (AC ## _t *)mxGetData(out[OUT_D]),                                \
      (DC ## _t *)s1_pt,                                                \
      (DC ## _t *)s2_pt,                                                \
      L, N1, N2,                                                        \
      self ) ;                                                          \
  break ;

#define DISPATCH_NORM(NORM)                                             \
  case opt_ ## NORM :                                                   \
    if (sparse) {                                                       \
      out[OUT_D] = mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL) ; \
      CORE_SPARSE(NORM, VL_XCAT(F_, NORM))                              \
    } else {                                                            \
      switch (data_class) {                                             \
        DISPATCH_CLASS(NORM,  UINT8 , UINT32)                           \
          DISPATCH_CLASS(NORM,  INT8 ,  INT32)                          \
          DISPATCH_CLASS(NORM, UINT16, UINT32)                          \
          DISPATCH_CLASS(NORM,  INT16,  INT32)                          \
          DISPATCH_CLASS(NORM, UINT32, UINT32)                          \
          DISPATCH_CLASS(NORM,  INT32,  INT32)                          \
          DISPATCH_CLASS(NORM, SINGLE, SINGLE)                          \
          DISPATCH_CLASS(NORM, DOUBLE,DOUBLE)                           \
      default:                                                          \
        mexErrMsgTxt("Data class not supported!") ;                     \
      }                                                                 \
    }                                                                   \
  break ;
  
  switch (norm) {
    DISPATCH_NORM(LINF ) ;
    DISPATCH_NORM(L2   ) ;
    DISPATCH_NORM(L1   ) ;
    DISPATCH_NORM(L0   ) ;
    DISPATCH_NORM(CHI2 ) ;
    DISPATCH_NORM(HELL ) ;

    DISPATCH_NORM(KL2  ) ;
    DISPATCH_NORM(KL1  ) ;
    DISPATCH_NORM(KCHI2) ;
    DISPATCH_NORM(KHELL) ;    

    DISPATCH_NORM(MIN  ) ;
  default:
    assert(0) ;
  }
}