void SIFT_ADAPTER::set_sift_model()
    {
        clear_model_related_data();

        m_sift_model = vl_sift_new(m_org_img.cols, m_org_img.rows, getNOctaves(),
                                   getNLevels(), getOctFirst());

        vl_sift_set_edge_thresh(m_sift_model, getEdgeThrd());
        vl_sift_set_peak_thresh(m_sift_model, getPeakThrd());
        vl_sift_set_norm_thresh(m_sift_model, getNormThrd());
        vl_sift_set_magnif(m_sift_model, getMagnif());
        vl_sift_set_window_size(m_sift_model, getWindowSize());
    }
示例#2
0
/**
 * Creates a new SIFT filter.  Must be called before calling other MAR SIFT functions.
 *
 * @param width The width of the camera frame
 * @param height The height of the camera frame
 * @param number_of_octaves The number of octaves used by the SIFT filter.  
 * Increasing the scale by an octave means doubling the size of the smoothing kernel, 
 * whose effect is roughly equivalent to halving the image resolution. 
 * @param number_of_levels The number of levels used by the SIFT filter.
 * Each octave is sampled at this given number of intermediate scales 
 * Increasing this number might in principle return more refined keypoints, but in practice can make their selection unstable due to noise.
 * @param first_octave The SIFT filter will iterate from first_octave to number_of_octaves
 * 
 * @return MAR_ERROR_NONE on success, an error code on failure.
 */
MAR_PUBLIC
mar_error_code mar_sift_new(int width, int height, int number_of_octaves, int number_of_levels, int first_octave)
{
  // Create the image buffer
  sift_image_width = width;
  sift_image_height = height;
  sift_image_buffer = malloc(width * height * sizeof(float));
  if (sift_image_buffer == NULL)
  {
    return MAR_ERROR_MALLOC;
  }

  // Create SIFT filter
  sift_filter = vl_sift_new(width, height, number_of_octaves, number_of_levels, first_octave);

  // Create the SIFT keypoint buffer
  sift_keypoints = malloc(sizeof(mar_sift_keypoint) * MAR_SIFT_DEFAULT_NUMBER_OF_KEYPOINTS);
  if (sift_keypoints == NULL)
  {
    return MAR_ERROR_MALLOC;
  }

  return MAR_ERROR_NONE;
}
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 ;

  vl_bool            floatDescriptors = 0 ;
  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 (!vlmxIsMatrix(in[IN_FRAMES], 4, -1)) {
    mexErrMsgTxt("FRAMES must be a 4xN matrix.") ;
  }
  nikeys = mxGetN (in[IN_FRAMES]) ;
  ikeys  = mxGetPr(in[IN_FRAMES]) ;

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

      case opt_verbose :
        ++ verbose ;
        break ;

      case opt_magnif :
        if (!vlmxIsPlainScalar(optarg) || (magnif = *mxGetPr(optarg)) < 0) {
          mexErrMsgTxt("MAGNIF must be a non-negative scalar.") ;
        }
        break ;

      case opt_float_descriptors :
        floatDescriptors = 1 ;
        break ;

      default :
        abort() ;
    }
  }

  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 ;
    void * 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("vl_siftdescriptor: filter settings:\n") ;
      mexPrintf("vl_siftdescriptor:   magnif                = %g\n",
                vl_sift_get_magnif (filt)) ;
      mexPrintf("vl_siftdescriptor:   num of frames         = %d\n",
                nikeys) ;
      mexPrintf("vl_siftdescriptor:   float descriptor      = %d\n",
                floatDescriptors) ;
    }

    {
      mwSize dims [2] ;
      dims [0] = 128 ;
      dims [1] = nikeys ;
      out[OUT_DESCRIPTORS]= mxCreateNumericArray
        (2, dims,
         floatDescriptors ? mxSINGLE_CLASS : 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) ;

      if (! floatDescriptors) {
        vl_uint8 * descr_ = descr ;
        for (j = 0 ; j < 128 ; ++j) {
          float x = 512.0F * rbuf [j] ;
          x = (x < 255.0F) ? x : 255.0F ;
          *descr_++ = (vl_uint8) (x) ;
        }
        descr = descr_ ;
      } else {
        float * descr_ = descr ;
        for (j = 0 ; j < 128 ; ++j) {
          *descr_++ = 512.0F * rbuf [j] ;
        }
        descr = descr_ ;
      }
    }
    /* cleanup */
    mxDestroyArray (grad_array) ;
    vl_sift_delete (filt) ;
  } /* job done */
}
示例#4
0
文件: vl_sift.c 项目: 0x27/encuadro
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 ;
  double             magnif      = -1 ;
  double             window_size = -1 ;

  mxArray           *ikeys_array = 0 ;
  double            *ikeys = 0 ;
  int                nikeys = -1 ;
  vl_bool            force_orientations = 0 ;
  vl_bool            floatDescriptors = 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 = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {

    case opt_verbose :
      ++ verbose ;
      break ;

    case opt_octaves :
      if (!vlmxIsPlainScalar(optarg) || (O = (int) *mxGetPr(optarg)) < 0) {
        mexErrMsgTxt("'Octaves' must be a positive integer.") ;
      }
      break ;

    case opt_levels :
      if (! vlmxIsPlainScalar(optarg) || (S = (int) *mxGetPr(optarg)) < 1) {
        mexErrMsgTxt("'Levels' must be a positive integer.") ;
      }
      break ;

    case opt_first_octave :
      if (!vlmxIsPlainScalar(optarg)) {
        mexErrMsgTxt("'FirstOctave' must be an integer") ;
      }
      o_min = (int) *mxGetPr(optarg) ;
      break ;

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

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

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

    case opt_magnif :
      if (!vlmxIsPlainScalar(optarg) || (magnif = *mxGetPr(optarg)) < 0) {
        mexErrMsgTxt("'Magnif' must be a non-negative real.") ;
      }
      break ;

    case opt_window_size :
      if (!vlmxIsPlainScalar(optarg) || (window_size = *mxGetPr(optarg)) < 0) {
        mexErrMsgTxt("'WindowSize' must be a non-negative real.") ;
      }
      break ;

    case opt_frames :
      if (!vlmxIsMatrix(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 ;

    case opt_float_descriptors :
      floatDescriptors = 1 ;
      break ;

    default :
      abort() ;
    }
  }

  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  {
    VlSiftFilt        *filt ;
    vl_bool            first ;
    double            *frames = 0 ;
    void              *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 (magnif      >= 0) vl_sift_set_magnif      (filt, magnif) ;
    if (window_size >= 0) vl_sift_set_window_size (filt, window_size) ;

    if (verbose) {
      mexPrintf("vl_sift: filter settings:\n") ;
      mexPrintf("vl_sift:   octaves      (O)      = %d\n",
                vl_sift_get_noctaves      (filt)) ;
      mexPrintf("vl_sift:   levels       (S)      = %d\n",
                vl_sift_get_nlevels       (filt)) ;
      mexPrintf("vl_sift:   first octave (o_min)  = %d\n",
                vl_sift_get_octave_first  (filt)) ;
      mexPrintf("vl_sift:   edge thresh           = %g\n",
                vl_sift_get_edge_thresh   (filt)) ;
      mexPrintf("vl_sift:   peak thresh           = %g\n",
                vl_sift_get_peak_thresh   (filt)) ;
      mexPrintf("vl_sift:   norm thresh           = %g\n",
                vl_sift_get_norm_thresh   (filt)) ;
      mexPrintf("vl_sift:   window size           = %g\n",
                vl_sift_get_window_size   (filt)) ;
      mexPrintf("vl_sift:   float descriptor      = %d\n",
                floatDescriptors) ;

      mexPrintf((nikeys >= 0) ?
                "vl_sift: will source frames? yes (%d read)\n" :
                "vl_sift: will source frames? no\n", nikeys) ;
      mexPrintf("vl_sift: will force orientations? %s\n",
                force_orientations ? "yes" : "no") ;
    }

    /* ...............................................................
     *                                             Process each octave
     * ............................................................ */
    i     = 0 ;
    first = 1 ;
    while (1) {
      int                   err ;
      VlSiftKeypoint const* keys  = 0 ;
      int                   nkeys = 0 ;

      if (verbose) {
        mexPrintf ("vl_sift: 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) {
        mexPrintf("vl_sift: 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_nkeypoints (filt) ;
        i     = 0 ;

        if (verbose > 1) {
          printf ("vl_sift: 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) {
              if (! floatDescriptors) {
                descr  = mxRealloc (descr,  128 * sizeof(vl_uint8) * reserved) ;
              } else {
                descr  = mxRealloc (descr,  128 * sizeof(float) * 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) {
            if (! floatDescriptors) {
              for (j = 0 ; j < 128 ; ++j) {
                float x = 512.0F * rbuf [j] ;
                x = (x < 255.0F) ? x : 255.0F ;
                ((vl_uint8*)descr) [128 * nframes + j] = (vl_uint8) x ;
              }
            } else {
              for (j = 0 ; j < 128 ; ++j) {
                float x = 512.0F * rbuf [j] ;
                ((float*)descr) [128 * nframes + j] = x ;
              }
            }
          }

          ++ nframes ;
        } /* next orientation */
      } /* next keypoint */
    } /* next octave */

    if (verbose) {
      mexPrintf ("vl_sift: found %d keypoints\n", nframes) ;
    }

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

    {
      mwSize 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 ;
      mxSetPr         (out[OUT_FRAMES], frames) ;
      mxSetDimensions (out[OUT_FRAMES], dims, 2) ;

      if (nout > 1) {

        /* create an empty array */
        dims [0] = 0 ;
        dims [1] = 0 ;
        out[OUT_DESCRIPTORS]= mxCreateNumericArray
          (2, dims,
           floatDescriptors ? mxSINGLE_CLASS : mxUINT8_CLASS,
           mxREAL) ;

        /* set array content to be the descriptors buffer */
        dims [0] = 128 ;
        dims [1] = nframes ;
        mxSetData       (out[OUT_DESCRIPTORS], descr) ;
        mxSetDimensions (out[OUT_DESCRIPTORS], dims, 2) ;
      }
    }

    /* cleanup */
    vl_sift_delete (filt) ;

    if (ikeys_array)
      mxDestroyArray(ikeys_array) ;

  } /* end: do job */
}
示例#5
0
static bool SIFTDetector(const Image<unsigned char>& I,
  std::vector<SIOPointFeature>& feats,
  std::vector<Descriptor<type,128> >& descs,
  bool bDezoom = false,
  bool bRootSift = false,
  float dPeakThreshold = 0.04f)
{
  // First Octave Index.
  int firstOctave = (bDezoom == true) ? -1 : 0;
  // Number of octaves.
  int numOctaves = 6;
  // Number of scales per octave.
  int numScales = 3;
  // Max ratio of Hessian eigenvalues.
  float edgeThresh = 10.0f;
  // Min contrast.
  float peakThresh = dPeakThreshold;

  int w=I.Width(), h=I.Height();
  //Convert to float
  Image<float> If( I.GetMat().cast<float>() );


  vl_constructor();

  VlSiftFilt *filt = vl_sift_new(w,h,numOctaves,numScales,firstOctave);
  if (edgeThresh >= 0)
    vl_sift_set_edge_thresh(filt, edgeThresh);
  if (peakThresh >= 0)
    vl_sift_set_peak_thresh(filt, 255*peakThresh/numScales);

  vl_sift_process_first_octave(filt, If.data());

  vl_sift_pix descr[128];
  Descriptor<type, 128> descriptor;

  while (true) {
    vl_sift_detect(filt);

    VlSiftKeypoint const *keys  = vl_sift_get_keypoints(filt);
    int nkeys = vl_sift_get_nkeypoints(filt);

    for (int i=0;i<nkeys;++i) {
      double angles [4];
      int	nangles=vl_sift_calc_keypoint_orientations(filt,angles,keys+i);

      for (int q=0 ; q < nangles ; ++q) {
        vl_sift_calc_keypoint_descriptor(filt,descr, keys+i, angles [q]);
        SIOPointFeature fp;
        fp.x() = keys[i].x;
        fp.y() = keys[i].y;
        fp.scale() = keys[i].sigma;
        fp.orientation() = static_cast<float>(angles[q]);

        siftDescToFloat(descr, descriptor, bRootSift);
        descs.push_back(descriptor);
        feats.push_back(fp);
      }
    }
    if (vl_sift_process_next_octave(filt))
      break; // Last octave
  }
  vl_sift_delete(filt);

  vl_destructor();

  return true;
}
示例#6
0
/** @brief SIFT driver entry point
 **/
int Sift::Detect()
{
  /* algorithm parameters */
  double   edge_thresh  = -1 ;
  double   peak_thresh  = -1 ;
  double   magnif       = -1 ;
  int      O = -1, S = 3, omin = -1 ;

  vl_bool  err    = VL_ERR_OK ;
  vl_bool  force_orientations = 0 ;


  VlSiftFilt      *filt = 0 ;
  vl_size          q ;
  int              i ;
  vl_bool          first ;

  TimeMeasureBase& measure = *TimeMeasureBase::getInstance();

  measure.startTimer("Sift::Detect()");

#define WERR(name,op)                                           \
  if (err == VL_ERR_OVERFLOW) {                               \
    snprintf(err_msg, sizeof(err_msg),                        \
             "Output file name too long.") ;                  \
    goto done ;                                               \
  } else if (err) {                                           \
    snprintf(err_msg, sizeof(err_msg),                        \
             "Could not open '%s' for " #op, name) ;          \
    goto done ;                                               \
  }


  /* ...............................................................
   *                                                     Make filter
   * ............................................................ */


  filt = vl_sift_new (pim.width, pim.height, O, S, omin) ;
  Logger::debug(Logger::SIFT, "new filter(vl_sift_new) created:%x", filt) ;

  if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ;
  if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ;
  if (magnif      >= 0) vl_sift_set_magnif      (filt, magnif) ;

  if (!filt)
  {
    Logger::error(Logger::SIFT, "Detect: could not create SIFT-fiter.");
    throw SiftException("could not create SIFT-fiter.");
  }

  Logger::debug(Logger::SIFT, "sift: filter settings:") ;
  Logger::debug(Logger::SIFT, "sift:   octaves      (O)     = %d",
          vl_sift_get_noctaves     (filt)) ;
  Logger::debug(Logger::SIFT, "sift:   levels       (S)     = %d",
          vl_sift_get_nlevels      (filt)) ;
  Logger::debug(Logger::SIFT, "sift:   first octave (o_min) = %d",
          vl_sift_get_octave_first (filt)) ;
  Logger::debug(Logger::SIFT, "sift:   edge thresh           = %g",
          vl_sift_get_edge_thresh  (filt)) ;
  Logger::debug(Logger::SIFT, "sift:   peak thresh           = %g",
          vl_sift_get_peak_thresh  (filt)) ;
  Logger::debug(Logger::SIFT, "sift:   magnif                = %g",
          vl_sift_get_magnif       (filt)) ;
  Logger::debug(Logger::SIFT, "sift: will force orientations? %s",
          force_orientations ? "yes" : "no") ;

  /* ...............................................................
   *                                             Process each octave
   * ............................................................ */
  i     = 0 ;
  first = 1 ;
  while (1)
  {
    VlSiftKeypoint const *keys = 0 ;
    int                   nkeys ;

    Logger::debug(Logger::SIFT, "sift: computing octave");

    /* calculate the GSS for the next octave .................... */
    measure.startTimer("process_octave");
    if (first)
    {
      measure.startTimer("process_f_octave");
      first = 0 ;
      err = vl_sift_process_first_octave(filt, fdata) ;
      measure.stopTimer("process_f_octave");
    }
    else
    {
      measure.startTimer("process_n_octave");
      err = vl_sift_process_next_octave(filt);
      measure.stopTimer("process_n_octave");
    }
    measure.stopTimer("process_octave");

    if (err)
    {
      err = VL_ERR_OK ;
      break ;
    }

    Logger::debug(Logger::SIFT, "sift: GSS octave %d computed",
             vl_sift_get_octave_index (filt));


    /* run detector ............................................. */
    measure.startTimer("sift_detect");
    vl_sift_detect (filt) ;
    measure.stopTimer("sift_detect");

    keys  = vl_sift_get_keypoints(filt) ;
    nkeys = vl_sift_get_nkeypoints(filt) ;
    i     = 0 ;

    Logger::debug(Logger::SIFT, "sift: detected %d (unoriented) keypoints", nkeys) ;



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

      /* obtain keypoint orientations ........................... */
      k = keys + i ;
      nangles = vl_sift_calc_keypoint_orientations
        (filt, angles, k) ;

      /* for each orientation ................................... */
      for (q = 0 ; q < (unsigned) nangles ; ++q)
      {
        KeyPointDescriptor newKeyPoint;

        /* compute descriptor (if necessary) */
        //if (out.active || dsc.active) {
        vl_sift_calc_keypoint_descriptor(filt, newKeyPoint.descr, k, angles [q]) ;
        //}

        newKeyPoint.keypoint = *k;
        newKeyPoint.angle = angles[q];

        detected_keypoints.push_back(newKeyPoint);
      }

      measure.stopTimer("per_kpoint");
    }
  }

  /* ...............................................................
   *                                                       Finish up
   * ............................................................ */


  /* release filter */
  if (filt)
  {
    Logger::debug(Logger::SIFT, "freeing filt: %x", filt);
    vl_sift_delete (filt) ;
    filt = 0 ;
  }


  measure.stopTimer("Sift::Detect()");

  measure.printStatistic();

  /* quit */
  return 0;
}
bool VlSIFTFeature::vl_keypoint_extractor(const vil_image_view<vxl_byte> & image,
                                          const vl_feat_sift_parameter &param,
                                          vcl_vector<bapl_keypoint_sptr> & keypoints,
                                          bool verbose)
{
    vil_image_view<vxl_byte> grey;
    if (image.nplanes() == 1) {
        grey.deep_copy(image);
    }
    else
    {
        vil_convert_planes_to_grey(image, grey);
    }
    
    int width  = grey.ni();
    int height = grey.nj();
    int noctaves = param.noctaves; // maximum octatve possible
    int nlevels = 3;
    int o_min = 0;   //first octave index
    
    // create a filter to process the image
    VlSiftFilt *filt = vl_sift_new (width, height, noctaves, nlevels, o_min) ;
    
    double   edge_thresh  = param.edge_thresh;
    double   peak_thresh  = param.peak_thresh;
    double   magnif       = param.magnif ;
    double   norm_thresh  = param.norm_thresh;
    double   window_size  = param.window_size;
    
    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 (magnif      >= 0) vl_sift_set_magnif      (filt, magnif) ;
    if (window_size >= 0) vl_sift_set_window_size (filt, window_size) ;
    
    // data from image
    vl_sift_pix *fdata = (vl_sift_pix *)malloc(width * height * sizeof (vl_sift_pix));
    for (int y = 0; y<grey.nj(); y++) {
        for (int x = 0; x<grey.ni(); x++) {
            int idx = y * width + x;
            fdata[idx] = grey(x, y, 0);
        }
    }
    
    
    //                                             Process each octave
    
    bool isFirst = true ;
    vl_bool err = VL_ERR_OK;
    
    int nangles = 0;
    double angles[4];
    vnl_vector_fixed<float, 128>  descriptor;
    while (1) {
        if (isFirst) {
            isFirst = false;
            err = vl_sift_process_first_octave (filt, fdata) ;
        } else {
            err = vl_sift_process_next_octave  (filt) ;
        }
        if(err == VL_ERR_EOF)
        {
            break;
        }
        
        vl_sift_detect (filt);
        
        VlSiftKeypoint const * keys  = vl_sift_get_keypoints(filt) ;
        int nkeys = vl_sift_get_nkeypoints (filt) ;
        
        for (int i = 0; i<nkeys; i++) {
            VlSiftKeypoint const * curKey = keys + i;
            
            // Depending on the symmetry of the keypoint appearance, determining the orientation can be ambiguous. SIFT detectors have up to four possible orientations
            nangles = vl_sift_calc_keypoint_orientations(filt, angles, curKey) ;
            
            for (int q = 0 ; q < nangles ; q++) {
                vl_sift_calc_keypoint_descriptor(filt, &descriptor[0], curKey, angles[q]);
                
                bapl_lowe_keypoint *pKeypoint = new bapl_lowe_keypoint();
                double x = curKey->x;
                double y = curKey->y;
                double s = curKey->sigma;
                double o = angles[q];
                vnl_vector_fixed<double, 128> des;
                for (int j = 0; j<128; j++) {
                    des[j] = descriptor[j];
                }
                
                pKeypoint->set_location_i(x);
                pKeypoint->set_location_j(y);
                pKeypoint->set_scale(s);
                pKeypoint->set_orientation(o);
                pKeypoint->set_descriptor(des);
                
                keypoints.push_back(bapl_keypoint_sptr(pKeypoint));
            }
        }
    }
    
    vl_sift_delete(filt);
    delete fdata;
    
    if(verbose){
        vcl_cout<<"Found "<<keypoints.size()<<" keypoints."<<vcl_endl;
    }
    
    return true;
}
示例#8
0
    void Sift::extract(Image &image, std::vector<Feature> *list) {
        float *fdata = new float[image.cv->width * image.cv->height];
        BOOST_VERIFY(fdata);
        {
            float *d = fdata;
            unsigned char *l = (unsigned char *)image.cv->imageData;
            for (int h = 0; h < image.cv->height; ++h) {
                for (int w = 0; w < image.cv->width; ++w) {
                    *d = float(l[w]);
                    d++;
                }
                l += image.cv->widthStep;
            }
        }

        VlSiftFilt *filt = vl_sift_new (image.cv->width, image.cv->height, O, S, omin) ;

        BOOST_VERIFY(filt);
        if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ;
        if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ;
        if (magnif      >= 0) vl_sift_set_magnif      (filt, magnif) ;

        magnif = vl_sift_get_magnif(filt);

        list->clear();

        int err = vl_sift_process_first_octave (filt, fdata);
        while (err == 0) {
          
            vl_sift_detect (filt) ;
            
            VlSiftKeypoint const *keys  = vl_sift_get_keypoints(filt) ;
            int nkeys = vl_sift_get_nkeypoints(filt) ;

            for (int i = 0; i < nkeys ; ++i) {
                VlSiftKeypoint const *key = keys + i;
                double                angles [4] ;

                int nangles = 0;
                if (do_angle) {
                    nangles = vl_sift_calc_keypoint_orientations(filt, angles, key) ;
                }
                else {
                    nangles = 1;
                    angles[0] = 0;
                }

                for (int q = 0 ; q < nangles ; ++q) {

                    list->push_back(Feature());
                    Feature &f = list->back();
                    f.desc.resize(DIM);
                  /* compute descriptor (if necessary) */
                    vl_sift_calc_keypoint_descriptor(filt, &f.desc[0], key, angles[q]) ;

                    BOOST_FOREACH(float &v, f.desc) {
                        /*
                        v = round(v * SIFT_RANGE);
                        if (v > SIFT_RANGE) v = SIFT_RANGE;
                        */
                        v *= 2;
                        if (v > 1.0) v = 1.0;
                    }

                    f.scale = image.getScale();
                    f.x = key->x;
                    f.y = key->y;
                    f.dir = angles[q] / M_PI / 2;
                    f.size = key->sigma * magnif;

                    if ((entropy(f.desc) < e_th) || !checkBlackList(f.desc)) {
                        list->pop_back();
                    }
                   
                }
            }
            err = vl_sift_process_next_octave  (filt) ;
        }
        vl_sift_delete (filt) ;
        delete [] fdata;
    }
示例#9
0
int main (int argc, const char * argv[]) {
    int w=1280,h=720;
    int i=0;
    int nkeypoints=0;
    int press=0;
    char img2_file[] = "/Users/quake0day/ana2/MVI_0124_QT 768Kbps_012.mov";
    vl_bool render=1;
    vl_bool first=1;
    VlSiftFilt * myFilter=0;
    VlSiftKeypoint const* keys;
    //CvCapture * camera = cvCreateCameraCapture (CV_CAP_ANY);
    CvCapture * camera = cvCreateFileCapture(img2_file);
    vl_sift_pix *descriptorsA, *descriptorsB;
    int ndescA=0, ndescB=0;

    //DescriptorA file
    int dscfd;
    struct stat filestat;
    dscfd = open("/Users/quake0day/ana2/saveC.jpg.dsc", O_RDONLY, 0644);
    fstat(dscfd, &filestat);
    int filesize=filestat.st_size;
    descriptorsA=(vl_sift_pix*)mmap(0, filesize, PROT_READ, MAP_SHARED, dscfd, 0);
    ndescA=(filesize/sizeof(vl_sift_pix))/DESCSIZE;
    printf("number of descriptors: %d\n", ndescA);

    //Build kdtreeA
    VlKDForest *myforest=vl_kdforest_new(VL_TYPE_FLOAT, DESCSIZE, 1);
    vl_kdforest_build(myforest, ndescA, descriptorsA);

    //DescriptorsB file
    dscfd=open("/Users/quake0day/ana2/saveD.jpg.dsc", O_RDONLY, 0644);
    fstat(dscfd, &filestat);
    filesize=filestat.st_size;
    descriptorsB=(vl_sift_pix*)mmap(0, filesize, PROT_READ, MAP_SHARED, dscfd, 0);
    ndescB=(filesize/sizeof(vl_sift_pix))/DESCSIZE;
    printf("number of descriptors: %d\n", ndescB);

    //Build kdtreeB
    VlKDForest *myforestB=vl_kdforest_new(VL_TYPE_FLOAT, DESCSIZE, 1);
    vl_kdforest_build(myforestB, ndescB, descriptorsB);

    //Neighbors
    VlKDForestNeighbor *neighbors=(VlKDForestNeighbor*)malloc(sizeof(VlKDForestNeighbor));
    VlKDForestNeighbor *neighborsB=(VlKDForestNeighbor*)malloc(sizeof(VlKDForestNeighbor));

    //Image variables
    vl_sift_pix* fim;
    int err=0;
    int octave, nlevels, o_min;
    cvNamedWindow("Hello", 1);

    //For text
    CvFont font;
    double hScale=2;
    double vScale=2;
    int    lineWidth=2;
    cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth, 1);

    IplImage *myCVImage=cvQueryFrame(camera);//cvLoadImage("2.jpg", -1);

    IplImage *afterCVImage=cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
    IplImage *resizingImg=cvCreateImage(cvSize(w, h), myCVImage->depth, myCVImage->nChannels);
    octave=2;
    nlevels=5;
    o_min=1;
    myFilter=vl_sift_new(w, h, octave, nlevels, o_min);
    vl_sift_set_peak_thresh(myFilter, 0.5);
    fim=malloc(sizeof(vl_sift_pix)*w*h);
    float thre;


    while (myCVImage) {
        dprintf("%d*%d\n",myCVImage->width,myCVImage->height);

        cvResize(myCVImage, resizingImg, CV_INTER_AREA);
        dprintf("resized scale:%d*%d\n",myCVImage->width,myCVImage->height);
        if (press=='s') {
            cvSaveImage("save.jpg", resizingImg);
        }
        cvConvertImage(resizingImg, afterCVImage, 0);


        for (i=0; i<h; i++) {
            for (int j=0; j<w; j++) {
                fim[i*w+j]=CV_IMAGE_ELEM(afterCVImage,uchar,i,j);
            }
        }

        //vl_sift_set_peak_thresh(myFilter, 0.5);
        //vl_sift_set_edge_thresh(myFilter, 10.0);
        first=1;
        while (1) {
            printf("~~~~~~~~~~start of octave~~~~~~~~~~~~\n");


            if (first) {
                first=0;
                thre=0.25;
                err=vl_sift_process_first_octave(myFilter, fim);
            }
            else {
                thre=0.05;
                err=vl_sift_process_next_octave(myFilter);
            }
            if (err) {
                err=VL_ERR_OK;
                break;
            }

            printf("Octave: %d\n", vl_sift_get_octave_index(myFilter));
            vl_sift_detect(myFilter);
            nkeypoints=vl_sift_get_nkeypoints(myFilter);
            dprintf("insider numkey:%d\n",nkeypoints);
            keys=vl_sift_get_keypoints(myFilter);
            dprintf("final numkey:%d\n",nkeypoints);

            int countA=0, countB=0;
            int matchcountA=0, matchcountB=0;
            float avgA=0, avgB=0;
            if (render) {
                for (i=0; i<nkeypoints; i++) {
                    //cvCircle(resizingImg, cvPoint(keys->x, keys->y), keys->sigma, cvScalar(100, 255, 50, 0), 1, CV_AA, 0);
                    dprintf("x:%f,y:%f,s:%f,sigma:%f,\n",keys->x,keys->y,keys->s,keys->sigma);

                    double angles [4] ;
                    int nangles ;


                    /* obtain keypoint orientations ........................... */
                    nangles=vl_sift_calc_keypoint_orientations(myFilter, angles, keys);

                    /* for each orientation ................................... */
                    for (int q = 0 ; q < (unsigned) 1 ; ++q)
                    {
                        vl_sift_pix descr [128] ;


                        /* compute descriptor (if necessary) */
                        vl_sift_calc_keypoint_descriptor(myFilter, descr, keys, angles[q]);

                        for (int j=0; j<128; j++)
                        {
                            descr[j]*=512.0;
                            descr[j]=(descr[j]<255.0)?descr[j]:255.0;
                        }

                        vl_kdforest_query(myforest, neighbors, 1, descr);
                        vl_kdforest_query(myforestB, neighborsB, 1, descr);
                        if (neighbors->distance<50000.0)
                        {
                            matchcountA++;
                            cvCircle(resizingImg, cvPoint(keys->x, keys->y), keys->sigma, cvScalar(100, 0, 0, 255), 1, CV_AA, 0);

                        }

                        if (neighborsB->distance<50000.0)
                        {
                            matchcountB++;
                            cvCircle(resizingImg, cvPoint(keys->x, keys->y), keys->sigma, cvScalar(0, 50, 255, 100), 1, CV_AA, 0);

                        }

                        countA++;
                        avgA+=neighbors->distance;
                        countB++;
                        avgB+=neighborsB->distance;

                    }
                    keys++;
                }
            }
            avgA=avgA/countA;
            float percentage=((float)matchcountA*2)/ndescA;
            printf("Percentage:%f\n", percentage);
            printf("avg:%f\n",avgA);
            printf("thre==%f\n", thre);
            if (percentage>=thre) {
                printf("A shows!!!\n");
                cvPutText (resizingImg, "A shows!!",cvPoint(50, 100), &font, cvScalar(0,255,255,0));

            }

            avgB=avgB/countB;
            percentage=((float)matchcountB*2.5)/ndescB;
            printf("Percentage:%f\n", percentage);
            printf("avg:%f\n",avgB);
            printf("thre==%f\n", thre);
            if (percentage>=thre) {
                printf("B shows!!!\n");
                cvPutText (resizingImg, "B shows!!",cvPoint(400, 100), &font, cvScalar(0,255,255,0));

            }
            printf("~~~~~~~~~~~end of octave~~~~~~~~~~~~\n");
        }

        cvShowImage("Hello", resizingImg);

        myCVImage = cvQueryFrame(camera);

        press=cvWaitKey(1);
        if( press=='q' )
            break;
        else if( press=='r' )
            render=1-render;
    }
    free(fim);
    free(neighbors);
    free(neighborsB);
    cvReleaseImage(&afterCVImage);
    cvReleaseImage(&resizingImg);
    cvReleaseImage(&myCVImage);

    return 0;
}
示例#10
0
void sift_keypoints_and_descriptors(
    float *pixels,
    int width,
    int height,
    int max_descriptors,
    int* nkeypoints, //output
    int** keypoints, //output
    int* ndescriptors, //output
    float** descriptors) //output
{
    unsigned int seed = time(NULL);

    *keypoints = (int*) malloc(KEYPOINT_SPACE_SIZE * 2 * sizeof(int));
    *descriptors = (float*) malloc(KEYPOINT_SPACE_SIZE * KEYPOINT_DESCRIPTOR_SIZE * sizeof(float));

    //printf("width=%d height=%d\n", width, height);

    //init the sift filter object
    VlSiftFilt *filter = vl_sift_new(
        width,//image width
        height,//image height
        -1,//number of octaves (-1 means all octaves)
        3,//number of levels per octave
        0);//startoctave (first is 0)

    vl_sift_set_edge_thresh(filter, 10.0); //default: 10.0
    vl_sift_set_peak_thresh(filter, 0.0); //default: 0.0
    //printf("a\n");
    //we start with the first octave first octave (highest image resolution)
    vl_sift_process_first_octave(filter, pixels);

    int keypoint_count = 0;
    int descriptor_count = 0;
    do
    {
        //detect the keypoints of the image
        vl_sift_detect(filter);

        //and get them
        const VlSiftKeypoint* vlkeypoints = vl_sift_get_keypoints(filter);

        //iterate them
        int i;
        for(i=0; i<filter->nkeys; i++)
        {
            //save keypoint coordinates
            (*keypoints)[2*keypoint_count] = (int) vlkeypoints[i].x;
            (*keypoints)[2*keypoint_count+1] = (int) vlkeypoints[i].y;

            //calculate keypoint orientations
            double angles[4]; 
            int norients = vl_sift_calc_keypoint_orientations(
                filter, angles, vlkeypoints+i);

            //iterate orientations
            int j;
            for(j=0; j<norients; j++)
            {
                //calculate the descriptor
                vl_sift_calc_keypoint_descriptor(
                    filter,
                    (*descriptors)+KEYPOINT_DESCRIPTOR_SIZE*descriptor_count,
                    vlkeypoints+i,
                    angles[j]);

                descriptor_count++;
            }

            keypoint_count++; 
        }
    } 
    //iterate over the rest of the octaves
    while(vl_sift_process_next_octave(filter) != VL_ERR_EOF);
    //printf("b\n");
    //delete the filter object from memory
    vl_sift_delete(filter);
    //printf("c\n");
    *keypoints = (int*) realloc(*keypoints, keypoint_count * 2 * sizeof(int));
    *descriptors = (float*) realloc(*descriptors, descriptor_count * KEYPOINT_DESCRIPTOR_SIZE * sizeof(float));

    //shuffle the keypoints and descriptors
    int i;
    for(i=0; i<descriptor_count; i++)
    {
        int r = rand_r(&seed) % descriptor_count;
        int j;
        for(j=0; j<KEYPOINT_DESCRIPTOR_SIZE; j++)
        {
            float tmp;
            tmp = (*descriptors)[i*KEYPOINT_DESCRIPTOR_SIZE+j];
            (*descriptors)[i*KEYPOINT_DESCRIPTOR_SIZE+j] = (*descriptors)[r*KEYPOINT_DESCRIPTOR_SIZE+j];
            (*descriptors)[r*KEYPOINT_DESCRIPTOR_SIZE+j] = tmp;
        }
    }
    //printf("descriptor_count=%d\n", descriptor_count);
    *ndescriptors = (descriptor_count < max_descriptors) ? descriptor_count : max_descriptors;
    *descriptors = (float*) realloc(*descriptors, (*ndescriptors) * KEYPOINT_DESCRIPTOR_SIZE * sizeof(float));

    *nkeypoints = keypoint_count;
}
示例#11
0
    /**
    @brief Detect regions on the image and compute their attributes (description)
    @param image Image.
    @param regions The detected regions and attributes (the caller must delete the allocated data)
    @param mask 8-bit gray image for keypoint filtering (optional).
       Non-zero values depict the region of interest.
    */
    bool Describe(const image::Image<unsigned char>& image,
                  std::unique_ptr<Regions> &regions,
                  const image::Image<unsigned char> * mask = NULL)
    {
        const int w = image.Width(), h = image.Height();
        //Convert to float
        const image::Image<float> If(image.GetMat().cast<float>());

        VlSiftFilt *filt = vl_sift_new(w, h,
                                       _params._num_octaves, _params._num_scales, _params._first_octave);
        if (_params._edge_threshold >= 0)
            vl_sift_set_edge_thresh(filt, _params._edge_threshold);
        if (_params._peak_threshold >= 0)
            vl_sift_set_peak_thresh(filt, 255*_params._peak_threshold/_params._num_scales);

        Descriptor<vl_sift_pix, 128> descr;
        Descriptor<unsigned char, 128> descriptor;

        // Process SIFT computation
        vl_sift_process_first_octave(filt, If.data());

        Allocate(regions);

        // Build alias to cached data
        SIFT_Regions * regionsCasted = dynamic_cast<SIFT_Regions*>(regions.get());
        // reserve some memory for faster keypoint saving
        regionsCasted->Features().reserve(2000);
        regionsCasted->Descriptors().reserve(2000);

        while (true) {
            vl_sift_detect(filt);

            VlSiftKeypoint const *keys  = vl_sift_get_keypoints(filt);
            const int nkeys = vl_sift_get_nkeypoints(filt);

            // Update gradient before launching parallel extraction
            vl_sift_update_gradient(filt);

#ifdef OPENMVG_USE_OPENMP
            #pragma omp parallel for private(descr, descriptor)
#endif
            for (int i = 0; i < nkeys; ++i) {

                // Feature masking
                if (mask)
                {
                    const image::Image<unsigned char> & maskIma = *mask;
                    if (maskIma(keys[i].y, keys[i].x) == 0)
                        continue;
                }

                double angles [4] = {0.0, 0.0, 0.0, 0.0};
                int nangles = 1; // by default (1 upright feature)
                if (_bOrientation)
                {   // compute from 1 to 4 orientations
                    nangles = vl_sift_calc_keypoint_orientations(filt, angles, keys+i);
                }

                for (int q=0 ; q < nangles ; ++q) {
                    vl_sift_calc_keypoint_descriptor(filt, &descr[0], keys+i, angles[q]);
                    const SIOPointFeature fp(keys[i].x, keys[i].y,
                                             keys[i].sigma, static_cast<float>(angles[q]));

                    siftDescToUChar(&descr[0], descriptor, _params._root_sift);
#ifdef OPENMVG_USE_OPENMP
                    #pragma omp critical
#endif
                    {
                        regionsCasted->Descriptors().push_back(descriptor);
                        regionsCasted->Features().push_back(fp);
                    }
                }
            }
            if (vl_sift_process_next_octave(filt))
                break; // Last octave
        }
        vl_sift_delete(filt);

        return true;
    };
示例#12
0
PyObject * vl_siftdescriptor_python(
		PyArrayObject & in_grad,
		PyArrayObject & in_frames)
{
	// TODO: check types and dim
	//	"GRAD must be a 2xMxN matrix of class SINGLE."

	assert(in_grad.descr->type_num == PyArray_FLOAT);
	assert(in_frames.descr->type_num == PyArray_FLOAT64);
	assert(in_grad.flags & NPY_FORTRAN);
	assert(in_frames.flags & NPY_FORTRAN);

	int verbose = 0;
	int opt;

	//  TODO: check if we need to do a copy of the grad array
	float * grad_array;
	vl_sift_pix *grad;
	int M, N;

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

	int i, j;


	/* -----------------------------------------------------------------
	 *                                               Check the arguments
	 * -------------------------------------------------------------- */

	// get frames nb and data pointer
	nikeys = in_frames.dimensions[1];
	ikeys = (double *) in_frames.data;


	// TODO: deal with optional params
	//  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 ;
	//    }
	//  }

	//  TODO: convert to Python
	//grad_array = mxDuplicateArray(in[IN_GRAD]); (copy?)
	grad = (float*) in_grad.data; //mxGetData(grad_array);
	M = in_grad.dimensions[1];
	N = in_grad.dimensions[2];


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

	/* -----------------------------------------------------------------
	 *                                                            Do job
	 * -------------------------------------------------------------- */
	PyArrayObject * _descr;
	{
		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) {
			printf("siftdescriptor: filter settings:\n");
			printf(
				"siftdescriptor:   magnif                = %g\n",
				vl_sift_get_magnif(filt));
			printf("siftdescriptor:   num of frames         = %d\n", nikeys);
		}

		{
			npy_intp dims[2];
			dims[0] = 128;
			dims[1] = nikeys;

			_descr = (PyArrayObject*) PyArray_NewFromDescr(
				&PyArray_Type, PyArray_DescrFromType(PyArray_UBYTE),
				2, dims, NULL, NULL, NPY_F_CONTIGUOUS, NULL);

			descr = (vl_uint8*) _descr->data;
		}

		/* ...............................................................
		 *                                             Process each octave
		 * ............................................................ */
		for (i = 0; i < nikeys; ++i) {
			vl_sift_pix buf[128], rbuf[128];

			double y = *ikeys++;
			double x = *ikeys++;
			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 */

	return PyArray_Return(_descr);
}
示例#13
0
文件: dump.c 项目: mdqyy/SIFT_Project
int main (int argc, const char * argv[]) {
	char *imagefilename=(char*)malloc(sizeof(char)*16);
	char *dscfilename=(char*)malloc(sizeof(char)*16);
	if (argc<3) {
		printf("Usage: ./dump-descr image-file-name descriptor-file-name");
		strcpy(imagefilename, "savekkkk.jpg");
		strcpy(dscfilename, "saveD.jpg.dsc");
	}
	else {
		strcpy(imagefilename,argv[1]);
		strcpy(dscfilename,argv[2]);
	}
	
	FILE* dscfile;
	int w=1280,h=720;
	int i=0;
	int nkeypoints=0;
	vl_bool render=1;
	vl_bool first=1;
	VlSiftFilt * myFilter=0;
	VlSiftKeypoint const* keys;
	char img2_file[] = "/Users/quake0day/ana2/MVI_0124.MOV";
	
	//printf("sizeof(VlSiftKeypoint)=%d, filt=%d, pix=%d\n", sizeof(VlSiftKeypoint), sizeof(VlSiftFilt),sizeof(vl_sift_pix));
	
	dscfile=fopen(dscfilename, "wb");
	vl_sift_pix* fim;
	int err=0;
	int octave, nlevels, o_min;
	
	//vl_sift_pix descr[128];
	
	
	//CvCapture * camera = cvCreateCameraCapture (CV_CAP_ANY);
	CvCapture * camera = cvCreateFileCapture(img2_file);

	cvNamedWindow("Hello", 1);
	
	IplImage *myCVImage=cvQueryFrame(camera);//cvLoadImage(imagefilename, 0);
	
	IplImage *afterCVImage=cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
	IplImage *resizingImg=cvCreateImage(cvSize(w, h), myCVImage->depth, myCVImage->nChannels);
	octave=3;
	nlevels=10;
	o_min=1;
	myFilter=vl_sift_new(w, h, octave, nlevels, o_min);
	vl_sift_set_peak_thresh(myFilter, 0.5);
	fim=malloc(sizeof(vl_sift_pix)*w*h);
	int press=0;
	
	while (myCVImage) {
		
		dprintf("%d*%d\n",myCVImage->width,myCVImage->height);
		//w=myCVImage->width;
		//h=myCVImage->height;
		
		cvResize(myCVImage, resizingImg, CV_INTER_AREA);
		dprintf("resized scale:%d*%d\n",myCVImage->width,myCVImage->height);
		cvConvertImage(resizingImg, afterCVImage, 0);
		
		
		for (i=0; i<h; i++) {
			for (int j=0; j<w; j++) {
				fim[i*w+j]=CV_IMAGE_ELEM(afterCVImage,uchar,i,j);
				//printf("%f ", fim[i*w+j]);
			}
		}
		
		
		//vl_sift_set_peak_thresh(myFilter, 0.5);
		//vl_sift_set_edge_thresh(myFilter, 10.0);
		first=1;
		while (1) {
			if (first) {
				first=0;
				err=vl_sift_process_first_octave(myFilter, fim);
			}
			else {
				err=vl_sift_process_next_octave(myFilter);
			}
			if (err) {
				err=VL_ERR_OK;
				break;
			}
			
			vl_sift_detect(myFilter);
			nkeypoints=vl_sift_get_nkeypoints(myFilter);
			dprintf("insider numkey:%d\n",nkeypoints);
			keys=vl_sift_get_keypoints(myFilter);
			dprintf("final numkey:%d\n",nkeypoints);
			
			
			if (render) {
				for (i=0; i<nkeypoints; i++) {
					cvCircle(resizingImg, cvPoint(keys->x, keys->y), keys->sigma, cvScalar(100, 255, 50, 0), 1, CV_AA, 0);
					//printf("x:%f,y:%f,s:%f,sigma:%f,\n",keys->x,keys->y,keys->s,keys->sigma);
					if (press=='d') {
						
						double angles [4] ;
						int nangles ;
						
						/* obtain keypoint orientations ........................... */
						nangles=vl_sift_calc_keypoint_orientations(myFilter, angles, keys);
						
						/* for each orientation ................................... */
						for (int q = 0 ; q < (unsigned) nangles ; ++q) {
							vl_sift_pix descr [128] ;
							
							
							//printf("\n");
							/* compute descriptor (if necessary) */
							vl_sift_calc_keypoint_descriptor(myFilter, descr, keys, angles[q]);
							for (int j=0; j<128; j++) {
								descr[j]*=512.0;
								descr[j]=(descr[j]<255.0)?descr[j]:255.0;
								printf("%f ", descr[j]);
							}
							fwrite(descr, sizeof(vl_sift_pix), 128, dscfile);
						}
					}
					keys++;
				}
			}
			
		}
		
		cvShowImage("Hello", resizingImg);
		
		myCVImage = cvQueryFrame(camera);
		
		press=cvWaitKey(1);
		if( press=='q' )
			return 0;
		else if( press=='r' )
			render=1-render;
	}
	free(fim);
	cvReleaseImage(&afterCVImage);
	cvReleaseImage(&resizingImg);
	cvReleaseImage(&myCVImage);
	
	return 0;
}
示例#14
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_I = 0, IN_END} ;
  enum {OUT_FRAMES=0, OUT_DESCRIPTORS, OUT_INFO, OUT_END} ;

  int verbose = 0 ;
  int opt ;
  int next = IN_END ;
  mxArray const *optarg ;
  VlEnumerator *pair ;

  float const *image ;
  vl_size numCols, numRows ;

  VlCovDetMethod method = VL_COVDET_METHOD_DOG;
  vl_bool estimateAffineShape = VL_FALSE ;
  vl_bool estimateOrientation = VL_FALSE ;

  vl_bool doubleImage = VL_TRUE ;
  vl_index octaveResolution = -1 ;
  double edgeThreshold = -1 ;
  double peakThreshold = -1 ;
  double lapPeakThreshold = -1 ;

  int descriptorType = -1 ;
  vl_index patchResolution = -1 ;
  double patchRelativeExtent = -1 ;
  double patchRelativeSmoothing = -1 ;
  float *patch = NULL ;
  float *patchXY = NULL ;

  vl_int liopNumSpatialBins = 6;
  vl_int liopNumNeighbours = 4;
  float liopRadius = 6.0;
  float liopIntensityThreshold = VL_NAN_F ;

  double boundaryMargin = 2.0 ;

  double * userFrames = NULL ;
  vl_size userFrameDimension = 0 ;
  vl_size numUserFrames = 0 ;

  VL_USE_MATLAB_ENV ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (nin < IN_END) {
    vlmxError(vlmxErrNotEnoughInputArguments, 0) ;
  } else if (nout > OUT_END) {
    vlmxError(vlmxErrTooManyOutputArguments, 0) ;
  }

  if (mxGetNumberOfDimensions(IN(I)) != 2 ||
      mxGetClassID(IN(I)) != mxSINGLE_CLASS){
    vlmxError(vlmxErrInvalidArgument, "I must be a matrix of class SINGLE.") ;
  }

  image = (float*) mxGetData(IN(I)) ;
  numRows = mxGetM(IN(I)) ;
  numCols = mxGetN(IN(I)) ;

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

    switch (opt) {

    case opt_verbose :
      ++ verbose ;
      break ;

    case opt_method:
      pair = vlmxDecodeEnumeration(optarg, vlCovdetMethods, VL_TRUE) ;
      if (pair == NULL) {
        vlmxError(vlmxErrInvalidArgument, "METHOD is not a supported detection method.") ;
      }
      method = (VlCovDetMethod)pair->value ;
      break;

      case opt_descriptor:
        pair = vlmxDecodeEnumeration(optarg, vlCovDetDescriptorTypes, VL_TRUE) ;
        if (pair == NULL) {
          vlmxError(vlmxErrInvalidArgument, "DESCRIPTOR is not a supported descriptor.") ;
        }
        descriptorType = (VlCovDetDescriptorType)pair->value ;
        break;

    case opt_estimate_affine_shape:
      if (!mxIsLogicalScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "ESTIMATEAFFINESHAPE must be a logical scalar value.") ;
      } else {
        estimateAffineShape = *mxGetLogicals(optarg) ;
      }
      break ;

    case opt_estimate_orientation:
      if (!mxIsLogicalScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "ESTIMATEORIENTATION must be a logical scalar value.") ;
      } else {
        estimateOrientation = *mxGetLogicals(optarg);
      }
      break ;

    case opt_double_image:
      if (!mxIsLogicalScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "DOUBLEIMAGE must be a logical scalar value.") ;
      } else {
        doubleImage = *mxGetLogicals(optarg);
      }
      break ;

    case opt_octave_resolution :
      if (!vlmxIsPlainScalar(optarg) || (octaveResolution = (vl_index)*mxGetPr(optarg)) < 1) {
        vlmxError(vlmxErrInvalidArgument, "OCTAVERESOLUTION must be an integer not smaller than 1.") ;
      }
      break ;

    case opt_edge_threshold :
      if (!vlmxIsPlainScalar(optarg) || (edgeThreshold = *mxGetPr(optarg)) < 1) {
        vlmxError(vlmxErrInvalidArgument, "EDGETHRESHOLD must be a real not smaller than 1.") ;
      }
      break ;

    case opt_peak_threshold :
      if (!vlmxIsPlainScalar(optarg) || (peakThreshold = *mxGetPr(optarg)) < 0) {
        vlmxError(vlmxErrInvalidArgument, "PEAKTHRESHOLD must be a non-negative real.") ;
      }
      break ;
        
    case opt_laplacian_peak_threshold :
      if (!vlmxIsPlainScalar(optarg) || (lapPeakThreshold = *mxGetPr(optarg)) < 0) {
        vlmxError(vlmxErrInvalidArgument, "LAPLACIANPEAKTHRESHOLD must be a non-negative real.") ;
      }
      break ;

    case opt_patch_relative_smoothing :
      if (!vlmxIsPlainScalar(optarg) || (patchRelativeSmoothing = *mxGetPr(optarg)) < 0) {
        vlmxError(vlmxErrInvalidArgument, "PATCHRELATIVESMOOTHING must be a non-negative real.") ;
      }
      break ;

    case opt_patch_relative_extent :
      if (!vlmxIsPlainScalar(optarg) || (patchRelativeExtent = *mxGetPr(optarg)) <= 0) {
        vlmxError(vlmxErrInvalidArgument, "PATCHRELATIVEEXTENT must be a posiive real.") ;
      }
      break ;

    case opt_patch_resolution :
      if (!vlmxIsPlainScalar(optarg) || (patchResolution = (vl_index)*mxGetPr(optarg)) <= 0) {
        vlmxError(vlmxErrInvalidArgument, "PATCHRESOLUTION must be a positive integer.") ;
      }
      break ;

    case opt_liop_bins :
      if (!vlmxIsPlainScalar(optarg) || (liopNumSpatialBins = (vl_int)*mxGetPr(optarg)) <= 0) {
        vlmxError(vlmxErrInvalidArgument, "number of LIOPNUMSPATIALBINS is not a positive scalar.") ;
      }
      break ;

    case opt_liop_neighbours :
      if (!vlmxIsPlainScalar(optarg) || (liopNumNeighbours = (vl_int)*mxGetPr(optarg)) <= 0) {
        vlmxError(vlmxErrInvalidArgument, "number of LIOPNUMNEIGHBOURS is not a positive scalar.") ;
      }
      break ;

    case opt_liop_radius :
      if (!vlmxIsPlainScalar(optarg) || (liopRadius = (float)*mxGetPr(optarg)) <= 0) {
        vlmxError(vlmxErrInvalidArgument, "LIOPRADIUS must is not a positive scalar.") ;
      }
      break ;

    case opt_liop_threshold :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "LIOPINTENSITYTHRESHOLD is not a scalar.") ;
      }
      liopIntensityThreshold = *mxGetPr(optarg) ;
      break ;

    case opt_frames:
      if (!vlmxIsPlainMatrix(optarg,-1,-1)) {
        vlmxError(vlmxErrInvalidArgument, "FRAMES must be a palin matrix.") ;
      }
      numUserFrames = mxGetN (optarg) ;
      userFrameDimension = mxGetM (optarg) ;
      userFrames = mxGetPr (optarg) ;
      switch (userFrameDimension) {
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
            /* ok */
          break ;
        default:
          vlmxError(vlmxErrInvalidArgument,
                    "FRAMES of dimensions %d are not recognised",
                    userFrameDimension); ;
      }
      break ;

    default :
      abort() ;
    }
  }

  if (descriptorType < 0) descriptorType = VL_COVDET_DESC_SIFT ;

  switch (descriptorType) {
    case VL_COVDET_DESC_NONE :
      break ;

    case VL_COVDET_DESC_PATCH :
      if (patchResolution < 0)  patchResolution = 20 ;
      if (patchRelativeExtent < 0) patchRelativeExtent = 6 ;
      if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 1 ;
      break ;

    case VL_COVDET_DESC_SIFT :
      /* the patch parameters are selected to match the SIFT descriptor geometry */
      if (patchResolution < 0)  patchResolution = 15 ;
      if (patchRelativeExtent < 0) patchRelativeExtent = 7.5 ;
      if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 1 ;
      break ;

    case VL_COVDET_DESC_LIOP :
      if (patchResolution < 0)  patchResolution = 20 ;
      if (patchRelativeExtent < 0) patchRelativeExtent = 4 ;
      if (patchRelativeSmoothing < 0) patchRelativeSmoothing = 0.5 ;
      break ;
  }

  if (patchResolution > 0) {
    vl_size w = 2*patchResolution + 1 ;
    patch = mxMalloc(sizeof(float) * w * w);
    patchXY = mxMalloc(2 * sizeof(float) * w * w);
  }

  if (descriptorType == VL_COVDET_DESC_LIOP && liopRadius > patchResolution) {
    vlmxError(vlmxErrInconsistentData, "LIOPRADIUS is larger than PATCHRESOLUTION.") ;
  }

  /* -----------------------------------------------------------------
   *                                                          Detector
   * -------------------------------------------------------------- */
  {
    VlCovDet * covdet = vl_covdet_new(method) ;

    /* set covdet parameters */
    vl_covdet_set_transposed(covdet, VL_TRUE) ;
    vl_covdet_set_first_octave(covdet, doubleImage ? -1 : 0) ;
    if (octaveResolution >= 0) vl_covdet_set_octave_resolution(covdet, octaveResolution) ;
    if (peakThreshold >= 0) vl_covdet_set_peak_threshold(covdet, peakThreshold) ;
    if (edgeThreshold >= 0) vl_covdet_set_edge_threshold(covdet, edgeThreshold) ;
    if (lapPeakThreshold >= 0) vl_covdet_set_laplacian_peak_threshold(covdet, lapPeakThreshold) ;
    
    if (verbose) {
      VL_PRINTF("vl_covdet: doubling image: %s\n",
                VL_YESNO(vl_covdet_get_first_octave(covdet) < 0)) ;
    }

    /* process the image */
    vl_covdet_put_image(covdet, image, numRows, numCols) ;

    /* fill with frames: eitehr run the detector of poure them in */
    if (numUserFrames > 0) {
      vl_index k ;

      if (verbose) {
        mexPrintf("vl_covdet: sourcing %d frames\n", numUserFrames) ;
      }

      for (k = 0 ; k < (signed)numUserFrames ; ++k) {
        double const * uframe = userFrames + userFrameDimension * k ;
        double a11, a21, a12, a22 ;
        VlCovDetFeature feature ;
        feature.peakScore = VL_INFINITY_F ;
        feature.edgeScore = 1.0 ;
        feature.frame.x = (float)uframe[1] - 1 ;
        feature.frame.y = (float)uframe[0] - 1 ;

        switch (userFrameDimension) {
          case 2:
            a11 = 1.0 ;
            a21 = 0.0 ;
            a12 = 0.0 ;
            a22 = 1.0 ;
            break ;
          case 3:
            a11 = uframe[2] ;
            a21 = 0.0 ;
            a12 = 0.0 ;
            a22 = uframe[2] ;
            break ;
          case 4:
          {
            double sigma = uframe[2] ;
            double c = cos(uframe[3]) ;
            double s = sin(uframe[3]) ;
            a11 = sigma * c ;
            a21 = sigma * s ;
            a12 = sigma * (-s) ;
            a22 = sigma * c ;
            break ;
          }
          case 5:
          {
            double d2 ;
            if (uframe[2] < 0) {
              vlmxError(vlmxErrInvalidArgument, "FRAMES(:,%d) does not have a PSD covariance.", k+1) ;
            }
            a11 = sqrt(uframe[2]) ;
            a21 = uframe[3] / VL_MAX(a11, 1e-10) ;
            a12 = 0.0 ;
            d2 = uframe[4] - a21*a21 ;
            if (d2 < 0) {
              vlmxError(vlmxErrInvalidArgument, "FRAMES(:,%d) does not have a PSD covariance.", k+1) ;
            }
            a22 = sqrt(d2) ;
            break ;
          }
          case 6:
          {
            a11 = uframe[2] ;
            a21 = uframe[3] ;
            a12 = uframe[4] ;
            a22 = uframe[5] ;
            break ;
          }
          default:
            a11 = 0 ;
            a21 = 0 ;
            a12 = 0 ;
            a22 = 0 ;
            assert(0) ;
        }
        feature.frame.a11 = (float)a22 ;
        feature.frame.a21 = (float)a12 ;
        feature.frame.a12 = (float)a21 ;
        feature.frame.a22 = (float)a11 ;
        vl_covdet_append_feature(covdet, &feature) ;
      }
    } else {
      if (verbose) {
        mexPrintf("vl_covdet: detector: %s\n",
                  vl_enumeration_get_by_value(vlCovdetMethods, method)->name) ;
        mexPrintf("vl_covdet: peak threshold: %g, edge threshold: %g\n",
                  vl_covdet_get_peak_threshold(covdet),
                  vl_covdet_get_edge_threshold(covdet)) ;
      }

      vl_covdet_detect(covdet) ;

      if (verbose) {
        vl_index i ;
        vl_size numFeatures = vl_covdet_get_num_features(covdet) ;
        mexPrintf("vl_covdet: %d features suppressed as duplicate (threshold: %g)\n",
                  vl_covdet_get_num_non_extrema_suppressed(covdet),
                  vl_covdet_get_non_extrema_suppression_threshold(covdet)) ;
        switch (method) {
        case VL_COVDET_METHOD_HARRIS_LAPLACE:
        case VL_COVDET_METHOD_HESSIAN_LAPLACE:
          {
            vl_size numScales ;
            vl_size const * numFeaturesPerScale ;
            numFeaturesPerScale = vl_covdet_get_laplacian_scales_statistics
              (covdet, &numScales) ;
            mexPrintf("vl_covdet: Laplacian scales:") ;
            for (i = 0 ; i <= (signed)numScales ; ++i) {
              mexPrintf("%d with %d scales;", numFeaturesPerScale[i], i) ;
            }
            mexPrintf("\n") ;
          }
          break ;
        default:
          break ;
        }
        mexPrintf("vl_covdet: detected %d features\n", numFeatures) ;
      }

      if (boundaryMargin > 0) {
        vl_covdet_drop_features_outside (covdet, boundaryMargin) ;
        if (verbose) {
          vl_size numFeatures = vl_covdet_get_num_features(covdet) ;
          mexPrintf("vl_covdet: kept %d inside the boundary margin (%g)\n",
                    numFeatures, boundaryMargin) ;
        }
      }
    }

    /* affine adaptation if needed */
    if (estimateAffineShape) {
      if (verbose) {
        vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ;
        mexPrintf("vl_covdet: estimating affine shape for %d features\n", numFeaturesBefore) ;
      }

      vl_covdet_extract_affine_shape(covdet) ;

      if (verbose) {
        vl_size numFeaturesAfter = vl_covdet_get_num_features(covdet) ;
        mexPrintf("vl_covdet: %d features passed affine adaptation\n", numFeaturesAfter) ;
      }
    }

    /* orientation estimation if needed */
    if (estimateOrientation) {
      vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ;
      vl_size numFeaturesAfter ;

      vl_covdet_extract_orientations(covdet) ;

      numFeaturesAfter = vl_covdet_get_num_features(covdet) ;
      if (verbose && numFeaturesAfter > numFeaturesBefore) {
        mexPrintf("vl_covdet: %d duplicate features were crated due to ambiguous "
                  "orientation detection (%d total)\n",
                  numFeaturesAfter - numFeaturesBefore, numFeaturesAfter) ;
      }
    }

    /* store results back */
    {
      vl_index i  ;
      vl_size numFeatures = vl_covdet_get_num_features(covdet) ;
      VlCovDetFeature const * feature = vl_covdet_get_features(covdet);
      double * pt ;

      OUT(FRAMES) = mxCreateDoubleMatrix (6, numFeatures, mxREAL) ;
      pt = mxGetPr(OUT(FRAMES)) ;

      for (i = 0 ; i < (signed)numFeatures ; ++i) {
        /* save the transposed frame, adjust origin to MATLAB's*/
        *pt++ = feature[i].frame.y + 1 ;
        *pt++ = feature[i].frame.x + 1 ;
        *pt++ = feature[i].frame.a22 ;
        *pt++ = feature[i].frame.a12 ;
        *pt++ = feature[i].frame.a21 ;
        *pt++ = feature[i].frame.a11 ;
      }
    }

    if (nout >= 2) {
      switch (descriptorType) {
        case VL_COVDET_DESC_NONE:
          OUT(DESCRIPTORS) = mxCreateDoubleMatrix(0,0,mxREAL);
          break ;

        case VL_COVDET_DESC_PATCH:
        {
		  vl_size numFeatures ;
		  VlCovDetFeature const * feature ;
          vl_index i ;
          vl_size w = 2*patchResolution + 1 ;
          float * desc ;

          if (verbose) {
            mexPrintf("vl_covdet: descriptors: type=patch, "
                      "resolution=%d, extent=%g, smoothing=%g\n",
                      patchResolution, patchRelativeExtent,
                      patchRelativeSmoothing);
          }
          numFeatures = vl_covdet_get_num_features(covdet) ;
          feature = vl_covdet_get_features(covdet);
          OUT(DESCRIPTORS) = mxCreateNumericMatrix(w*w, numFeatures, mxSINGLE_CLASS, mxREAL) ;
          desc = mxGetData(OUT(DESCRIPTORS)) ;
          for (i = 0 ; i < (signed)numFeatures ; ++i) {
            vl_covdet_extract_patch_for_frame(covdet,
                                    desc,
                                    patchResolution,
                                    patchRelativeExtent,
                                    patchRelativeSmoothing,
                                    feature[i].frame) ;
            desc += w*w ;
          }
          break ;
        }
        case VL_COVDET_DESC_SIFT:
        {
          vl_size numFeatures = vl_covdet_get_num_features(covdet) ;
          VlCovDetFeature const * feature = vl_covdet_get_features(covdet);
          VlSiftFilt * sift = vl_sift_new(16, 16, 1, 3, 0) ;
          vl_index i ;
          vl_size dimension = 128 ;
          vl_size patchSide = 2 * patchResolution + 1 ;
          double patchStep = (double)patchRelativeExtent / patchResolution ;
          float tempDesc [128] ;
          float * desc ;
          if (verbose) {
            mexPrintf("vl_covdet: descriptors: type=sift, "
                      "resolution=%d, extent=%g, smoothing=%g\n",
                      patchResolution, patchRelativeExtent,
                      patchRelativeSmoothing);
          }
          OUT(DESCRIPTORS) = mxCreateNumericMatrix(dimension, numFeatures, mxSINGLE_CLASS, mxREAL) ;
          desc = mxGetData(OUT(DESCRIPTORS)) ;
          vl_sift_set_magnif(sift, 3.0) ;
          for (i = 0 ; i < (signed)numFeatures ; ++i) {
            vl_covdet_extract_patch_for_frame(covdet,
                                              patch,
                                              patchResolution,
                                              patchRelativeExtent,
                                              patchRelativeSmoothing,
                                              feature[i].frame) ;

            vl_imgradient_polar_f (patchXY, patchXY +1,
                                   2, 2 * patchSide,
                                   patch, patchSide, patchSide, patchSide) ;


            /*
             Note: the patch is transposed, so that x and y are swapped.
             However, if NBO is not divisible by 4, then the configuration
             of the SIFT orientations is not symmetric by rotations of pi/2.
             Hence the only option is to rotate the descriptor further by
             an angle we need to compute the descriptor rotaed by an additional pi/2
             angle. In this manner, x concides and y is flipped.
             */
            vl_sift_calc_raw_descriptor (sift,
                                         patchXY,
                                         tempDesc,
                                         (int)patchSide, (int)patchSide,
                                         (double)(patchSide-1) / 2, (double)(patchSide-1) / 2,
                                         (double)patchRelativeExtent / (3.0 * (4 + 1) / 2) /
                                         patchStep,
                                         VL_PI / 2) ;

            flip_descriptor (desc, tempDesc) ;
            desc += dimension ;
          }
          vl_sift_delete(sift) ;
          break ;
        }
        case VL_COVDET_DESC_LIOP :
        {          /* TODO: get parameters form input */
          vl_size numFeatures = vl_covdet_get_num_features(covdet) ;
          vl_size dimension ;
          VlCovDetFeature const * feature = vl_covdet_get_features(covdet);
          vl_index i ;

          vl_size patchSide = 2 * patchResolution + 1 ;
          float * desc ;

          VlLiopDesc * liop = vl_liopdesc_new(liopNumNeighbours, liopNumSpatialBins, liopRadius, (vl_size)patchSide) ;
          if (!vl_is_nan_f(liopIntensityThreshold)) {
            vl_liopdesc_set_intensity_threshold(liop, liopIntensityThreshold) ;
          }
          dimension = vl_liopdesc_get_dimension(liop) ;
          if (verbose) {
            mexPrintf("vl_covdet: descriptors: type=liop, "
                      "resolution=%d, extent=%g, smoothing=%g\n",
                      patchResolution, patchRelativeExtent,
                      patchRelativeSmoothing);
          }
          OUT(DESCRIPTORS) = mxCreateNumericMatrix(dimension, numFeatures, mxSINGLE_CLASS, mxREAL);
          desc = mxGetData(OUT(DESCRIPTORS)) ;
          vl_tic();
          for(i = 0; i < (signed)numFeatures; i++){
              vl_covdet_extract_patch_for_frame(covdet,
                                                patch,
                                                patchResolution,
                                                patchRelativeExtent,
                                                patchRelativeSmoothing,
                                                feature[i].frame);

              vl_liopdesc_process(liop, desc, patch);

              desc += dimension;

          }
          mexPrintf("time: %f\n",vl_toc());
          mexPrintf("threshold: %f\n",liop->intensityThreshold);
          break;
        }

        default:
          assert(0) ; /* descriptor type */
      }
    }

    if (nout >= 3) {
      vl_index i ;
      vl_size numFeatures = vl_covdet_get_num_features(covdet) ;
      VlCovDetFeature const * feature = vl_covdet_get_features(covdet);
      const char* names[] = {
        "gss",
        "css",
        "peakScores",
        "edgeScores",
        "orientationScore",
        "laplacianScaleScore"
      };
      mxArray * gss_array = _createArrayFromScaleSpace(vl_covdet_get_gss(covdet)) ;
      mxArray * css_array = _createArrayFromScaleSpace(vl_covdet_get_css(covdet)) ;
      mxArray * peak_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ;
      mxArray * edge_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ;
      mxArray * orientation_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ;
      mxArray * laplacian_array = mxCreateNumericMatrix(1,numFeatures,mxSINGLE_CLASS,mxREAL) ;

      float * peak = mxGetData(peak_array) ;
      float * edge = mxGetData(edge_array) ;
      float * orientation = mxGetData(orientation_array) ;
      float * laplacian = mxGetData(laplacian_array) ;
      for (i = 0 ; i < (signed)numFeatures ; ++i) {
        peak[i] = feature[i].peakScore ;
        edge[i] = feature[i].edgeScore ;
        orientation[i] = feature[i].orientationScore ;
        laplacian[i] = feature[i].laplacianScaleScore ;
      }

      OUT(INFO) = mxCreateStructMatrix(1, 1, 6, names) ;
      mxSetFieldByNumber(OUT(INFO), 0, 0, gss_array) ;
      mxSetFieldByNumber(OUT(INFO), 0, 1, css_array) ;
      mxSetFieldByNumber(OUT(INFO), 0, 2, peak_array) ;
      mxSetFieldByNumber(OUT(INFO), 0, 3, edge_array) ;
      mxSetFieldByNumber(OUT(INFO), 0, 4, orientation_array) ;
      mxSetFieldByNumber(OUT(INFO), 0, 5, laplacian_array) ;
    }
    /* cleanup */
    vl_covdet_delete (covdet) ;
  }

  if (patchXY) mxFree(patchXY) ;
  if (patch) mxFree(patch) ;
}
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 ;
  double             magnif      = -1 ;
  double             window_size = -1 ;

  mxArray           *ikeys_array = 0 ;
  double            *ikeys = 0 ;
  int                nikeys = -1 ;
  vl_bool            force_orientations = 0 ;
  vl_bool            floatDescriptors = 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 = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {

    case opt_verbose :
      ++ verbose ;
      break ;

    case opt_frames :
      if (!vlmxIsMatrix(optarg, 4, -1)) {
        mexErrMsgTxt("'Frames' must be a 4 x N matrix.") ;
      }
      ikeys_array = mxDuplicateArray (optarg) ;
      nikeys      = mxGetN (optarg) ;
      ikeys       = mxGetPr (ikeys_array) ;
      if (! check_sorted (ikeys, nikeys)) {
        qsort (ikeys, nikeys, 4 * sizeof(double), korder) ;
      }
      break ;

    default :
		mexPrintf("F**k you!");
      abort() ;
    }
  }
  
  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  {
    VlSiftFilt        *filt ;
    vl_bool            first ;
    double            *frames = 0 ;
    void              *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) ;

	//mexPrintf("%f %f %f \n%f %f %f %f %f\n",(float)O,(float)S,(float)o_min,(float)peak_thresh
	//	,(float)edge_thresh,(float)norm_thresh,(float)magnif,(float)window_size);


    /* ...............................................................
     *                                             Process each octave
     * ............................................................ */
    i     = 0 ;
    first = 1 ;
    while (first == 1) {
      int                   err ;
      VlSiftKeypoint const *keys  = 0 ;
      int                   nkeys = 0 ;


        err   = vl_sift_process_first_octave (filt, data) ;
        first = 0 ;

      if (err) break ;

      /* Run detector ............................................. */
        nkeys = nikeys ;

	  //mexPrintf("Zhu: entering sweeping nkeys, nkeys = %d, i = %d \n", nkeys, i);

      /* For each keypoint ........................................ */
		for (; i < nkeys ; ++i) {
			int h;
			vl_sift_pix  buf[128];
			vl_sift_pix rbuf[128];
        double                angle;
        VlSiftKeypoint        ik ;
        VlSiftKeypoint const *k ;

        /* Obtain keypoint orientations ........................... */
          vl_sift_keypoint_init (filt, &ik,
                                 ikeys [4 * i + 1] - 1,
                                 ikeys [4 * i + 0] - 1,
                                 ikeys [4 * i + 2]) ;
		  //mexPrintf("ikeys: [%f, %f, %f]\n", (float)(ikeys [4 * i + 1] - 1), (float)(ikeys [4 * i + 0] - 1), (float)(ikeys [4 * i + 2]) );

          k = &ik ;

          /* optionally compute orientations too */
            angle = VL_PI / 2 - ikeys [4 * i + 3] ;
			q = 0;

		  
		  /* compute descriptor (if necessary) */
		  //int h;
		  //mexPrintf("M = %d, N = %d.\n",M,N);
		  //for (h = 0; h < 300; h++) 
		  //{
			//  mexPrintf("%f ",data[h]);
			//  if (h % 8 == 7) mexPrintf("\n");
		  //}
          if (nout > 1) {
			  //mexPrintf("angles = %f, x = %f(%d), y = %f(%d), s = %f(%d), o = %d, sigma = %f.\n buf = [", 
				  //angle,k->x,k->ix,k->y,k->iy,k->s,k->is,k->o,k->sigma);
			  vl_sift_calc_keypoint_descriptor (filt, buf, k, angle) ;
			  //for (h = 0; h < 128; h++) 
			  //{
				//  mexPrintf("%f ",(float)buf[h]);
				//  if (h % 8 == 7) mexPrintf("\n");
			  //}
			  //mexPrintf("...].\nrbuf = [");
			  transpose_descriptor (rbuf, buf) ;
			  //for (h = 0; h < 128; h++) 
			  //{
				//  mexPrintf("%f ",(float)rbuf[h]);
				//  if (h % 8 == 7) mexPrintf("\n");
			  //}
			  //mexPrintf("...].\n");
          }

          /* 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) {
              if (! floatDescriptors) {
                descr  = mxRealloc (descr,  128 * sizeof(vl_uint8) * reserved) ;
              } else {
                descr  = mxRealloc (descr,  128 * sizeof(float) * 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 - angle;

		  //mexPrintf("Zhu: %d\n", nframes);
          if (nout > 1) {
            if (! floatDescriptors) {
              for (j = 0 ; j < 128 ; ++j) {
                float x = 512.0F * rbuf [j] ;
                x = (x < 255.0F) ? x : 255.0F ;
                ((vl_uint8*)descr) [128 * nframes + j] = (vl_uint8) x ;
              }
            } else {
              for (j = 0 ; j < 128 ; ++j) {
                float x = 512.0F * rbuf [j] ;
                ((float*)descr) [128 * nframes + j] = x ;
              }
            }
          }

          ++ nframes ;
         /* next orientation */
      } /* next keypoint */
	  //break;
	  //mexPrintf("Zhu: skip subsequent octave\n");
    } /* next octave */

	//mexPrintf("nframes_tot = %d\n",nframes);

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

    {
      mwSize 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 ;
      mxSetPr         (out[OUT_FRAMES], frames) ;
      mxSetDimensions (out[OUT_FRAMES], dims, 2) ;

      if (nout > 1) {

        /* create an empty array */
        dims [0] = 0 ;
        dims [1] = 0 ;
        out[OUT_DESCRIPTORS]= mxCreateNumericArray
          (2, dims,
           floatDescriptors ? mxSINGLE_CLASS : mxUINT8_CLASS,
           mxREAL) ;

        /* set array content to be the descriptors buffer */
        dims [0] = 128 ;
        dims [1] = nframes ;
        mxSetData       (out[OUT_DESCRIPTORS], descr) ;
        mxSetDimensions (out[OUT_DESCRIPTORS], dims, 2) ;
      }
    }

    /* cleanup */
    vl_sift_delete (filt) ;

    if (ikeys_array)
      mxDestroyArray(ikeys_array) ;

  } /* end: do job */
}
void siftDesctor::covdet_keypoints_and_descriptors(cv::Mat &img, std::vector<std::vector<float>> &frames, std::vector<std::vector<float>> &desctor, bool rootSIFT, bool verbose){
    
    bool display_image = 0;
    
    vl_size numCols, numRows;
    numCols = img.cols; //61
    numRows = img.rows; //74
    
    img = (cv::Mat_<float>)img/255.0;
    
    // This is for debugging, checking the image was correctly loaded.
    if (display_image) {
        std::string window_name = "Image";
        namedWindow(window_name, cv::WINDOW_AUTOSIZE );// Create a window for display.
        imshow(window_name, img);               // Show our image inside it.
        cv::waitKey(0);                                 // Wait for a keystroke in the window
    }
    
    cv::Mat imageTest(img.rows, img.cols, CV_32FC1);
    cv::Mat imgT(img.cols, img.rows, CV_32FC1);
    img.copyTo(imageTest);
    imgT = img.t();
    imgT = imgT.reshape(1,1);
    //std::cout << imgT << std::endl;
    
    float *image = new float[(int)imgT.cols];
    for(int i = 0; i < imgT.cols; i++){
        image[i] = (float)imgT.at<float>(i);
        //std::cout << image[i] << " ";
    }
    
    typedef enum _VlCovDetDescriptorType{
        VL_COVDET_DESC_SIFT
    } VlCovDetDescriporType;
    
    
    VlCovDetMethod method = VL_COVDET_METHOD_DOG;
    //vl_bool estimateAffineShape = VL_FALSE;
    //vl_bool estimateOrientation = VL_FALSE;
    
    vl_bool doubleImage = VL_TRUE;
    vl_index octaveResolution = -1;
    double edgeThreshold = 10;
    double peakThreshold = 0.01;
    double lapPeakThreshold = -1;
    
    int descriptorType = -1;
    vl_index patchResolution = -1;
    double patchRelativeExtent = -1;
    double patchRelativeSmoothing = -1;
    
    double boundaryMargin = 2.0;
    
    if (descriptorType < 0) descriptorType = VL_COVDET_DESC_SIFT;
    
    switch (descriptorType){
        case VL_COVDET_DESC_SIFT:
            if (patchResolution < 0) patchResolution = 15;
            if (patchRelativeExtent < 0) patchRelativeExtent = 10;
            if (patchRelativeSmoothing <0) patchRelativeSmoothing = 1;
            if (verbose){
                printf("vl_covdet: VL_COVDET_DESC_SIFT: patchResolution=%lld, patchRelativeExtent=%g, patchRelativeSmoothing=%g\n", patchResolution, patchRelativeExtent, patchRelativeSmoothing);
            }
    }
    
    if (1) {
        //clock_t t_start = clock();
        // create a detector object: VL_COVDET_METHOD_HESSIAN
        VlCovDet * covdet = vl_covdet_new(method);
        
        // set various parameters (optional)
        vl_covdet_set_transposed(covdet, VL_TRUE);
        vl_covdet_set_first_octave(covdet, doubleImage? -1 : 0);
        if (octaveResolution >= 0) vl_covdet_set_octave_resolution(covdet, octaveResolution);
        if (peakThreshold >= 0) vl_covdet_set_peak_threshold(covdet, peakThreshold);
        if (edgeThreshold >= 0) vl_covdet_set_edge_threshold(covdet, edgeThreshold);
        if (lapPeakThreshold >= 0) vl_covdet_set_laplacian_peak_threshold(covdet, lapPeakThreshold);
        
        //vl_covdet_set_target_num_features(covdet, target_num_features);
        //vl_covdet_set_use_adaptive_suppression(covdet, use_adaptive_suppression);
        
        if(verbose){
            VL_PRINTF("vl_covdet: doubling image: %s, image size: numRows = %d, numCols = %d\n", VL_YESNO(vl_covdet_get_first_octave(covdet) < 0), numCols, numRows);
        }
        
        // process the image and run the detector, im.shape(1) is column, im.shape(0) is row
        //see http://www.vlfeat.org/api/covdet_8h.html#affcedda1fdc7ed72d223e0aab003024e for detail
        vl_covdet_put_image(covdet, image, numRows, numCols);
        
        if (verbose) {
            VL_PRINTF("vl_covdet: detector: %s\n", vl_enumeration_get_by_value(vlCovdetMethods, method)->name);
            VL_PRINTF("vl_covdet: peak threshold: %g, edge threshold: %g\n", vl_covdet_get_peak_threshold(covdet),vl_covdet_get_edge_threshold(covdet));
        }

        vl_covdet_detect(covdet);
        
        if (verbose) {
            vl_size numFeatures = vl_covdet_get_num_features(covdet) ;
            VL_PRINTF("vl_covdet: %d features suppressed as duplicate (threshold: %g)\n", vl_covdet_get_num_non_extrema_suppressed(covdet), vl_covdet_get_non_extrema_suppression_threshold(covdet));
            VL_PRINTF("vl_covdet: detected %d features", numFeatures);
        }
        
        
        //drop feature on the margin(optimal)
        if(boundaryMargin > 0){
            vl_covdet_drop_features_outside(covdet, boundaryMargin);
            if(verbose){
                vl_size numFeatures = vl_covdet_get_num_features(covdet);
                VL_PRINTF("vl_covdet: kept %d inside the boundary margin (%g)\n", numFeatures, boundaryMargin);
            }
        }
        
        /* affine adaptation if needed */
        bool estimateAffineShape = true;
        if (estimateAffineShape) {
            if (verbose) {
                vl_size numFeaturesBefore = vl_covdet_get_num_features(covdet) ;
                VL_PRINTF("vl_covdet: estimating affine shape for %d features", numFeaturesBefore);
            }
            
            vl_covdet_extract_affine_shape(covdet) ;
            
            if (verbose) {
                vl_size numFeaturesAfter = vl_covdet_get_num_features(covdet) ;
                VL_PRINTF("vl_covdet: %d features passed affine adaptation\n", numFeaturesAfter);
            }
        }
        
        // compute the orientation of the features (optional)
        //vl_covdet_extract_orientations(covdet);
        
        // get feature descriptors
        vl_size numFeatures = vl_covdet_get_num_features(covdet);
        VlCovDetFeature const * feature = (VlCovDetFeature const *)vl_covdet_get_features(covdet);
        VlSiftFilt * sift = vl_sift_new(16, 16, 1, 3, 0);
        vl_size patchSide = 2 * patchResolution + 1;
        double patchStep = (double)patchRelativeExtent / patchResolution;
        float tempDesc[128];
        //float * desc;
        if (verbose) {
            VL_PRINTF("vl_covdet: descriptors: type = sift, resolution = %d, extent = %g, smoothing = %g\n", patchResolution,patchRelativeExtent, patchRelativeSmoothing);
        }
        
        //std::vector<float> points(6 * numFeatures);
        //std::vector<float> desc(dimension * numFeatures);
        
        std::vector<float> desc(128);
        std::vector<float> frame(6);
        
        //std::vector<float> patch(patchSide * patchSide);
        //std::vector<float> patchXY(2 * patchSide * patchSide);
        float *patch = (float*)malloc(sizeof(float)*patchSide*patchSide);
        float *patchXY = (float*)malloc(2*sizeof(float)*patchSide*patchSide);
        
        vl_sift_set_magnif(sift, 3.0);
        for (vl_index i = 0; i < (signed)numFeatures; i++) {
            frame.clear();
            frame.push_back(feature[i].frame.y);
            frame.push_back(feature[i].frame.x);
            frame.push_back(feature[i].frame.a22);
            frame.push_back(feature[i].frame.a12);
            frame.push_back(feature[i].frame.a21);
            frame.push_back(feature[i].frame.a11);
            frames.push_back(frame);
            //std::cout << std::setiosflags(std::ios::fixed);
            //std::cout << std::setprecision(6) << feature[i].frame.y << ", " << feature[i].frame.x << ", " << feature[i].frame.a22 << ", "<< feature[i].frame.a12 << ", "<< feature[i].frame.a21 << ", " << feature[i].frame.a11 << ", "<< std::endl;
            
            vl_covdet_extract_patch_for_frame(covdet,
                                              patch,
                                              patchResolution,
                                              patchRelativeExtent,
                                              patchRelativeSmoothing,
                                              feature[i].frame);
            
            vl_imgradient_polar_f(patchXY, patchXY+1,
                                  2, 2 * patchSide,
                                  patch, patchSide, patchSide, patchSide);
            
            vl_sift_calc_raw_descriptor(sift,
                                        patchXY,
                                        tempDesc,
                                        (int)patchSide, (int)patchSide,
                                        (double)(patchSide - 1) / 2, (double)(patchSide - 1) / 2,
                                        (double)patchRelativeExtent / (3.0 * (4 + 1) / 2) / patchStep,
                                        VL_PI / 2);
            flip_descriptor(desc, tempDesc);
            
            // sift or rootsift
            if(rootSIFT == true){
                std::vector<float> rootdesc = rootsift(desc);
                desctor.push_back(rootdesc);
            }else{
                desctor.push_back(desc);
            }
            /*std::cout << std::setiosflags(std::ios::fixed);
            for(vl_index j = 0; j < 128; j++){
                std::cout << std::setprecision(6) << desc[j] << " ";
            }
            std::cout << "\n" << std::endl;*/
        }
        vl_sift_delete(sift);
        vl_covdet_delete(covdet);
        //delete covdet;
        delete patch;
        delete patchXY;
    }
}
示例#17
0
/** @brief SIFT driver entry point
 **/
int
main(int argc, char **argv)
{
  /* algorithm parameters */
  double   edge_thresh  = -1 ;
  double   peak_thresh  = -1 ;
  double   magnif       = -1 ;
  int      O = -1, S = 3, omin = -1 ;

  vl_bool  err    = VL_ERR_OK ;
  char     err_msg [1024] ;
  int      n ;
  int      exit_code          = 0 ;
  int      verbose            = 0 ;
  vl_bool  force_output       = 0 ;
  vl_bool  force_orientations = 0 ;

  VlFileMeta out  = {1, "%.sift",  VL_PROT_ASCII, "", 0} ;
  VlFileMeta frm  = {0, "%.frame", VL_PROT_ASCII, "", 0} ;
  VlFileMeta dsc  = {0, "%.descr", VL_PROT_ASCII, "", 0} ;
  VlFileMeta met  = {0, "%.meta",  VL_PROT_ASCII, "", 0} ;
  VlFileMeta gss  = {0, "%.pgm",   VL_PROT_ASCII, "", 0} ;
  VlFileMeta ifr  = {0, "%.frame", VL_PROT_ASCII, "", 0} ;

#define ERRF(msg, arg) {                                        \
    err = VL_ERR_BAD_ARG ;                                      \
    snprintf(err_msg, sizeof(err_msg), msg, arg) ;              \
    break ;                                                     \
  }

#define ERR(msg) {                                              \
    err = VL_ERR_BAD_ARG ;                                      \
    snprintf(err_msg, sizeof(err_msg), msg) ;                   \
    break ;                                                     \
}

  /* -----------------------------------------------------------------
   *                                                     Parse options
   * -------------------------------------------------------------- */

  while (!err) {
    int ch = getopt_long(argc, argv, opts, longopts, 0) ;

    /* If there are no files passed as input, print the help and settings */
    if (ch == -1 && argc - optind == 0)
      ch = 'h';

    /* end of option list? */
    if (ch == -1) break;

    switch (ch) {

    case '?' :
      /* unkown option ............................................ */
      ERRF("Invalid option '%s'.", argv [optind - 1]) ;
      break ;

    case ':' :
      /* missing argument ......................................... */
      ERRF("Missing mandatory argument for option '%s'.",
          argv [optind - 1]) ;
      break ;

    case 'h' :
      /* --help ................................................... */
      printf (help_message, argv [0]) ;
      printf ("SIFT         filespec: `%s'\n", out.pattern) ;
      printf ("Frames       filespec: `%s'\n", frm.pattern) ;
      printf ("Descriptors  filespec: `%s'\n", dsc.pattern) ;
      printf ("Meta         filespec: `%s'\n", met.pattern) ;
      printf ("GSS          filespec: '%s'\n", gss.pattern) ;
      printf ("Read frames  filespec: '%s'\n", ifr.pattern) ;
      printf ("Version: driver %s; libvl %s\n",
              VL_XSTRINGIFY(VL_SIFT_DRIVER_VERSION),
              vl_get_version_string()) ;
      exit (0) ;
      break ;

    case 'v' :
      /* --verbose ................................................ */
      ++ verbose ;
      break ;

    case 'o' :
      /* --output  ................................................ */
      err = vl_file_meta_parse (&out, optarg) ;
      if (err)
        ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
      force_output = 1 ;
      break ;

    case opt_frames :
      /* --frames  ................................................ */
      err = vl_file_meta_parse (&frm, optarg) ;
      if (err)
        ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
      break ;

    case opt_descriptors :
      /* --descriptor ............................................. */
      err = vl_file_meta_parse (&dsc, optarg) ;
      if (err)
        ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
      break;

    case opt_meta :
      /* --meta ................................................... */
      err = vl_file_meta_parse (&met, optarg) ;
      if (err)
        ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;

      if (met.protocol != VL_PROT_ASCII)
        ERR("meta file supports only ASCII protocol") ;
      break ;

    case opt_read_frames :
      /* --read_frames ............................................ */
      err = vl_file_meta_parse (&ifr, optarg) ;
      if (err)
        ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
      break ;

    case opt_gss :
      /* --gss .................................................... */
      err = vl_file_meta_parse (&gss, optarg) ;
      if (err)
        ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ;
      break ;



    case 'O' :
      /* --octaves ............................................... */
      n = sscanf (optarg, "%d", &O) ;
      if (n == 0 || O < 0)
        ERRF("The argument of '%s' must be a non-negative integer.",
            argv [optind - 1]) ;
      break ;

    case 'S' :
      /* --levels ............................................... */
      n = sscanf (optarg, "%d", &S) ;
      if (n == 0 || S < 0)
        ERRF("The argument of '%s' must be a non-negative integer.",
            argv [optind - 1]) ;
      break ;

    case opt_first_octave :
      /* --first-octave ......................................... */
      n = sscanf (optarg, "%d", &omin) ;
      if (n == 0)
        ERRF("The argument of '%s' must be an integer.",
            argv [optind - 1]) ;
      break ;



    case opt_edge_thresh :
      /* --edge-thresh ........................................... */
      n = sscanf (optarg, "%lf", &edge_thresh) ;
      if (n == 0 || edge_thresh < 1)
        ERRF("The argument of '%s' must be not smaller than 1.",
            argv [optind - 1]) ;
      break ;

    case opt_peak_thresh :
      /* --edge-thresh ........................................... */
      n = sscanf (optarg, "%lf", &peak_thresh) ;
      if (n == 0 || peak_thresh < 0)
        ERRF("The argument of '%s' must be a non-negative float.",
            argv [optind - 1]) ;
      break ;

    case opt_magnif :
      /* --magnif  .............................................. */
      n = sscanf (optarg, "%lf", &magnif) ;
      if (n == 0 || magnif < 1)
        ERRF("The argument of '%s' must be a non-negative float.",
            argv [optind - 1]) ;
      break ;


    case opt_orientations :
      /* --orientations ......................................... */
      force_orientations = 1 ;
      break ;

    case 0 :
    default :
      /* should not get here ...................................... */
      assert (0) ;
      break ;
    }
  }

  /* check for parsing errors */
  if (err) {
    fprintf(stderr, "%s: error: %s (%d)\n",
            argv [0],
            err_msg, err) ;
    exit (1) ;
  }

  /* parse other arguments (filenames) */
  argc -= optind ;
  argv += optind ;

  /*
     if --output is not specified, specifying --frames or --descriptors
     prevent the aggregate outout file to be produced.
  */
  if (! force_output && (frm.active || dsc.active)) {
    out.active = 0 ;
  }

  if (verbose > 1) {
#define PRNFO(name,fm)                                                  \
    printf("sift: " name) ;                                             \
    printf("%3s ",  (fm).active ? "yes" : "no") ;                       \
    printf("%-6s ", vl_string_protocol_name ((fm).protocol)) ;          \
    printf("%-10s\n", (fm).pattern) ;

    PRNFO("write aggregate . ", out) ;
    PRNFO("write frames .... ", frm) ;
    PRNFO("write descriptors ", dsc) ;
    PRNFO("write meta ...... ", met) ;
    PRNFO("write GSS ....... ", gss) ;
    PRNFO("read  frames .... ", ifr) ;

    if (force_orientations)
      printf("sift: will compute orientations\n") ;
  }

  /* ------------------------------------------------------------------
   *                                         Process one image per time
   * --------------------------------------------------------------- */

  while (argc--) {

    char             basename [1024] ;
    char const      *name = *argv++ ;

    FILE            *in    = 0 ;
    vl_uint8        *data  = 0 ;
    vl_sift_pix     *fdata = 0 ;
    VlPgmImage       pim ;

    VlSiftFilt      *filt = 0 ;
    int              q, i ;
    vl_bool          first ;

    double           *ikeys = 0 ;
    int              nikeys = 0, ikeys_size = 0 ;

    /* ...............................................................
     *                                                 Determine files
     * ............................................................ */

    /* get basenmae from filename */
    q = vl_string_basename (basename, sizeof(basename), name, 1) ;

    err = (q >= sizeof(basename)) ;

    if (err) {
      snprintf(err_msg, sizeof(err_msg),
               "Basename of '%s' is too long", name);
      err = VL_ERR_OVERFLOW ;
      goto done ;
    }

    if (verbose) {
      printf ("sift: <== '%s'\n", name) ;
    }

    if (verbose > 1) {
      printf ("sift: basename is '%s'\n", basename) ;
    }

    /* open input file */
    in = fopen (name, "rb") ;
    if (!in) {
      err = VL_ERR_IO ;
      snprintf(err_msg, sizeof(err_msg),
               "Could not open '%s' for reading.", name) ;
      goto done ;
    }

    /* ...............................................................
     *                                                       Read data
     * ............................................................ */

    /* read PGM header */
    err = vl_pgm_extract_head (in, &pim) ;

    if (err) {
      switch (vl_err_no) {
      case  VL_ERR_PGM_IO :
        snprintf(err_msg, sizeof(err_msg),
                 "Cannot read from '%s'.", name) ;
        err = VL_ERR_IO ;
        break ;

      case VL_ERR_PGM_INV_HEAD :
        snprintf(err_msg, sizeof(err_msg),
                 "'%s' contains a malformed PGM header.", name) ;
        err = VL_ERR_IO ;
        goto done ;
      }
    }

    if (verbose)
      printf ("sift: image is %d by %d pixels\n",
              pim. width,
              pim. height) ;

    /* allocate buffer */
    data  = malloc(vl_pgm_get_npixels (&pim) *
                   vl_pgm_get_bpp       (&pim) * sizeof (vl_uint8)   ) ;
    fdata = malloc(vl_pgm_get_npixels (&pim) *
                   vl_pgm_get_bpp       (&pim) * sizeof (vl_sift_pix)) ;

    if (!data || !fdata) {
      err = VL_ERR_ALLOC ;
      snprintf(err_msg, sizeof(err_msg),
               "Could not allocate enough memory.") ;
      goto done ;
    }

    /* read PGM body */
    err  = vl_pgm_extract_data (in, &pim, data) ;

    if (err) {
      snprintf(err_msg, sizeof(err_msg), "PGM body malformed.") ;
      err = VL_ERR_IO ;
      goto done ;
    }

    /* convert data type */
    for (q = 0 ; q < pim.width * pim.height ; ++q)
      fdata [q] = data [q] ;

    /* ...............................................................
     *                                     Optionally source keypoints
     * ............................................................ */

#define WERR(name,op)                                           \
    if (err == VL_ERR_OVERFLOW) {                               \
      snprintf(err_msg, sizeof(err_msg),                        \
               "Output file name too long.") ;                  \
      goto done ;                                               \
    } else if (err) {                                           \
      snprintf(err_msg, sizeof(err_msg),                        \
               "Could not open '%s' for " #op, name) ;          \
      goto done ;                                               \
    }

    if (ifr.active) {

      /* open file */
      err = vl_file_meta_open (&ifr, basename, "rb") ;
      WERR(ifr.name, reading) ;

#define QERR                                                            \
      if (err ) {                                                       \
        snprintf (err_msg, sizeof(err_msg),                             \
                  "'%s' malformed", ifr.name) ;                         \
        err = VL_ERR_IO ;                                               \
        goto done ;                                                     \
      }

      while (1) {
        double x, y, s, th ;

        /* read next guy */
        err = vl_file_meta_get_double (&ifr, &x) ;
        if   (err == VL_ERR_EOF) break;
        else QERR ;
        err = vl_file_meta_get_double (&ifr, &y ) ; QERR ;
        err = vl_file_meta_get_double (&ifr, &s ) ; QERR ;
        err = vl_file_meta_get_double (&ifr, &th) ;
        if   (err == VL_ERR_EOF) break;
        else QERR ;

        /* make enough space */
        if (ikeys_size < nikeys + 1) {
          ikeys_size += 10000 ;
          ikeys       = realloc (ikeys, 4 * sizeof(double) * ikeys_size) ;
        }

        /* add the guy to the buffer */
        ikeys [4 * nikeys + 0]  = x ;
        ikeys [4 * nikeys + 1]  = y ;
        ikeys [4 * nikeys + 2]  = s ;
        ikeys [4 * nikeys + 3]  = th ;

        ++ nikeys ;
      }

      /* now order by scale */
      qsort (ikeys, nikeys, 4 * sizeof(double), korder) ;

      if (verbose) {
        printf ("sift: read %d keypoints from '%s'\n", nikeys, ifr.name) ;
      }

      /* close file */
      vl_file_meta_close (&ifr) ;
    }

    /* ...............................................................
     *                                               Open output files
     * ............................................................ */

    err = vl_file_meta_open (&out, basename, "wb") ; WERR(out.name, writing) ;
    err = vl_file_meta_open (&dsc, basename, "wb") ; WERR(dsc.name, writing) ;
    err = vl_file_meta_open (&frm, basename, "wb") ; WERR(frm.name, writing) ;
    err = vl_file_meta_open (&met, basename, "wb") ; WERR(met.name, writing) ;

    if (verbose > 1) {
      if (out.active) printf("sift: writing all ....... to . '%s'\n", out.name);
      if (frm.active) printf("sift: writing frames .... to . '%s'\n", frm.name);
      if (dsc.active) printf("sift: writing descriptors to . '%s'\n", dsc.name);
      if (met.active) printf("sift: writign meta ...... to . '%s'\n", met.name);
    }

    /* ...............................................................
     *                                                     Make filter
     * ............................................................ */

    filt = vl_sift_new (pim.width, pim.height, O, S, omin) ;

    if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ;
    if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ;
    if (magnif      >= 0) vl_sift_set_magnif      (filt, magnif) ;

    if (!filt) {
      snprintf (err_msg, sizeof(err_msg),
                "Could not create SIFT filter.") ;
      err = VL_ERR_ALLOC ;
      goto done ;
    }

    if (verbose > 1) {
      printf ("sift: filter settings:\n") ;
      printf ("sift:   octaves      (O)     = %d\n",
              vl_sift_get_noctaves     (filt)) ;
      printf ("sift:   levels       (S)     = %d\n",
              vl_sift_get_nlevels      (filt)) ;
      printf ("sift:   first octave (o_min) = %d\n",
              vl_sift_get_octave_first (filt)) ;
      printf ("sift:   edge thresh           = %g\n",
              vl_sift_get_edge_thresh  (filt)) ;
      printf ("sift:   peak thresh           = %g\n",
              vl_sift_get_peak_thresh  (filt)) ;
      printf ("sift:   magnif                = %g\n",
              vl_sift_get_magnif       (filt)) ;
      printf ("sift: will source frames? %s\n",
              ikeys ? "yes" : "no") ;
      printf ("sift: will force orientations? %s\n",
              force_orientations ? "yes" : "no") ;
    }

    /* ...............................................................
     *                                             Process each octave
     * ............................................................ */
    i     = 0 ;
    first = 1 ;
    while (1) {
      VlSiftKeypoint const *keys ;
      int                   nkeys ;

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

      if (err) {
        err = VL_ERR_OK ;
        break ;
      }

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

      /* optionally save GSS */
      if (gss.active) {
        err = save_gss (filt, &gss, basename, verbose) ;
        if (err) {
          snprintf (err_msg, sizeof(err_msg),
                    "Could not write GSS to PGM file.") ;
          goto done ;
        }
      }

      /* run detector ............................................. */
      if (ikeys == 0) {
        vl_sift_detect (filt) ;

        keys  = vl_sift_get_keypoints     (filt) ;
        nkeys = vl_sift_get_nkeypoints (filt) ;
        i     = 0 ;

        if (verbose > 1) {
          printf ("sift: 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 (ikeys) {
          vl_sift_keypoint_init (filt, &ik,
                                 ikeys [4 * i + 0],
                                 ikeys [4 * i + 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] = 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 descr [128] ;

          /* compute descriptor (if necessary) */
          if (out.active || dsc.active) {
            vl_sift_calc_keypoint_descriptor
              (filt, descr, k, angles [q]) ;
          }

          if (out.active) {
            int l ;
            vl_file_meta_put_double (&out, k -> x     ) ;
            vl_file_meta_put_double (&out, k -> y     ) ;
            vl_file_meta_put_double (&out, k -> sigma ) ;
            vl_file_meta_put_double (&out, angles [q] ) ;
            for (l = 0 ; l < 128 ; ++l) {
              vl_file_meta_put_uint8 (&out, (vl_uint8) (512.0 * descr [l])) ;
            }
            if (out.protocol == VL_PROT_ASCII) fprintf(out.file, "\n") ;
          }

          if (frm.active) {
            vl_file_meta_put_double (&frm, k -> x     ) ;
            vl_file_meta_put_double (&frm, k -> y     ) ;
            vl_file_meta_put_double (&frm, k -> sigma ) ;
            vl_file_meta_put_double (&frm, angles [q] ) ;
            if (frm.protocol == VL_PROT_ASCII) fprintf(frm.file, "\n") ;
          }

          if (dsc.active) {
            int l ;
            for (l = 0 ; l < 128 ; ++l) {
              double x = 512.0 * descr[l] ;
              x = (x < 255.0) ? x : 255.0 ;
              vl_file_meta_put_uint8 (&dsc, (vl_uint8) (x)) ;
            }
            if (dsc.protocol == VL_PROT_ASCII) fprintf(dsc.file, "\n") ;
          }
        }
      }
    }

    /* ...............................................................
     *                                                       Finish up
     * ............................................................ */

    if (met.active) {
      fprintf(met.file, "<sift\n") ;
      fprintf(met.file, "  input       = '%s'\n", name) ;
      if (dsc.active) {
        fprintf(met.file, "  descriptors = '%s'\n", dsc.name) ;
      }
      if (frm.active) {
        fprintf(met.file,"  frames      = '%s'\n", frm.name) ;
      }
      fprintf(met.file, ">\n") ;
    }

  done :
    /* release input keys buffer */
    if (ikeys) {
      free (ikeys) ;
      ikeys_size = nikeys = 0 ;
      ikeys = 0 ;
    }

    /* release filter */
    if (filt) {
      vl_sift_delete (filt) ;
      filt = 0 ;
    }

    /* release image data */
    if (fdata) {
      free (fdata) ;
      fdata = 0 ;
    }

    /* release image data */
    if (data) {
      free (data) ;
      data = 0 ;
    }

    /* close files */
    if (in) {
      fclose (in) ;
      in = 0 ;
    }

    vl_file_meta_close (&out) ;
    vl_file_meta_close (&frm) ;
    vl_file_meta_close (&dsc) ;
    vl_file_meta_close (&met) ;
    vl_file_meta_close (&gss) ;
    vl_file_meta_close (&ifr) ;

    /* if bad print error message */
    if (err) {
      fprintf
        (stderr,
         "sift: err: %s (%d)\n",
         err_msg,
         err) ;
      exit_code = 1 ;
    }
  }

  /* quit */
  return exit_code ;
}
示例#18
0
static PyObject *sift(PyObject *self, PyObject *args, PyObject *kwargs)
{
  PyObject *input, *input_frames = NULL;
  PyArrayObject *matin, *out_descr, *out_frames;
  /* Input arguments */
  static char *kwlist[] = {"input", "Octave", "Levels", "FirstOctave", "Frames",
                           "PeakThresh", "EdgeThresh", "NormThresh", "Orientations", "Verbose", NULL};

  enum {IN_I=0,IN_END} ;
  enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ;

  int                verbose = 0 ;
  int                opt ;
  int                next = IN_END ;
  int                nout = 2;
  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 ;

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

  //  VL_USE_MATLAB_ENV ;

  /* Parse Python tuples into their appropriate variables */
  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iiiOiiiii", kwlist, &matin, &O, &S, &o_min, &input_frames,
                                   &peak_thresh, &edge_thresh, &norm_thresh, &force_orientations, &verbose))
    return NULL;

  //  matin = (PyArrayObject *) PyArray_ContiguousFromObject(input, PyArray_FLOAT, 2, 2);
  //if (matin == NULL)
  //  return NULL;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */

  if (matin->nd != 2 || matin->descr->type_num != PyArray_FLOAT) {
    printf("I must be a 2d matrix of dtype float32\n") ;
    return NULL;
  }

  // Pointer to the data array in matin
  //data = (vl_sift_pix *) pyvector_to_Carrayptrs(matin);
  // vl_sift_pix is float!
  data = (vl_sift_pix *) matin->data;

  M = matin->dimensions[0];
  N = matin->dimensions[1];

  if (input_frames != NULL) {
    ikeys_array = (PyArrayObject *) PyArray_ContiguousFromObject(input_frames, PyArray_FLOAT, 2, 2);
    if (ikeys_array->dimensions[0] != 4) {
      printf("'Frames' must be a 4 x N matrix.x\n");
      return NULL;
    }
    nikeys = ikeys_array->dimensions[1];
    ikeys = (double *) ikeys_array->data;
    qsort (ikeys, nikeys, 4 * sizeof(double), korder);
  }


  /* -----------------------------------------------------------------
   *                                                            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) {
      printf("siftmx: filter settings:\n") ;
      printf("siftpy:   octaves      (O)     = %d\n",
             vl_sift_get_octave_num   (filt)) ;
      printf("siftpy:   levels       (S)     = %d\n",
             vl_sift_get_level_num    (filt)) ;
      printf("siftpy:   first octave (o_min) = %d\n",
             vl_sift_get_octave_first (filt)) ;
      printf("siftpy:   edge thresh           = %g\n",
             vl_sift_get_edge_thresh   (filt)) ;
      printf("siftpy:   peak thresh           = %g\n",
             vl_sift_get_peak_thresh   (filt)) ;
      printf("siftpy:   norm thresh           = %g\n",
             vl_sift_get_norm_thresh   (filt)) ;
      printf("siftpy: will force orientations? %s\n",
             force_orientations ? "yes" : "no") ;
    }
    
    Py_BEGIN_ALLOW_THREADS

    /* ...............................................................
     *                                             Process each octave
     * ............................................................ */
    i     = 0 ;
    first = 1 ;
    while (1) {
      int                   err ;
      VlSiftKeypoint const *keys  = 0 ;
      int                   nkeys = 0 ;

      if (verbose) {
        printf ("siftpy: 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("siftpy: 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 ("siftpy: 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 = malloc (4 * sizeof(double) * reserved) ;
            if (nout > 1) {
              descr  = malloc (128 * sizeof(vl_uint8) * 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) {
      printf ("siftpy: found %d keypoints\n", nframes) ;
    }

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

    {
      int dims [2] ;

      /* create an empty array */
      dims [0] = nframes ;
      dims [1] = 4 ;
      // We are allocating new memory here because its the only way to make
      // sure that it will get free()ed when there are no more references
      out_frames = (PyArrayObject*) PyArray_FromDims(2, dims, PyArray_DOUBLE);
      memcpy((double*) out_frames->data, frames, 4 * nframes * sizeof(double));
      dims [0] = nframes ; // Numpy Array uses row format, Matlab uses column format
      dims [1] = 128 ;
      out_descr = (PyArrayObject*) PyArray_FromDims(2, dims, PyArray_UBYTE);
      memcpy((vl_uint8 *) out_descr->data, descr, 128 * nframes * sizeof(vl_uint8) );
    }

    /* cleanup */
    vl_sift_delete (filt) ;
    free(frames);
    free(descr);

  } /* end: do job */
  return Py_BuildValue("(OO)",PyArray_Return(out_frames), PyArray_Return(out_descr));
}
int GetSiftFeatures(unsigned char *data, int nw, int nh, float *features, int *features_num)
{
	vl_sift_pix *img_data = (vl_sift_pix *)malloc(sizeof(vl_sift_pix) * nw * nh);
	if(img_data == NULL)
	{
		printf("Memory overflow error:can't apply image data memory!\n");
		return -1;
	}
	unsigned char *pixel;
	int i = 0, j = 0;
	for(i = 0;i < nh;++i)
	{
		for(j = 0;j < nw;++j)
		{
			pixel = (unsigned char *)(data + i * nw + j);
			img_data[i * nw + j] = *pixel;
		}
	}
	int noctaves = 4, nlevels = 3, o_min = -1;
	VlSiftFilt *sift_filt = NULL;
	sift_filt =  vl_sift_new(nw, nh, noctaves, nlevels, o_min);
	int num_descriptors = 0;
	// int save_flag = -1;
	if(vl_sift_process_first_octave(sift_filt,img_data) != VL_ERR_EOF)
	{
		while(1)
		{
			vl_sift_detect(sift_filt);
			VlSiftKeypoint *sift_keypoints = sift_filt->keys; 
			for(i = 0; i < sift_filt->nkeys;++i)
			{
				VlSiftKeypoint temp_sift_keypoint = *sift_keypoints;
				double angles[4];
				int angle_count = vl_sift_calc_keypoint_orientations(sift_filt,angles,&temp_sift_keypoint);
				for(j = 0; j < angle_count;++j)
				{
					double temp_angle = angles[j];
					float *descriptor = (float *)malloc(sizeof(float) * SIFT_DESCRIPTOR_DIM);
					vl_sift_calc_keypoint_descriptor(sift_filt, descriptor, &temp_sift_keypoint, temp_angle);
					float *curr_features = features + num_descriptors * SIFT_DESCRIPTOR_DIM;
					// if(save_flag == -1)
					// {
						memcpy(curr_features,descriptor,sizeof(float) * SIFT_DESCRIPTOR_DIM);
						//save_flag == 1;
					// }
					++num_descriptors;
					free(descriptor);
				}
				++sift_keypoints;
			}
			if(vl_sift_process_next_octave(sift_filt) == VL_ERR_EOF)
			{
				break;
			}
		}
	}
	*features_num = num_descriptors;
	vl_sift_delete(sift_filt);
	free(img_data);
	return 0;
}