示例#1
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  int verbose = 0 ;
  char buffer [1024] ;
  int unsigned const bufferSize = sizeof(buffer)/sizeof(buffer[0]) ;

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

  VL_USE_MATLAB_ENV ;

  if (nout > 1) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
    case opt_verbose :
      ++ verbose ;
      break ;
    default:
      abort() ;
    }
  }

  if (verbose) {
    int offset = 0 ;
    char * string = vl_configuration_to_string_copy() ;
    offset = vl_string_copy(buffer, bufferSize, string) ;
    snprintf(buffer + offset, bufferSize - offset,
             "    SIMD enabled: %s\n", VL_YESNO(vl_get_simd_enabled())) ;
    if(string) vl_free(string) ;
  } else {
    snprintf(buffer, sizeof(buffer)/sizeof(buffer[0]),
             "%s", VL_VERSION_STRING) ;
  }

  if (nout == 0) {
    mexPrintf("%s\n", buffer) ;
  } else {
    out[0] = mxCreateString(buffer) ;
  }
}
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 */
}
示例#3
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 */
}
示例#4
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_DATA, IN_LABELS, IN_LAMBDA, IN_END} ;
  enum {OUT_MODEL = 0} ;

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

  double biasMultiplier = 0 ;
  double lambda ;
  void * data ;
  void * preconditioner = NULL ;
  vl_size preconditionerDimension = 0 ;
  mxClassID dataClass ;
  vl_type dataType ;
  vl_size numSamples ;
  vl_size dimension ;
  vl_size numIterations = 0 ;
  vl_uindex startingIteration = 1 ;
  vl_uint32 * permutation  = NULL ;
  vl_size permutationSize = 0 ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 3) {
    vlmxError(vlmxErrInvalidArgument,
              "At least three arguments are required.") ;
  } else if (nout > 2) {
    vlmxError(vlmxErrInvalidArgument,
              "Too many output arguments.");
  }

  dataClass = mxGetClassID(IN(DATA)) ;

  if (! vlmxIsMatrix (IN(DATA), -1, -1) ||
      ! vlmxIsReal (IN(DATA))) {
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be a real matrix.") ;
  }

  data = mxGetData (IN(DATA)) ;
  dimension = mxGetM(IN(DATA)) ;
  numSamples = mxGetN(IN(DATA)) ;

  switch (dataClass) {
  case mxSINGLE_CLASS : dataType = VL_TYPE_FLOAT ; break ;
  case mxDOUBLE_CLASS : dataType = VL_TYPE_DOUBLE ; break ;
  default:
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be either SINGLE or DOUBLE.") ;
  }

  if (mxGetClassID(IN(LABELS)) != mxINT8_CLASS) {
    vlmxError(vlmxErrInvalidArgument, "LABELS must be INT8.") ;
  }
  if (! vlmxIsVector(IN(LABELS), numSamples)) {
    vlmxError(vlmxErrInvalidArgument, "LABELS is not a vector of dimension compatible with DATA.") ;
  }

  if (! vlmxIsPlainScalar(IN(LAMBDA))) {
    vlmxError(vlmxErrInvalidArgument, "LAMBDA is not a plain scalar.") ;
  }
  lambda = *mxGetPr(IN(LAMBDA)) ;

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_bias_multiplier :
        if (!vlmxIsPlainScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "BIASMULTIPLIER is not a plain scalar.") ;
        }
        biasMultiplier = *mxGetPr(optarg) ;
        break ;

      case opt_num_iterations :
        if (!vlmxIsPlainScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "NUMITERATIONS is not a plain scalar.") ;
        }
        if (*mxGetPr(optarg) < 0) {
          vlmxError(vlmxErrInvalidArgument, "NUMITERATIONS is negative.") ;
        }
        numIterations = (vl_size) *mxGetPr(optarg) ;
        break ;

      case opt_starting_iteration :
        if (!vlmxIsPlainScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is not a plain scalar.") ;
        }
        if (*mxGetPr(optarg) < 1) {
          vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is smaller than 1.") ;
        }
        startingIteration = (vl_size) *mxGetPr(optarg) ;
        break ;

      case opt_starting_model :
        if (!vlmxIsVector(optarg, -1) ||
            mxIsComplex(optarg) ||
            !mxIsNumeric(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL is not a real vector.") ;
        }
        OUT(MODEL) = mxDuplicateArray(optarg) ;
        break ;

      case opt_permutation :
        if (!vlmxIsVector(optarg, -1) ||
            mxIsComplex(optarg) ||
            mxGetClassID(optarg) != mxUINT32_CLASS) {
          vlmxError(vlmxErrInvalidArgument, "PERMUTATION is not a UINT32 vector.") ;
        }
        permutationSize = mxGetNumberOfElements(optarg) ;
        permutation = mxMalloc(sizeof(vl_uint32) * permutationSize) ;
        {
          /* adjust indexing */
          vl_uint32 const * matlabPermutation = mxGetData(optarg) ;
          vl_uindex k ;
          for (k = 0 ; k < permutationSize ; ++k) {
            permutation[k] = matlabPermutation[k] - 1 ;
            if (permutation[k] >= numSamples) {
              vlmxError(vlmxErrInconsistentData,
                        "Permutation indexes out of bounds: PERMUTATION(%d) = %d > %d = number of data samples.",
                        k + 1, permutation[k] + 1, numSamples) ;
            }
          }
        }
        break ;

      case opt_preconditioner :
        if (!vlmxIsVector(optarg, -1) ||
            mxIsComplex(optarg) ||
            !mxIsNumeric(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "PRECONDITIONER is not a real vector.") ;
        }
        if (mxGetClassID(optarg) != dataClass) {
          vlmxError(vlmxErrInvalidArgument, "PRECODNITIONER storage class does not match the data.") ;
        }
        preconditioner = mxGetData(optarg) ;
        preconditionerDimension = mxGetNumberOfElements(optarg) ;
        break ;

      case opt_verbose :
        ++ verbose ;
        break ;
    }
  }

  if (preconditioner && preconditionerDimension != (dimension + (biasMultiplier > 0))) {
    vlmxError(vlmxErrInvalidArgument, "PRECONDITIONER has incompatible dimension.") ;
  }

  if (numIterations == 0) {
    numIterations = (vl_size) 10 / (lambda + 1) ;
  }

  if (! OUT(MODEL)) {
    OUT(MODEL) = mxCreateNumericMatrix(dimension + (biasMultiplier > 0),
                                       1,
                                       dataClass, mxREAL) ;
  } else {
    if (mxGetClassID(OUT(MODEL)) != dataClass) {
      vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL is not of the same class of DATA.") ;
    }
    if (mxGetNumberOfElements(OUT(MODEL)) != dimension + (biasMultiplier > 0)) {
      vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL has incompatible dimension.") ;
    }
  }

  if (verbose) {
    mexPrintf("vl_pegasos: Lambda = %g\n", lambda) ;
    mexPrintf("vl_pegasos: BiasMultiplier = %g\n", biasMultiplier) ;
    mexPrintf("vl_pegasos: NumIterations = %d\n", numIterations) ;
    mexPrintf("vl_pegasos: permutation size = %d\n", permutationSize) ;
    mexPrintf("vl_pegasos: using preconditioner = %s\n", VL_YESNO(preconditioner)) ;
  }

  switch (dataType) {
    case VL_TYPE_FLOAT :
      vl_pegasos_train_binary_svm_f((float *)mxGetData(OUT(MODEL)),
                                    (float const *)mxGetPr(IN(DATA)), dimension, numSamples,
                                    (vl_int8 const *)mxGetData(IN(LABELS)),
                                    lambda,
                                    biasMultiplier,
                                    startingIteration,
                                    numIterations,
                                    NULL,
                                    permutation,
                                    permutationSize,
                                    (float const*)preconditioner) ;
      break ;
    case VL_TYPE_DOUBLE:
      vl_pegasos_train_binary_svm_d((double *)mxGetData(OUT(MODEL)),
                                    (double const *)mxGetData(IN(DATA)), dimension, numSamples,
                                    (vl_int8 const *)mxGetData(IN(LABELS)),
                                    lambda,
                                    biasMultiplier,
                                    startingIteration,
                                    numIterations,
                                    NULL,
                                    permutation,
                                    permutationSize,
                                    (double const *)preconditioner) ;
      break ;
  }

  if (permutation) vl_free(permutation) ;

}
示例#5
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_DATA = 0, IN_END} ;
  enum {OUT_TREE = 0} ;

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

  VlKDForest * forest ;
  void * data ;
  vl_size numData ;
  vl_size dimension ;
  mxClassID dataClass ;
  vl_type dataType ;
  int thresholdingMethod = VL_KDTREE_MEDIAN ;
  vl_size numTrees = 1 ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 1) {
    vlmxError(vlmxErrInvalidArgument,
             "At least one argument required") ;
  } else if (nout > 2) {
    vlmxError(vlmxErrInvalidArgument,
             "Too many output arguments");
  }

  dataClass = mxGetClassID(IN(DATA)) ;

  if (! vlmxIsMatrix (IN(DATA), -1, -1) ||
      ! vlmxIsReal (IN(DATA))) {
    vlmxError(vlmxErrInvalidArgument,
             "DATA must be a real matrix ") ;
  }

  switch (dataClass) {
    case mxSINGLE_CLASS : dataType = VL_TYPE_FLOAT ; break ;
    case mxDOUBLE_CLASS : dataType = VL_TYPE_DOUBLE ; break ;
    default:
      vlmxError(vlmxErrInvalidArgument,
               "DATA must be either SINGLE or DOUBLE") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    char buffer [1024] ;
    switch (opt) {
      case opt_threshold_method :
        mxGetString (optarg, buffer, sizeof(buffer)/sizeof(buffer[0])) ;
        if (! vlmxIsString(optarg, -1)) {
          vlmxError(vlmxErrInvalidOption,
                   "THRESHOLDMETHOD must be a string") ;
        }
        if (vl_string_casei_cmp(buffer, "median") == 0) {
          thresholdingMethod = VL_KDTREE_MEDIAN ;
        } else if (vl_string_casei_cmp(buffer, "mean") == 0) {
          thresholdingMethod = VL_KDTREE_MEAN ;
        } else {
          vlmxError(vlmxErrInvalidOption,
                   "Unknown thresholding method %s", buffer) ;
        }
        break ;

      case opt_num_trees :
        if (! vlmxIsScalar(optarg) ||
            (numTrees = mxGetScalar(optarg)) < 1) {
          vlmxError(vlmxErrInvalidOption,
                   "NUMTREES must be not smaller than one") ;
        }
        break ;

      case opt_verbose :
        ++ verbose ;
        break ;
    }
  }

  data = mxGetData (IN(DATA)) ;
  numData = mxGetN (IN(DATA)) ;
  dimension = mxGetM (IN(DATA)) ;

  forest = vl_kdforest_new (dataType, dimension, numTrees) ;
  vl_kdforest_set_thresholding_method (forest, thresholdingMethod) ;

  if (verbose) {
    char const * str = 0 ;
    mexPrintf("vl_kdforestbuild: data %s [%d x %d]\n",
              vl_get_type_name (dataType), dimension, numData) ;
    switch (vl_kdforest_get_thresholding_method(forest)) {
      case VL_KDTREE_MEAN : str = "mean" ; break ;
      case VL_KDTREE_MEDIAN : str = "median" ; break ;
      default: abort() ;
    }
    mexPrintf("vl_kdforestbuild: threshold selection method: %s\n", str) ;
    mexPrintf("vl_kdforestbuild: number of trees: %d\n",
              vl_kdforest_get_num_trees(forest)) ;
  }

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

  vl_kdforest_build (forest, numData, data) ;

  if (verbose) {
    vl_uindex ti ;
    for (ti = 0 ; ti < vl_kdforest_get_num_trees(forest) ; ++ ti) {
      mexPrintf("vl_kdforestbuild: tree %d: depth %d, num nodes %d\n",
                ti,
                vl_kdforest_get_depth_of_tree(forest, ti),
                vl_kdforest_get_num_nodes_of_tree(forest, ti)) ;
    }
  }

  out[OUT_TREE] = new_array_from_kdforest (forest) ;
  vl_kdforest_delete (forest) ;
}
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {
    IN_I=0,     /* Input image */
    IN_KERNEL_SIZE,  /* The bandwidth parameter for density estimation */
    IN_MAX_DIST,     /* The maximum distance to a neighbor which increases
                   the density */
    IN_END
  } ;
  enum {
    OUT_PARENTS=0, /* parents (same size as I) */
    OUT_DISTS,     /* dists (same size as I) */
    OUT_DENSITY    /* density (same size as I) */
  } ;

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

  double const *I ;
  double *parents, *dists, *density ;
  int *parentsi;
  double sigma ;
  double tau ;

  int K,N1,N2;

  int medoid = 0 ;

  mwSize const *dims ;
  int ndims ;

  int i;

  VlQS * q;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 2) {
    mexErrMsgTxt("At least two arguments.") ;
  }

  if (nout > 3) {
    mexErrMsgTxt("At most three output arguments.") ;
  }

  ndims = mxGetNumberOfDimensions(in[IN_I]) ;
  dims  = mxGetDimensions(in[IN_I]) ;

  if (ndims > 3) {
    mexErrMsgTxt("I must have at most 3 dimensions.") ;
  }

  if (mxGetClassID(in[IN_I]) != mxDOUBLE_CLASS) {
    mexErrMsgTxt("I must be DOUBLE.")  ;
  }

  N1 = dims [0] ;
  N2 = dims [1] ;
  K = (ndims == 3) ? dims [2] : 1 ;

  I     =  mxGetPr (in[IN_I]) ;
  sigma = *mxGetPr (in[IN_KERNEL_SIZE]) ;
  tau   = 3*sigma;
  if (nin > 2)
    tau = *mxGetPr (in[IN_MAX_DIST]) ;

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
    case opt_medoid: /* Do medoid shift instead of mean shift */
      medoid = 1 ;
      break ;
    case opt_verbose :
      ++ verb ;
      break ;
    }
  } /* while opts */

  /* Create outputs */
  out[OUT_PARENTS] = mxCreateDoubleMatrix(N1, N2, mxREAL) ;
  parents          = mxGetPr (out[OUT_PARENTS]) ;

  out[OUT_DISTS]   = mxCreateDoubleMatrix(N1, N2, mxREAL) ;
  dists            = mxGetPr (out[OUT_DISTS]) ;

  out[OUT_DENSITY] = mxCreateDoubleMatrix(N1, N2, mxREAL) ;
  density          = mxGetPr (out[OUT_DENSITY]) ;

  if (verb) {
    mexPrintf("quickshift: [N1,N2,K]: [%d,%d,%d]\n", N1,N2,K) ;
    mexPrintf("quickshift: type: %s\n", medoid ? "medoid" : "quick");
    mexPrintf("quickshift: kernel size:  %g\n", sigma) ;
    mexPrintf("quickshift: maximum gap:  %g\n", tau) ;
  }

  /* Do job */
  q = vl_quickshift_new(I, N1, N2, K);

  vl_quickshift_set_kernel_size (q, sigma) ;
  vl_quickshift_set_max_dist     (q, tau) ;
  vl_quickshift_set_medoid      (q, medoid) ;

  vl_quickshift_process(q);

  parentsi = vl_quickshift_get_parents(q);
  /* Copy results */
  for(i = 0; i < N1*N2; i++) parents[i] = parentsi[i] + 1;
  memcpy(dists, vl_quickshift_get_dists(q), sizeof(double)*N1*N2);
  memcpy(density, vl_quickshift_get_density(q), sizeof(double)*N1*N2);

  /* Delete quick shift object */
  vl_quickshift_delete(q);
}
示例#7
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) ;
}
示例#8
0
/* driver */
void
mexFunction (int nout VL_UNUSED, mxArray * out[], int nin, const mxArray * in[])
{
  enum {IN_DATA = 0, IN_MEANS, IN_COVARIANCES, IN_PRIORS, IN_END} ;
  enum {OUT_ENC} ;

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

  vl_size numClusters = 10;
  vl_size dimension ;
  vl_size numData ;
  int flags = 0 ;

  void * covariances = NULL;
  void * means = NULL;
  void * priors = NULL;
  void * data = NULL ;

  int verbosity = 0 ;

  vl_type dataType ;
  mxClassID classID ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 4) {
    vlmxError (vlmxErrInvalidArgument,
               "At least four arguments required.");
  }
  if (nout > 1) {
    vlmxError (vlmxErrInvalidArgument,
               "At most one output argument.");
  }

  classID = mxGetClassID (IN(DATA)) ;
  switch (classID) {
    case mxSINGLE_CLASS: dataType = VL_TYPE_FLOAT ; break ;
    case mxDOUBLE_CLASS: dataType = VL_TYPE_DOUBLE ; break ;
    default:
      vlmxError (vlmxErrInvalidArgument,
                 "DATA is neither of class SINGLE or DOUBLE.") ;
  }

  if (mxGetClassID (IN(MEANS)) != classID) {
    vlmxError(vlmxErrInvalidArgument, "MEANS is not of the same class as DATA.") ;
  }
  if (mxGetClassID (IN(COVARIANCES)) != classID) {
    vlmxError(vlmxErrInvalidArgument, "COVARIANCES is not of the same class as DATA.") ;
  }
  if (mxGetClassID (IN(PRIORS)) != classID) {
    vlmxError(vlmxErrInvalidArgument, "PRIORS is not of the same class as DATA.") ;
  }

  dimension = mxGetM (IN(DATA)) ;
  numData = mxGetN (IN(DATA)) ;
  numClusters = mxGetN (IN(MEANS)) ;

  if (dimension == 0) {
    vlmxError (vlmxErrInvalidArgument, "SIZE(DATA,1) is zero.") ;
  }
  if (!vlmxIsMatrix(IN(MEANS), dimension, numClusters)) {
    vlmxError (vlmxErrInvalidArgument, "MEANS is not a matrix or does not have the right size.") ;
  }
  if (!vlmxIsMatrix(IN(COVARIANCES), dimension, numClusters)) {
    vlmxError (vlmxErrInvalidArgument, "COVARIANCES is not a matrix or does not have the right size.") ;
  }
  if (!vlmxIsVector(IN(PRIORS), numClusters)) {
    vlmxError (vlmxErrInvalidArgument, "PRIORS is not a vector or does not have the right size.") ;
  }
  if (!vlmxIsMatrix(IN(DATA), dimension, numData)) {
    vlmxError (vlmxErrInvalidArgument, "DATA is not a matrix or does not have the right size.") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_verbose : ++ verbosity ; break ;
      case opt_normalized: flags |= VL_FISHER_FLAG_NORMALIZED ; break ;
      case opt_square_root: flags |= VL_FISHER_FLAG_SQUARE_ROOT ; break ;
      case opt_improved: flags |= VL_FISHER_FLAG_IMPROVED ; break ;
      case opt_fast: flags |= VL_FISHER_FLAG_FAST ; break ;
      default : abort() ;
    }
  }

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

  data = mxGetPr(IN(DATA)) ;
  means = mxGetPr(IN(MEANS)) ;
  covariances = mxGetPr(IN(COVARIANCES)) ;
  priors = mxGetPr(IN(PRIORS)) ;

  if (verbosity) {
    mexPrintf("vl_fisher: num data: %d\n", numData) ;
    mexPrintf("vl_fisher: num clusters: %d\n", numClusters) ;
    mexPrintf("vl_fisher: data dimension: %d\n", dimension) ;
    mexPrintf("vl_fisher: code dimension: %d\n", numClusters * dimension) ;
    mexPrintf("vl_fisher: normalized: %s\n", VL_YESNO(flags & VL_FISHER_FLAG_NORMALIZED)) ;
    mexPrintf("vl_fisher: square root: %s\n", VL_YESNO(flags & VL_FISHER_FLAG_SQUARE_ROOT)) ;
    mexPrintf("vl_fisher: normalized: %s\n", VL_YESNO(flags & VL_FISHER_FLAG_NORMALIZED)) ;
    mexPrintf("vl_fisher: fast: %s\n", VL_YESNO(flags & VL_FISHER_FLAG_FAST)) ;
  }

  /* -------------------------------------------------------------- */
  /*                                                       Encoding */
  /* -------------------------------------------------------------- */

  OUT(ENC) = mxCreateNumericMatrix (dimension * numClusters * 2, 1, classID, mxREAL) ;

  vl_fisher_encode (mxGetData(OUT(ENC)), dataType,
                    means, dimension, numClusters,
                    covariances,
                    priors,
                    data, numData,
                    flags) ;
}
示例#9
0
/* driver */
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{

  typedef int  unsigned data_t ;

  /*  mxClassID data_class = mxINT8_CLASS ;*/
  enum {IN_S1,IN_S2} ;
  enum {OUT_D=0} ;
  vl_size L,N1,N2 ;
  vl_bool sparse = 0 ;
  void const * s1_pt ;
  void const * s2_pt ;
  mxClassID data_class ;
  mxClassID acc_class ;
  mwSize dims [2] ;

  /* for option parsing */
  bool           self = 1 ;      /* called with one numeric argument? */
  int            norm = opt_L2 ; /* type of norm to be computed       */
  int            opt ;
  int            next = 1 ;
  mxArray const *optarg ;

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

  if (nout > 1) {
    mexErrMsgTxt("Too many output arguments.");
  }

  if (nin < 1) {
    mexErrMsgTxt("At leat one argument required.") ;
  }

  if(! mxIsNumeric(in[IN_S1])) {
    mexErrMsgTxt ("X must be numeric") ;
  }

  if (nin >= 2 && mxIsNumeric(in[IN_S2])) {
    self = 0 ;
    next = 2 ;
  }

  sparse = mxIsSparse(in[IN_S1]) ;

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

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

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

    case opt_MIN :
      norm = opt ;
      break ;

    default:
      abort() ;
    }
  }

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

  assert ((! sparse) || (data_class == mxDOUBLE_CLASS)) ;

  L  = mxGetM(in[IN_S1]) ;
  N1 = mxGetN(in[IN_S1]) ;
  N2 = self ?  N1 : mxGetN(in[IN_S2]) ;

  dims[0] = N1 ;
  dims[1] = N2 ;

  if ((!self) && L != mxGetM(in[IN_S2])) {
    mexErrMsgTxt("X and Y must have the same number of rows") ;
  }

  s1_pt = mxGetData(in[IN_S1]) ;
  s2_pt = self ? s1_pt : mxGetData(in[IN_S2]) ;

#define DISPATCH_CLASS(NORM, DC,AC)                                     \
  case mx ## DC ## _CLASS :                                             \
    acc_class = mx ## AC ## _CLASS ;                                    \
  out[OUT_D] = mxCreateNumericArray(2,dims,acc_class,mxREAL) ;          \
  dist ## NORM ## _ ## DC ## _ ## AC                                    \
    ( (AC ## _t *)mxGetData(out[OUT_D]),                                \
      (DC ## _t *)s1_pt,                                                \
      (DC ## _t *)s2_pt,                                                \
      L, N1, N2,                                                        \
      self ) ;                                                          \
  break ;

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

  switch (norm) {
    DISPATCH_NORM(LINF ) ;
    DISPATCH_NORM(L2   ) ;
    DISPATCH_NORM(L1   ) ;
    DISPATCH_NORM(L0   ) ;
    DISPATCH_NORM(CHI2 ) ;
    DISPATCH_NORM(HELL ) ;

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

    DISPATCH_NORM(MIN  ) ;
  default:
    abort() ;
  }
}
示例#10
0
/* driver */
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{

  typedef int  unsigned data_t ;

  vl_bool autoComparison = VL_TRUE ;
  VlVectorComparisonType comparisonType = VlDistanceL2 ;

  enum {IN_X = 0, IN_Y} ;
  enum {OUT_D = 0} ;
  mwSize numDataX = 0 ;
  mwSize numDataY = 0 ;
  mwSize dimension ;
  mxClassID classId ;

  /* for option parsing */
  int opt ;
  int next ;
  mxArray const *optarg ;

  VL_USE_MATLAB_ENV ;

  if (nout > 1) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }
  if (nin < 1) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  }
  if (! (vlmxIsMatrix (in[IN_X],-1,-1) && vlmxIsReal(in[IN_X]))) {
    vlmxError(vlmxErrInvalidArgument, "X must be a real matrix.") ;
  }
  next = 1 ;
  classId = mxGetClassID(in[IN_X]) ;
  dimension = mxGetM(in[IN_X]) ;
  numDataX = mxGetN(in[IN_X]) ;

  if (nin > 1 && vlmxIsMatrix (in[IN_Y],-1,-1) && vlmxIsReal(in[IN_Y])) {
    next = 2 ;
    autoComparison = VL_FALSE ;
    numDataY = mxGetN(in[IN_Y]) ;
    if (mxGetClassID(in[IN_Y]) != classId) {
      vlmxError(vlmxErrInvalidArgument, "X and Y must have the same class.") ;
    }
    if (dimension != mxGetM(in[IN_Y])) {
      vlmxError(vlmxErrInvalidArgument, "X and Y must have the same number of rows.") ;
    }
  }

  if (classId != mxSINGLE_CLASS && classId != mxDOUBLE_CLASS) {
    vlmxError(vlmxErrInvalidArgument,
             "X must be either of class SINGLE or DOUBLE.");
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_L2    : comparisonType = VlDistanceL2 ; break ;
      case opt_L1    : comparisonType = VlDistanceL1 ; break ;
      case opt_CHI2  : comparisonType = VlDistanceChi2 ; break ;
      case opt_HELL  : comparisonType = VlDistanceHellinger ; break ;
      case opt_JS    : comparisonType = VlDistanceJS ; break ;
      case opt_KL2   : comparisonType = VlKernelL2 ; break ;
      case opt_KL1   : comparisonType = VlKernelL1 ; break ;
      case opt_KCHI2 : comparisonType = VlKernelChi2 ; break ;
      case opt_KHELL : comparisonType = VlKernelHellinger ; break ;
      case opt_KJS   : comparisonType = VlKernelJS ; break ;
      default:
        abort() ;
    }
  }

  /* allocate output */
  {
    mwSize dims [2] ;
    dims[0] = numDataX ;
    dims[1] = autoComparison ? numDataX : numDataY ;
    out[OUT_D] = mxCreateNumericArray (2, dims, classId, mxREAL) ;
  }

  /* If either numDataX or numDataY are null, their data pointers are
     null as well. This may confuse
     vl_eval_vector_comparison_on_all_pairs_*, so we intercept this as
     a special case. The same is true if dimension is null.
  */

  if (numDataX == 0 || (! autoComparison && numDataY == 0)) {
    return ;
  }
  if (dimension == 0) {
    return ;
  }

  /* make calculation */
  switch (classId) {
  case mxSINGLE_CLASS:
    {
      VlFloatVectorComparisonFunction f = vl_get_vector_comparison_function_f (comparisonType) ;
      if (autoComparison) {
        vl_eval_vector_comparison_on_all_pairs_f ((float*)mxGetData(out[OUT_D]),
                                                  dimension,
                                                  (float*)mxGetData(in[IN_X]), numDataX,
                                                  0, 0,
                                                  f) ;
      } else {
        vl_eval_vector_comparison_on_all_pairs_f ((float*)mxGetData(out[OUT_D]),
                                                  dimension,
                                                  (float*)mxGetData(in[IN_X]), numDataX,
                                                  (float*)mxGetData(in[IN_Y]), numDataY,
                                                  f) ;
      }
    }
    break ;

    case mxDOUBLE_CLASS:
    {
      VlDoubleVectorComparisonFunction f = vl_get_vector_comparison_function_d (comparisonType) ;
      if (autoComparison) {
        vl_eval_vector_comparison_on_all_pairs_d ((double*)mxGetData(out[OUT_D]),
                                                  dimension,
                                                  (double*)mxGetData(in[IN_X]), numDataX,
                                                  0, 0,
                                                  f) ;
      } else {
        vl_eval_vector_comparison_on_all_pairs_d ((double*)mxGetData(out[OUT_D]),
                                                  dimension,
                                                  (double*)mxGetData(in[IN_X]), numDataX,
                                                  (double*)mxGetData(in[IN_Y]), numDataY,
                                                  f) ;
      }
    }
    break ;

  default:
    abort() ;
  }
}
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 */
}
示例#12
0
/** @brief MEX driver entry point
 **/
void mexFunction (int nout, mxArray * out[], int nin, const mxArray * in[])
{
  enum {IN_TREE = 0, IN_DATA, IN_END} ;
  enum {OUT_ASGN = 0} ;
  vl_uint8 const *data;

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

  int N = 0 ;
  int method_type = VL_IKM_LLOYD ;
  int verb = 0 ;

  /* -----------------------------------------------------------------
   *                                               Check the arguments
   * -------------------------------------------------------------- */
  if (nin < 2)
    mexErrMsgTxt ("At least two arguments required.");
  else if (nout > 1)
    mexErrMsgTxt ("Too many output arguments.");

  if (mxGetClassID (in[IN_DATA]) != mxUINT8_CLASS) {
    mexErrMsgTxt ("DATA must be of class UINT8");
  }

  N = mxGetN (in[IN_DATA]);   /* n of elements */
  data = (vl_uint8 *) mxGetPr (in[IN_DATA]);

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    char buf [1024] ;

    switch (opt) {

    case opt_verbose :
      ++ verb ;
      break ;

    case opt_method :
      if (!vlmxIsString (optarg, -1)) {
        mexErrMsgTxt("'Method' must be a string.") ;
      }
      if (mxGetString (optarg, buf, sizeof(buf))) {
        mexErrMsgTxt("Option argument too long.") ;
      }
      if (strcmp("lloyd", buf) == 0) {
        method_type = VL_IKM_LLOYD ;
      } else if (strcmp("elkan", buf) == 0) {
        method_type = VL_IKM_ELKAN ;
      } else {
        mexErrMsgTxt("Unknown cost type.") ;
      }

      break ;

    default :
      abort() ;
    }
  }

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

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

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

    if (verb) {
      mexPrintf("hikmeanspush: ndims: %d K: %d depth: %d\n",
                vl_hikm_get_ndims (tree),
                vl_hikm_get_K (tree),
                depth) ;
    }

    out[OUT_ASGN] = mxCreateNumericMatrix (depth, N, mxUINT32_CLASS, mxREAL) ;
    ids = mxGetData (out[OUT_ASGN]) ;

    vl_hikm_push   (tree, ids, data, N) ;
    vl_hikm_delete (tree) ;

    for (j = 0 ; j < N*depth ; j++) ids [j] ++ ;
  }
}
示例#13
0
文件: vl_dsift.c 项目: 19test/sandbox
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 ;

  float const *data ;
  int M, N ;

  int step [2] = {1,1} ;
  vl_bool norm = 0 ;

  vl_bool floatDescriptors = VL_FALSE ;
  vl_bool useFlatWindow = VL_FALSE ;
  double windowSize = -1.0 ;

  double *bounds = NULL ;
  double boundBuffer [4] ;
  VlDsiftDescriptorGeometry geom ;

  VL_USE_MATLAB_ENV ;

  geom.numBinX = 4 ;
  geom.numBinY = 4 ;
  geom.numBinT = 8 ;
  geom.binSizeX = 3 ;
  geom.binSizeY = 3 ;

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

  if (nin < 1) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  } else if (nout > 2) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }

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

  data = (float*) 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_fast :
        useFlatWindow = 1 ;
        break ;

      case opt_norm :
        norm = 1 ;
        break ;

      case opt_bounds :
        if (!vlmxIsPlainVector(optarg, 4)) {
          mexErrMsgTxt("BOUNDS must be a 4-dimensional vector.") ;
        }
        bounds = boundBuffer ;
        bounds [0] = mxGetPr(optarg)[0] - 1 ;
        bounds [1] = mxGetPr(optarg)[1] - 1 ;
        bounds [2] = mxGetPr(optarg)[2] - 1 ;
        bounds [3] = mxGetPr(optarg)[3] - 1 ;
        break ;

      case opt_size :
        if (!vlmxIsPlainVector(optarg,-1)) {
          vlmxError(vlmxErrInvalidArgument,"SIZE is not a plain vector.") ;
        }
        if (mxGetNumberOfElements(optarg) == 1) {
          geom.binSizeX = (int) mxGetPr(optarg)[0] ;
          geom.binSizeY = (int) mxGetPr(optarg)[0] ;
        } else if (mxGetNumberOfElements(optarg) == 2) {
          geom.binSizeX = (int) mxGetPr(optarg)[1] ;
          geom.binSizeY = (int) mxGetPr(optarg)[0] ;
        } else {
          vlmxError(vlmxErrInvalidArgument,"SIZE is neither a scalar or a 2D vector.") ;
        }
        if (geom.binSizeX < 1 || geom.binSizeY < 1) {
          vlmxError(vlmxErrInvalidArgument,"SIZE value is invalid.") ;
        }
        break ;

      case opt_step :
        if (!vlmxIsPlainVector(optarg,-1)) {
          vlmxError(vlmxErrInvalidArgument,"STEP is not a plain vector.") ;
        }
        if (mxGetNumberOfElements(optarg) == 1) {
          step[0] = (int) mxGetPr(optarg)[0] ;
          step[1] = (int) mxGetPr(optarg)[0] ;
        } else if (mxGetNumberOfElements(optarg) == 2) {
          step[0] = (int) mxGetPr(optarg)[1] ;
          step[1] = (int) mxGetPr(optarg)[0] ;
        } else {
          vlmxError(vlmxErrInvalidArgument,"STEP is neither a scalar or a 2D vector.") ;
        }
        if (step[0] < 1 || step[1] < 1) {
          vlmxError(vlmxErrInvalidArgument,"STEP value is invalid.") ;
        }
        break ;

      case opt_window_size :
        if (!vlmxIsPlainScalar(optarg) || (windowSize = *mxGetPr(optarg)) < 0) {
          vlmxError(vlmxErrInvalidArgument,"WINDOWSIZE is not a scalar or it is negative.") ;
        }
        break ;

      case opt_float_descriptors :
        floatDescriptors = VL_TRUE ;
        break ;

      case opt_geometry :
        if (!vlmxIsPlainVector(optarg,3)) {
          vlmxError(vlmxErrInvalidArgument, "GEOMETRY is not a 3D vector.") ;
        }
        geom.numBinY = (int)mxGetPr(optarg)[0] ;
        geom.numBinX = (int)mxGetPr(optarg)[1] ;
        geom.numBinT = (int)mxGetPr(optarg)[2] ;
        if (geom.numBinX < 1 ||
            geom.numBinY < 1 ||
            geom.numBinT < 1) {
          vlmxError(vlmxErrInvalidArgument, "GEOMETRY value is invalid.") ;
        }
        break ;

      default :
        abort() ;
    }
  }

  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  {
    int numFrames ;
    int descrSize ;
    VlDsiftKeypoint const *frames ;
    float const *descrs ;
    int k, i ;

    VlDsiftFilter *dsift ;

    /* note that the image received from MATLAB is transposed */
    dsift = vl_dsift_new (M, N) ;
    vl_dsift_set_geometry(dsift, &geom) ;
    vl_dsift_set_steps(dsift, step[0], step[1]) ;

    if (bounds) {
      vl_dsift_set_bounds(dsift,
                          VL_MAX(bounds[1], 0),
                          VL_MAX(bounds[0], 0),
                          VL_MIN(bounds[3], M - 1),
                          VL_MIN(bounds[2], N - 1));
    }
    vl_dsift_set_flat_window(dsift, useFlatWindow) ;

    if (windowSize >= 0) {
      vl_dsift_set_window_size(dsift, windowSize) ;
    }

    numFrames = vl_dsift_get_keypoint_num (dsift) ;
    descrSize = vl_dsift_get_descriptor_size (dsift) ;
    geom = *vl_dsift_get_geometry (dsift) ;

    if (verbose) {
      int stepX ;
      int stepY ;
      int minX ;
      int minY ;
      int maxX ;
      int maxY ;
      vl_bool useFlatWindow ;

      vl_dsift_get_steps (dsift, &stepY, &stepX) ;
      vl_dsift_get_bounds (dsift, &minY, &minX, &maxY, &maxX) ;
      useFlatWindow = vl_dsift_get_flat_window(dsift) ;

      mexPrintf("vl_dsift: image size         [W, H] = [%d, %d]\n", N, M) ;
      mexPrintf("vl_dsift: bounds:            [minX,minY,maxX,maxY] = [%d, %d, %d, %d]\n",
                minX+1, minY+1, maxX+1, maxY+1) ;
      mexPrintf("vl_dsift: subsampling steps: stepX=%d, stepY=%d\n", stepX, stepY) ;
      mexPrintf("vl_dsift: num bins:          [numBinT, numBinX, numBinY] = [%d, %d, %d]\n",
                geom.numBinT,
                geom.numBinX,
                geom.numBinY) ;
      mexPrintf("vl_dsift: descriptor size:   %d\n", descrSize) ;
      mexPrintf("vl_dsift: bin sizes:         [binSizeX, binSizeY] = [%d, %d]\n",
                geom.binSizeX,
                geom.binSizeY) ;
      mexPrintf("vl_dsift: flat window:       %s\n", VL_YESNO(useFlatWindow)) ;
      mexPrintf("vl_dsift: window size:       %g\n", vl_dsift_get_window_size(dsift)) ;
      mexPrintf("vl_dsift: num of features:   %d\n", numFrames) ;
    }

    vl_dsift_process (dsift, data) ;

    frames = vl_dsift_get_keypoints (dsift) ;
    descrs = vl_dsift_get_descriptors (dsift) ;

    /* ---------------------------------------------------------------
     *                                            Create output arrays
     * ------------------------------------------------------------ */
    {
      mwSize dims [2] ;

      dims [0] = descrSize ;
      dims [1] = numFrames ;

      if (floatDescriptors) {
        out[OUT_DESCRIPTORS] = mxCreateNumericArray
        (2, dims, mxSINGLE_CLASS, mxREAL) ;
      } else {
        out[OUT_DESCRIPTORS] = mxCreateNumericArray
        (2, dims, mxUINT8_CLASS, mxREAL) ;
      }

      dims [0] = norm ? 3 : 2 ;

      out[OUT_FRAMES] = mxCreateNumericArray
      (2, dims, mxDOUBLE_CLASS, mxREAL) ;
    }

    /* ---------------------------------------------------------------
     *                                                       Copy back
     * ------------------------------------------------------------ */
    {
      float *tmpDescr = mxMalloc(sizeof(float) * descrSize) ;
      double *outFrameIter = mxGetPr(out[OUT_FRAMES]) ;
      void *outDescrIter = mxGetData(out[OUT_DESCRIPTORS]) ;
      for (k = 0 ; k < numFrames ; ++k) {
        *outFrameIter++ = frames[k].y + 1 ;
        *outFrameIter++ = frames[k].x + 1 ;

        /* We have an implied / 2 in the norm, because of the clipping
           below */
        if (norm)
          *outFrameIter++ = frames [k].norm ;

        vl_dsift_transpose_descriptor (tmpDescr,
                                       descrs + descrSize * k,
                                       geom.numBinT,
                                       geom.numBinX,
                                       geom.numBinY) ;

        if (floatDescriptors) {
          for (i = 0 ; i < descrSize ; ++i) {
            float * pt = (float*) outDescrIter ;
            *pt++ = VL_MIN(512.0F * tmpDescr[i], 255.0F) ;
            outDescrIter = pt ;
          }
        } else {
          for (i = 0 ; i < descrSize ; ++i) {
            vl_uint8 * pt = (vl_uint8*) outDescrIter ;
            *pt++ = (vl_uint8) (VL_MIN(512.0F * tmpDescr[i], 255.0F)) ;
            outDescrIter = pt ;

          }
        }
      }
      mxFree(tmpDescr) ;
    }
    vl_dsift_delete (dsift) ;
  }
}
示例#14
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_FOREST = 0, IN_DATA, IN_QUERY, IN_END} ;
  enum {OUT_INDEX = 0, OUT_DISTANCE} ;

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

  VlKDForest * forest ;
  mxArray const * forest_array = in[IN_FOREST] ;
  mxArray const * data_array = in[IN_DATA] ;
  mxArray const * query_array = in[IN_QUERY] ;
  void * query ;
  vl_uint32 * index ;
  void * distance ;
  vl_size numNeighbors = 1 ;
  vl_size numQueries ;
  unsigned int numComparisons = 0 ;
  unsigned int maxNumComparisons = 0 ;
  mxClassID dataClass ;
  vl_index i ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 3) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  }
  if (nout > 2) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }

  forest = new_kdforest_from_array (forest_array, data_array) ;

  dataClass = mxGetClassID (data_array) ;
  if (mxGetClassID (query_array) != dataClass) {
    vlmxError(vlmxErrInvalidArgument,
              "QUERY must have the same storage class as DATA.") ;
  }
  if (! vlmxIsReal (query_array)) {
    vlmxError(vlmxErrInvalidArgument,
              "QUERY must be real.") ;
  }
  if (! vlmxIsMatrix (query_array, forest->dimension, -1)) {
    vlmxError(vlmxErrInvalidArgument,
              "QUERY must be a matrix with TREE.NUMDIMENSIONS rows.") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_num_neighs :
        if (! vlmxIsScalar(optarg) ||
            (numNeighbors = mxGetScalar(optarg)) < 1) {
          vlmxError(vlmxErrInvalidArgument,
                    "NUMNEIGHBORS must be a scalar not smaller than one.") ;
        }
        break;

      case opt_max_num_comparisons :
        if (! vlmxIsScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument,
                    "MAXNUMCOMPARISONS must be a scalar.") ;
        }
        maxNumComparisons = mxGetScalar(optarg) ;
        break;

      case opt_verbose :
        ++ verbose ;
        break ;
    }
  }

  vl_kdforest_set_max_num_comparisons (forest, maxNumComparisons) ;

  query = mxGetData (query_array) ;
  numQueries = mxGetN (query_array) ;

  out[OUT_INDEX] = mxCreateNumericMatrix (numNeighbors, numQueries, mxUINT32_CLASS, mxREAL) ;
  out[OUT_DISTANCE] = mxCreateNumericMatrix (numNeighbors, numQueries, dataClass, mxREAL) ;

  index = mxGetData (out[OUT_INDEX]) ;
  distance = mxGetData (out[OUT_DISTANCE]) ;

  if (verbose) {
    VL_PRINTF ("vl_kdforestquery: number of queries: %d\n", numQueries) ;
    VL_PRINTF ("vl_kdforestquery: number of neighbors per query: %d\n", numNeighbors) ;
    VL_PRINTF ("vl_kdforestquery: max num of comparisons per query: %d\n",
               vl_kdforest_get_max_num_comparisons (forest)) ;
  }

  numComparisons = vl_kdforest_query_with_array (forest, index, numNeighbors, numQueries, distance, query) ;
  
  vl_kdforest_delete(forest) ;
  
  /* adjust for MATLAB indexing */
  for (i = 0 ; i < (signed) (numNeighbors * numQueries) ; ++i) { index[i] ++ ; }

  if (verbose) {
    VL_PRINTF ("vl_kdforestquery: number of comparisons per query: %.3f\n",
               ((double) numComparisons) / numQueries) ;
    VL_PRINTF ("vl_kdforestquery: number of comparisons per neighbor: %.3f\n",
               ((double) numComparisons) / (numQueries * numNeighbors)) ;
  }
}
示例#15
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_PCX = 0, IN_END} ;
  enum {OUT_PARENTS = 0, OUT_COST} ;
  enum {INFORMATION, EC} ;

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

  double   *Pcx     ;
  vl_uint32    nlabels ;
  vl_uint32    nvalues ;

  mxArray *Pcx_cpy ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 1) {
    mexErrMsgTxt("One argument required.") ;
  } else if (nout > 2) {
    mexErrMsgTxt("Too many output arguments.");
  }

  if (!vlmxIsMatrix(in[IN_PCX], -1, -1)) {
    mexErrMsgTxt("PCX must be a real matrix.") ;
  }

  Pcx_cpy = mxDuplicateArray(in[IN_PCX]);
  Pcx     = mxGetPr (Pcx_cpy) ;
  nlabels = mxGetM  (in[IN_PCX]) ;
  nvalues = mxGetN  (in[IN_PCX]) ;

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

    switch (opt) {

    case opt_verbose :
      ++ verbose ;
      break ;

    case opt_cluster_null :
      cluster_null = 1 ;
      break ;

    }
  }

  if (verbose) {
    mexPrintf("aib: cluster null:    %d", cluster_null) ;
  }

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

  {
    VlAIB   *aib;
    double* acost = 0, *cost = 0 ;
    vl_uint32 *aparents = 0, *parents = 0 ;
    vl_uint32 n ;

    out[OUT_PARENTS] = mxCreateNumericMatrix(1, 2*nvalues - 1, mxUINT32_CLASS, mxREAL);
    parents = mxGetData(out[OUT_PARENTS]);

    if (nout > 1) {
      out[OUT_COST] = mxCreateNumericMatrix(1, nvalues, mxDOUBLE_CLASS, mxREAL);
      cost = mxGetPr(out[OUT_COST]);
    }

    aib = vl_aib_new (Pcx, nvalues, nlabels) ;
    vl_aib_process (aib);

    aparents = vl_aib_get_parents (aib);
    acost    = vl_aib_get_costs (aib);
    memcpy(parents, aparents, sizeof(vl_uint32)*(2*nvalues-1));
    if (nout > 1)
      memcpy(cost, acost, sizeof(double)*nvalues);

    vl_aib_delete(aib);

    if (cluster_null) {
      cluster_null_nodes (parents, nvalues, (nout == 0) ? 0 : cost) ;
    }

    /* save back parents */
    for (n = 0 ; n < 2 * nvalues - 1 ; ++n) {
      if (parents [n] > 2 * nvalues - 1) {
        /* map ingored nodes to zero */
        parents [n] = 0 ;
      } else {
        /* MATLAB starts counting from 1 */
        ++ parents [n]  ;
      }
    }

  }
  mxDestroyArray(Pcx_cpy);
}
示例#16
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_DATA, IN_LABELS, IN_LAMBDA, IN_END} ;
  enum {OUT_MODEL = 0, OUT_BIAS, OUT_INFO} ;

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

  mxArray *inputModel = NULL;
  VlSvmPegasos* svm = NULL ;

  vl_bool freeModel = VL_TRUE ;
  vl_size dataDimension ;

  vl_uint32* matlabPermutation ;

  void * data ;
  mxClassID dataClass ;
  vl_type dataType ;
  vl_size numSamples ;

  vl_uint32 * permutation  = NULL ;
  vl_size permutationSize = 0 ;

  DiagnosticsDispatcher* disp ;
  VlSvmDatasetInnerProduct innerProduct = NULL ;
  VlSvmDatasetAccumulator accumulator = NULL ;

  /* maps */
  VlSvmDatasetFeatureMap mapFunc  = NULL ;

  /* Homkermap */
  VlHomogeneousKernelType kernelType = VlHomogeneousKernelChi2 ;
  VlHomogeneousKernelMapWindowType windowType = VlHomogeneousKernelMapWindowRectangular ;
  double gamma = 1.0 ;
  int n = 0 ;
  double period = -1 ;

  VlSvmDataset* dataset ;

  vl_bool homkermap = VL_FALSE ;
  void * map = NULL ;

  VL_USE_MATLAB_ENV ;

  disp = (DiagnosticsDispatcher*) vl_malloc(sizeof(DiagnosticsDispatcher)) ;
  disp->diagnosticsHandle = NULL ;
  disp->callerRef = NULL ;
  disp->verbose = 0 ;

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

  if (nin < 3) {
    vlmxError(vlmxErrInvalidArgument,
              "At least three arguments are required.") ;
  } else if (nout > 3) {
    vlmxError(vlmxErrInvalidArgument,
              "Too many output arguments.");
  }

  dataClass = mxGetClassID(IN(DATA)) ;

  if (! vlmxIsMatrix (IN(DATA), -1, -1) ||
      ! vlmxIsReal (IN(DATA))) {
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be a real matrix.") ;
  }

  data = mxGetData (IN(DATA)) ;
  dataDimension = mxGetM(IN(DATA)) ;
  numSamples = mxGetN(IN(DATA)) ;

  /* Get order of the HOMKERMAP, if used. */
  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    if  (opt == opt_homkermap) {
      homkermap = VL_TRUE ;
      if (! vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "N is not a scalar.") ;
      }
      n = *mxGetPr(optarg) ;
      if (n < 0) {
        vlmxError(vlmxErrInvalidArgument, "N is negative.") ;
      }
    }
  }

  next = IN_END ;

  if (! vlmxIsVector(IN(LABELS), numSamples)) {
    vlmxError(vlmxErrInvalidArgument, "LABELS is not a vector of dimension compatible with DATA.") ;
  }


  switch (dataClass) {
  case mxSINGLE_CLASS : dataType = VL_TYPE_FLOAT ; break ;
  case mxDOUBLE_CLASS : dataType = VL_TYPE_DOUBLE ; break ;
  default:
    vlmxError(vlmxErrInvalidArgument,
              "DATA must be either SINGLE or DOUBLE.") ;
  }

  if (mxGetClassID(IN(LABELS)) != mxINT8_CLASS) {
    vlmxError(vlmxErrInvalidArgument, "LABELS must be INT8.") ;
  }


  if (! vlmxIsPlainScalar(IN(LAMBDA))) {
    vlmxError(vlmxErrInvalidArgument, "LAMBDA is not a plain scalar.") ;
  }

  svm = vl_svmpegasos_new ((2*n + 1)*dataDimension,*mxGetPr(IN(LAMBDA))) ;

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
    case opt_bias_multiplier :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "BIASMULTIPLIER is not a plain scalar.") ;
      }
      vl_svmpegasos_set_bias_multiplier(svm, *mxGetPr(optarg)) ;
      break ;

    case opt_max_iterations :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "MAXITERATIONS is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 0) {
        vlmxError(vlmxErrInvalidArgument, "MAXITERATIONS is negative.") ;
      }
      vl_svmpegasos_set_maxiterations(svm, (vl_size) *mxGetPr(optarg)) ;
      break ;

    case opt_epsilon :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "EPSILON is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 0) {
        vlmxError(vlmxErrInvalidArgument, "EPSILON is negative.") ;
      }
      vl_svmpegasos_set_epsilon(svm, (double) *mxGetPr(optarg)) ;
      break ;

    case opt_starting_iteration :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is not a plain scalar.") ;
      }
      if (*mxGetPr(optarg) < 1) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGITERATION is smaller than 1.") ;
      }
      vl_svmpegasos_set_iterations(svm, (vl_size) *mxGetPr(optarg) - 1) ;
      break ;

    case opt_starting_model :
      if (!vlmxIsVector(optarg, -1) ||
          mxIsComplex(optarg) ||
          mxGetClassID(optarg) != mxDOUBLE_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGMODEL is not a real vector.") ;
      }
      inputModel = mxDuplicateArray(optarg) ;
      vl_svmpegasos_set_model(svm,(double*) mxGetData(inputModel)) ;
      freeModel = VL_FALSE ;
      break ;

    case opt_starting_bias :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "STARTINGBIAS is not a plain scalar.") ;
      }
      vl_svmpegasos_set_bias(svm, (double) *mxGetPr(optarg)) ;
      break ;

    case opt_permutation :
      if (!vlmxIsVector(optarg, -1) ||
          mxIsComplex(optarg) ||
          mxGetClassID(optarg) != mxUINT32_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "PERMUTATION is not a UINT32 vector.") ;
      }
      permutationSize = mxGetNumberOfElements(optarg) ;
      permutation = mxMalloc(sizeof(vl_uint32) * permutationSize) ;
      matlabPermutation = mxGetData(optarg) ;
      {
        /* adjust indexing */
        vl_uindex k ;
        for (k = 0 ; k < permutationSize ; ++k) {
          permutation[k] = matlabPermutation[k] - 1 ;
          if (permutation[k] >= numSamples) {
            vlmxError(vlmxErrInconsistentData,
                      "Permutation indexes out of bounds: PERMUTATION(%d) = %d > %d = number of data samples.",
                      k + 1, permutation[k] + 1, numSamples) ;
          }
        }
      }
      vl_svmpegasos_set_permutation(svm,permutation,permutationSize) ;
      break ;

    case opt_bias_learningrate :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "BIASLEARNINGRATE is not a plain scalar.") ;
      }
      if (mxGetClassID(optarg) != mxDOUBLE_CLASS) {
        vlmxError(vlmxErrInvalidArgument, "BIASLEARNINGRATE must be double.") ;
      }
      vl_svmpegasos_set_bias_learningrate(svm, (double)*mxGetPr(optarg)) ;
      break ;
    case opt_diagnostic :

      if( !mxIsClass( optarg , "function_handle")) {
        mexErrMsgTxt("DIAGNOSTICSFUNCTION must be  a function handle.");
      }
      disp->diagnosticsHandle = (mxArray*)(optarg) ;
      break ;

    case opt_diagnostic_caller_ref :
      disp->callerRef = (mxArray*)(optarg) ;
      break ;

    case opt_energy_freq :
      if (!vlmxIsPlainScalar(optarg)) {
        vlmxError(vlmxErrInvalidArgument, "ENERGYFREQ is not a plain scalar.") ;
      }
      vl_svmpegasos_set_energy_frequency (svm, (vl_size)*mxGetPr(optarg)) ;
      break ;

    case opt_verbose :
      ++ verbose ;
      disp->verbose = 1 ;
      break ;

    case opt_KINTERS:
    case opt_KL1:
      kernelType = VlHomogeneousKernelIntersection ;
      break ;

    case opt_KCHI2:
      kernelType = VlHomogeneousKernelChi2 ;
      break ;

    case opt_KJS:
      kernelType = VlHomogeneousKernelJS ;
      break ;

    case opt_period:
      if (! vlmxIsPlainScalar(optarg)){
        vlmxError(vlmxErrInvalidArgument, "PERIOD is not a scalar.") ;
      }
      period = *mxGetPr(optarg) ;
      if (period <= 0) {
        vlmxError(vlmxErrInvalidArgument, "PERIOD is not positive.") ;
      }
      break ;

    case opt_gamma:
      if (! vlmxIsPlainScalar(optarg)){
        vlmxError(vlmxErrInvalidArgument, "GAMMA is not a scalar.") ;
      }
      gamma = *mxGetPr(optarg) ;
      if (gamma <= 0) {
        vlmxError(vlmxErrInvalidArgument, "GAMMA is not positive.") ;
      }
      break ;

    case opt_window:
      if (! vlmxIsString(optarg,-1)){
        vlmxError(vlmxErrInvalidArgument, "WINDOW is not a string.") ;
      } else {
        char buffer [1024] ;
        mxGetString(optarg, buffer, sizeof(buffer) / sizeof(char)) ;
        if (vl_string_casei_cmp("uniform", buffer) == 0) {
          windowType = VlHomogeneousKernelMapWindowUniform ;
        } else if (vl_string_casei_cmp("rectangular", buffer) == 0) {
          windowType = VlHomogeneousKernelMapWindowRectangular ;
        } else {
          vlmxError(vlmxErrInvalidArgument, "WINDOW=%s is not recognized.", buffer) ;
        }
      }
      break ;
    }
  }

  if (verbose) {
    mexPrintf("vl_pegasos: Lambda = %g\n", svm->lambda) ;
    mexPrintf("vl_pegasos: BiasMultiplier = %g\n", svm->biasMultiplier) ;
    mexPrintf("vl_pegasos: MaxIterations = %d\n", svm->maxIterations) ;
    mexPrintf("vl_pegasos: permutation size = %d\n", permutationSize) ;
  }

  switch (dataType) {
  case VL_TYPE_FLOAT :
    innerProduct = (VlSvmDatasetInnerProduct)&vl_svmdataset_innerproduct_f ;
    accumulator = (VlSvmDatasetAccumulator)&vl_svmdataset_accumulator_f ;
    break ;
  case VL_TYPE_DOUBLE:
    innerProduct = (VlSvmDatasetInnerProduct)&vl_svmdataset_innerproduct_d ;
    accumulator = (VlSvmDatasetAccumulator)&vl_svmdataset_accumulator_d ;
    break ;
  }

  dataset = vl_svmdataset_new(data,dataDimension) ;
  if (homkermap) {
    map = vl_homogeneouskernelmap_new (kernelType, gamma, n, period, windowType) ;
    mapFunc = (VlSvmDatasetFeatureMap)&vl_homogeneouskernelmap_evaluate_d ;
    vl_svmdataset_set_map(dataset,map,mapFunc,2*n + 1) ;
  }

  /* -----------------------------------------------------------------
   *                                                            Do job
   * -------------------------------------------------------------- */
  if (disp->diagnosticsHandle) {
    vl_svmpegasos_set_diagnostic (svm, (VlSvmDiagnostics)&diagnosticDispatcher, disp) ;
  }

  vl_svmpegasos_train (svm,dataset, numSamples,innerProduct, accumulator,
                       (vl_int8 const *)mxGetData(IN(LABELS))) ;

  /* -----------------------------------------------------------------
   *                                                            Output
   * -------------------------------------------------------------- */

  if (nout >= 1) {
    double * tempBuffer ;
    mwSize dims[2] ;
    dims[0] = svm->dimension ;
    dims[1] = 1 ;
    out[OUT_MODEL] = mxCreateNumericArray(2, dims,
                                          mxDOUBLE_CLASS, mxREAL) ;
    tempBuffer  = (double*) mxGetData(out[OUT_MODEL]) ;
    memcpy(tempBuffer,svm->model,svm->dimension * sizeof(double)) ;
  }

  if (nout >= 2) {
    double * tempBuffer ;
    mwSize dims[2] ;
    dims[0] = 1 ;
    dims[1] = 1 ;

    out[OUT_BIAS] = mxCreateNumericArray(2, dims,
                                         mxDOUBLE_CLASS, mxREAL) ;
    tempBuffer = (double*) mxGetData(out[OUT_BIAS]) ;
    *tempBuffer = svm->bias ;
  }

  if (nout == 3) {
    out[OUT_INFO] = createInfoStruct(svm) ;
  }

  if (homkermap) {
    vl_homogeneouskernelmap_delete(map);
  }
  vl_svmdataset_delete(dataset) ;
  vl_svmpegasos_delete(svm,freeModel) ;
  vl_free(disp) ;
}
示例#17
0
/** ------------------------------------------------------------------
 ** @internal
 ** @brief MEX driver
 **/
void mexFunction (int nout, mxArray * out[], int nin, const mxArray * in[])
{
  vl_uint8 *data ;
  enum {IN_DATA = 0, IN_K, IN_NLEAVES, IN_END} ;
  enum {OUT_TREE = 0, OUT_ASGN} ;
  int M, N, K = 2, depth = 0 ;

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

  int nleaves     = 1 ;
  int method_type = VL_IKM_LLOYD ;
  int max_niters  = 200 ;
  int verb        = 0 ;

  VlHIKMTree* tree ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 3)
    {
      mexErrMsgTxt ("At least three arguments required.");
    }
  else if (nout > 2)
    {
      mexErrMsgTxt ("Too many output arguments.");
    }

  if (mxGetClassID (in[IN_DATA]) != mxUINT8_CLASS)
    {
      mexErrMsgTxt ("DATA must be of class UINT8.");
    }

  if (! vlmxIsPlainScalar (in[IN_NLEAVES])           ||
      (nleaves = (int) *mxGetPr (in[IN_NLEAVES])) < 1) {
    mexErrMsgTxt ("NLEAVES must be a scalar not smaller than 2.") ;
  }

  M = mxGetM (in[IN_DATA]);   /* n of components */
  N = mxGetN (in[IN_DATA]);   /* n of elements */

  if (! vlmxIsPlainScalar (in[IN_K])         ||
      (K = (int) *mxGetPr (in[IN_K])) > N  ) {
    mexErrMsgTxt ("Cannot have more clusters than data.") ;
  }

  data = (vl_uint8 *) mxGetPr (in[IN_DATA]) ;

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    char buf [1024] ;

    switch (opt) {

    case opt_verbose :
      ++ verb ;
      break ;

    case opt_max_niters :
      if (!vlmxIsPlainScalar(optarg) || (max_niters = (int) *mxGetPr(optarg)) < 1) {
        mexErrMsgTxt("MaxNiters must be not smaller than 1.") ;
      }
      break ;

    case opt_method :
      if (!vlmxIsString (optarg, -1)) {
        mexErrMsgTxt("'Method' must be a string.") ;
      }
      if (mxGetString (optarg, buf, sizeof(buf))) {
        mexErrMsgTxt("Option argument too long.") ;
      }
      if (strcmp("lloyd", buf) == 0) {
        method_type = VL_IKM_LLOYD ;
      } else if (strcmp("elkan", buf) == 0) {
        method_type = VL_IKM_ELKAN ;
      } else {
        mexErrMsgTxt("Unknown cost type.") ;
      }

      break ;

    default :
      abort() ;
      break ;
    }
  }

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

  depth = VL_MAX(1, ceil (log (nleaves) / log(K))) ;
  tree  = vl_hikm_new  (method_type) ;

  if (verb) {
    mexPrintf("hikmeans: # dims: %d\n", M) ;
    mexPrintf("hikmeans: # data: %d\n", N) ;
    mexPrintf("hikmeans: K: %d\n", K) ;
    mexPrintf("hikmeans: depth: %d\n", depth) ;
  }

  vl_hikm_set_verbosity (tree, verb) ;
  vl_hikm_init          (tree, M, K, depth) ;
  vl_hikm_train         (tree, data, N) ;

  out[OUT_TREE] = hikm_to_matlab (tree) ;

  if (nout > 1) {
    vl_uint *asgn ;
    int j ;
    out [OUT_ASGN] = mxCreateNumericMatrix
      (vl_hikm_get_depth (tree), N, mxUINT32_CLASS, mxREAL) ;
    asgn = mxGetData(out[OUT_ASGN]) ;
    vl_hikm_push (tree, asgn, data, N) ;
    for (j = 0 ; j < N*depth ; ++ j) asgn [j] ++ ;
  }

  if (verb) {
    mexPrintf("hikmeans: done.\n") ;
  }

  /* vl_hikm_delete (tree) ; */
}
示例#18
0
/* driver */
void mexFunction (int nout, mxArray * out[], int nin, const mxArray * in[])
{
  enum {IN_X = 0, IN_K, IN_END} ;
  enum {OUT_C = 0, OUT_I} ;

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

  int M, N, K = 0 ;
  int err = 0 ;

  vl_uint     *asgn = 0 ;
  vl_ikm_acc  *centers = 0 ;
  vl_uint8 *data ;

  int method_type = VL_IKM_LLOYD ;
  int max_niters  = 200 ;
  int verb = 0 ;

  VlIKMFilt *ikmf ;

  VL_USE_MATLAB_ENV ;

  /* ------------------------------------------------------------------
   *                                                Check the arguments
   * --------------------------------------------------------------- */
  if (nin < 2) {
    mexErrMsgTxt ("At least two arguments required.");
  }
  else if (nout > 2) {
    mexErrMsgTxt ("Too many output arguments.");
  }
  if (mxGetClassID (in[IN_X]) != mxUINT8_CLASS) {
    mexErrMsgTxt ("X must be of class uint8");
  }

  M = mxGetM (in[IN_X]);   /* n of components */
  N = mxGetN (in[IN_X]);   /* n of elements */

  if (!vlmxIsPlainScalar (in[IN_K])          ||
      (K = (int) *mxGetPr(in[IN_K])) < 1 ||
      K > N                               ) {
    mexErrMsgTxt ("K must be a positive integer not greater than the number of data.");
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    char buf [1024] ;

    switch (opt) {

    case opt_verbose :
      ++ verb ;
      break ;

    case opt_max_niters :
      if (!vlmxIsPlainScalar(optarg) || (max_niters = (int) *mxGetPr(optarg)) < 1) {
        mexErrMsgTxt("MaxNiters must be not smaller than 1.") ;
      }
      break ;

    case opt_method :
      if (!vlmxIsString (optarg, -1)) {
        mexErrMsgTxt("'Method' must be a string.") ;
      }
      if (mxGetString (optarg, buf, sizeof(buf))) {
        mexErrMsgTxt("Option argument too long.") ;
      }
      if (strcmp("lloyd", buf) == 0) {
        method_type = VL_IKM_LLOYD ;
      } else if (strcmp("elkan", buf) == 0) {
        method_type = VL_IKM_ELKAN ;
      } else {
        mexErrMsgTxt("Unknown method type.") ;
      }
      break ;

    default :
      abort() ;
    }
  }

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

  if (verb) {
    char const * method_name = 0 ;
    switch (method_type) {
    case VL_IKM_LLOYD: method_name = "Lloyd" ; break ;
    case VL_IKM_ELKAN: method_name = "Elkan" ; break ;
    default :
      abort() ;
    }
    mexPrintf("ikmeans: MaxInters = %d\n", max_niters) ;
    mexPrintf("ikmeans: Method    = %s\n", method_name) ;
  }

  data = (vl_uint8*) mxGetPr(in[IN_X]) ;
  ikmf = vl_ikm_new (method_type) ;

  vl_ikm_set_verbosity  (ikmf, verb) ;
  vl_ikm_set_max_niters (ikmf, max_niters) ;
  vl_ikm_init_rand_data (ikmf, data, M, N, K) ;

  err = vl_ikm_train (ikmf, data, N) ;
  if (err) mexWarnMsgTxt("ikmeans: possible overflow!") ;

  /* ------------------------------------------------------------------
 *                                                       Return results
   * --------------------------------------------------------------- */

  {
    out[OUT_C] = mxCreateNumericMatrix (M, K, mxINT32_CLASS, mxREAL) ;
    centers    = mxGetData (out[OUT_C]) ;
    memcpy (centers, vl_ikm_get_centers (ikmf), sizeof(vl_ikm_acc) * M * K) ;
  }

  if (nout > 1) {
    int j ;
    out[OUT_I] = mxCreateNumericMatrix (1, N, mxUINT32_CLASS, mxREAL) ;
    asgn       = mxGetData (out[OUT_I]) ;

    vl_ikm_push (ikmf, asgn, data, N) ;

    for (j = 0 ; j < N ; ++j)
      ++ asgn [j] ;
  }

  vl_ikm_delete (ikmf) ;

  if (verb) {
    mexPrintf("ikmeans: done\n") ;
  }
}
示例#19
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_FOREST = 0, IN_DATA, IN_QUERY, IN_END} ;
  enum {OUT_INDEX = 0, OUT_DISTANCE} ;

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

  VlKDForest * forest ;
  mxArray const * forest_array = in[IN_FOREST] ;
  mxArray const * data_array = in[IN_DATA] ;
  mxArray const * query_array = in[IN_QUERY] ;
  mxArray * index_array ;
  mxArray * distance_array ;
  void * query ;
  vl_uint32 * index ;
  void * distance ;
  vl_size numNeighbors = 1 ;
  vl_size numQueries ;
  vl_uindex qi, ni;
  unsigned int numComparisons = 0 ;
  unsigned int maxNumComparisons = 0 ;
  VlKDForestNeighbor * neighbors ;
  mxClassID dataClass ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 3) {
    vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
  }
  if (nout > 2) {
    vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
  }

  forest = new_kdforest_from_array (forest_array, data_array) ;

  dataClass = mxGetClassID (data_array) ;
  if (mxGetClassID (query_array) != dataClass) {
    vlmxError(vlmxErrInvalidArgument,
             "QUERY must have the same storage class as DATA.") ;
  }
  if (! vlmxIsReal (query_array)) {
    vlmxError(vlmxErrInvalidArgument,
             "QUERY must be real.") ;
  }
  if (! vlmxIsMatrix (query_array, forest->dimension, -1)) {
    vlmxError(vlmxErrInvalidArgument,
             "QUERY must be a matrix with TREE.NUMDIMENSIONS rows.") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_num_neighs :
        if (! vlmxIsScalar(optarg) ||
            (numNeighbors = mxGetScalar(optarg)) < 1) {
          vlmxError(vlmxErrInvalidArgument,
                   "NUMNEIGHBORS must be a scalar not smaller than one.") ;
        }
        break;

      case opt_max_num_comparisons :
        if (! vlmxIsScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument,
                   "MAXNUMCOMPARISONS must be a scalar.") ;
        }
        maxNumComparisons = mxGetScalar(optarg) ;
        break;

      case opt_verbose :
        ++ verbose ;
        break ;
    }
  }

  vl_kdforest_set_max_num_comparisons (forest, maxNumComparisons) ;

  neighbors = vl_malloc (sizeof(VlKDForestNeighbor) * numNeighbors) ;

  query = mxGetData (query_array) ;
  numQueries = mxGetN (query_array) ;

  out[OUT_INDEX] = index_array = mxCreateNumericMatrix
    (numNeighbors, numQueries, mxUINT32_CLASS, mxREAL) ;

  out[OUT_DISTANCE] = distance_array = mxCreateNumericMatrix
    (numNeighbors, numQueries, dataClass, mxREAL) ;

  index = mxGetData (index_array) ;
  distance = mxGetData (distance_array) ;

  if (verbose) {
    VL_PRINTF ("vl_kdforestquery: number of queries: %d\n", numQueries) ;
    VL_PRINTF ("vl_kdforestquery: number of neighbors per query: %d\n", numNeighbors) ;
    VL_PRINTF ("vl_kdforestquery: max num of comparisons per query: %d\n",
               vl_kdforest_get_max_num_comparisons (forest)) ;
  }

  for (qi = 0 ; qi < numQueries ; ++ qi) {
    numComparisons += vl_kdforest_query (forest, neighbors, numNeighbors,
                                         query) ;
    switch (dataClass) {
      case mxSINGLE_CLASS:
      {
        float * distance_ = (float*) distance ;
        for (ni = 0 ; ni < numNeighbors ; ++ni) {
          *index++     = neighbors[ni].index + 1 ;
          *distance_++ = neighbors[ni].distance ;
        }
        query = (float*)query + vl_kdforest_get_data_dimension (forest) ;
        distance = distance_ ;
        break ;
      }
      case mxDOUBLE_CLASS:
      {
        double * distance_ = (double*) distance ;
        for (ni = 0 ; ni < numNeighbors ; ++ni) {
          *index++     = neighbors[ni].index + 1 ;
          *distance_++ = neighbors[ni].distance ;
        }
        query = (double*)query + vl_kdforest_get_data_dimension (forest)  ;
        distance = distance_ ;
        break ;
      }
      default:
        abort() ;
    }
  }

  if (verbose) {
    VL_PRINTF ("vl_kdforestquery: number of comparisons per query: %.3f\n",
               ((double) numComparisons) / numQueries) ;
    VL_PRINTF ("vl_kdforestquery: number of comparisons per neighbor: %.3f\n",
               ((double) numComparisons) / (numQueries * numNeighbors)) ;
  }

  vl_kdforest_delete (forest) ;
  vl_free (neighbors) ;
}
示例#20
0
/* driver */
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_X=0,IN_C,IN_END} ;
  enum {OUT_ASGN=0} ;
  vl_uint*     asgn ;
  vl_ikm_acc*  centers ;
  vl_uint8* data ;

  int M,N,j,K=0 ;

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

  int method_type = VL_IKM_LLOYD ;
  int verb = 0 ;

  VlIKMFilt *ikmf ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 2) {
    mexErrMsgTxt("At least two arguments required.") ;
  } else if (nout > 2) {
    mexErrMsgTxt("Too many output arguments.") ;
  }

  if(mxGetClassID(in[IN_X]) != mxUINT8_CLASS) {
    mexErrMsgTxt("X must be of class UINT8") ;
  }

  if(mxGetClassID(in[IN_C]) != mxINT32_CLASS) {
    mexErrMsgTxt("C must be of class INT32") ;
  }

  M = mxGetM(in[IN_X]) ;  /* n of components */
  N = mxGetN(in[IN_X]) ;  /* n of elements */
  K = mxGetN(in[IN_C]) ;  /* n of centers */

  if( (int) mxGetM(in[IN_C]) != M ) {
    mexErrMsgTxt("DATA and CENTERS must have the same number of columns.") ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    char buf [1024] ;

    switch (opt) {

    case opt_verbose :
      ++ verb ;
      break ;

    case opt_method :
      if (!vlmxIsString (optarg, -1)) {
        mexErrMsgTxt("'Method' must be a string.") ;
      }
      if (mxGetString (optarg, buf, sizeof(buf))) {
        mexErrMsgTxt("Option argument too long.") ;
      }
      if (strcmp("lloyd", buf) == 0) {
        method_type = VL_IKM_LLOYD ;
      } else if (strcmp("elkan", buf) == 0) {
        method_type = VL_IKM_ELKAN ;
      } else {
        mexErrMsgTxt("Unknown cost type.") ;
      }

      break ;

    default :
      abort() ;
    }
  }

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

  if (verb) {
    char const * method_name = 0 ;
    switch (method_type) {
    case VL_IKM_LLOYD: method_name = "Lloyd" ; break ;
    case VL_IKM_ELKAN: method_name = "Elkan" ; break ;
    default :
      abort() ;
    }
    mexPrintf("ikmeanspush: Method = %s\n", method_name) ;
    mexPrintf("ikmeanspush: ndata  = %d\n", N) ;
  }

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

  data    = (vl_uint8*) mxGetData (in[IN_X]) ;
  centers = (vl_ikm_acc*)  mxGetData (in[IN_C]) ;
  asgn    = (vl_uint*)     mxGetData (out[OUT_ASGN]) ;
  ikmf    = vl_ikm_new (method_type) ;

  vl_ikm_set_verbosity  (ikmf, verb) ;
  vl_ikm_init           (ikmf, centers, M, K) ;
  vl_ikm_push           (ikmf, asgn, data, N) ;

  /* adjust for MATLAB indexing */
  for(j = 0 ; j < N ; ++j) ++ asgn[j] ;

  vl_ikm_delete (ikmf) ;
}
示例#21
0
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_I = 0, IN_S, IN_END} ;
  enum {OUT_J = 0} ;
  int opt ;
  int next = IN_END ;
  mxArray const  *optarg ;

  int padding = VL_PAD_BY_CONTINUITY ;
  int kernel = GAUSSIAN ;
  int flags ;
  vl_size step = 1 ;
  int verb = 0 ;
  double sigma ;
  mxClassID classid ;

  mwSize M, N, K, M_, N_, ndims ;
  mwSize dims_ [3] ;
  mwSize const * dims ;

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

  if (nin < 2) {
    mexErrMsgTxt("At least two input arguments required.");
  } else if (nout > 1) {
    mexErrMsgTxt("Too many output arguments.");
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_padding :
      {
        enum {buflen = 32} ;
        char buf [buflen] ;
        if (!vlmxIsString(optarg, -1)) {
          vlmxError(vlmxErrInvalidArgument,
                   "PADDING argument must be a string.") ;
        }
        mxGetString(optarg, buf, buflen) ;
        buf [buflen - 1] = 0 ;
        if (vlmxCompareStringsI("zero", buf) == 0) {
          padding = VL_PAD_BY_ZERO ;
        } else if (vlmxCompareStringsI("continuity", buf) == 0) {
          padding = VL_PAD_BY_CONTINUITY ;
        } else {
          vlmxError(vlmxErrInvalidArgument,
                   "PADDING must be either ZERO or CONTINUITY, was '%s'.",
                   buf) ;
        }
        break ;
      }

      case opt_subsample :
        if (!vlmxIsPlainScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument,
                   "SUBSAMPLE must be a scalar.") ;
        }
        step = *mxGetPr(optarg) ;
        if (step < 1) {
          vlmxError(vlmxErrInvalidArgument,
                   "SUBSAMPLE must be not less than one.") ;
        }
        break ;

      case opt_kernel :
      {
        enum {buflen = 32} ;
        char buf [buflen] ;
        if (!vlmxIsString(optarg, -1)) {
          vlmxError(vlmxErrInvalidArgument,
                   "KERNEL argument must be a string.") ;
        }
        mxGetString(optarg, buf, buflen) ;
        buf [buflen - 1] = 0 ;
        if (vlmxCompareStringsI("gaussian", buf) == 0) {
          kernel = GAUSSIAN ;
        } else if (vlmxCompareStringsI("triangular", buf) == 0) {
          kernel = TRIANGULAR ;
        } else {
          vlmxError(vlmxErrInvalidArgument,
                   "Unknown kernel type '%s'.",
                   buf) ;
        }
        break ;
      }

      case opt_verbose :
        ++ verb ;
        break ;

      default:
        abort() ;
    }
  }

  if (! vlmxIsPlainScalar(IN(S))) {
    vlmxError(vlmxErrInvalidArgument,
             "S must be a real scalar.") ;
  }

  classid = mxGetClassID(IN(I)) ;

  if (classid != mxDOUBLE_CLASS &&
      classid != mxSINGLE_CLASS) {
    vlmxError(vlmxErrInvalidArgument,
             "I must be either DOUBLE or SINGLE.") ;
  }
  if (mxGetNumberOfDimensions(IN(I)) > 3) {
    vlmxError(vlmxErrInvalidArgument,
             "I must be either a two or three dimensional array.") ;
  }

  ndims = mxGetNumberOfDimensions(IN(I)) ;
  dims = mxGetDimensions(IN(I)) ;
  M = dims[0] ;
  N = dims[1] ;
  K = (ndims > 2) ? dims[2] : 1 ;

  sigma = * mxGetPr(IN(S)) ;
  if ((sigma < 0.01) && (step == 1)) {
    OUT(J) = mxDuplicateArray(IN(I)) ;
    return ;
  }

  M_ = (M - 1) / step + 1 ;
  N_ = (N - 1) / step + 1 ;
  dims_ [0] = M_ ;
  dims_ [1] = N_ ;
  if (ndims > 2) dims_ [2] = K ;

  OUT(J) = mxCreateNumericArray(ndims, dims_, classid, mxREAL) ;

  if (verb) {
    char const *classid_str = 0, *kernel_str = 0, *padding_str = 0 ;
    switch (padding) {
      case VL_PAD_BY_ZERO       : padding_str = "with zeroes" ; break ;
      case VL_PAD_BY_CONTINUITY : padding_str = "by continuity" ; break ;
      default: abort() ;
    }
    switch (classid) {
      case mxDOUBLE_CLASS: classid_str = "DOUBLE" ; break ;
      case mxSINGLE_CLASS: classid_str = "SINGLE" ; break ;
      default: abort() ;
    }
    switch (kernel) {
      case GAUSSIAN:   kernel_str = "Gaussian" ; break ;
      case TRIANGULAR: kernel_str = "triangular" ; break ;
      default: abort() ;
    }

    mexPrintf("vl_imsmooth: [%dx%dx%d] -> [%dx%dx%d] (%s, subsampling step %d)\n",
              N, M, K, N_, M_, K, classid_str, step) ;
    mexPrintf("vl_imsmooth: padding: %s\n", padding_str) ;
    mexPrintf("vl_imsmooth: kernel: %s\n", kernel_str) ;
    mexPrintf("vl_imsmooth: sigma: %g\n", sigma) ;
    mexPrintf("vl_imsmooth: SIMD enabled: %s\n",
              vl_get_simd_enabled() ? "yes" : "no") ;
  }

  /* -----------------------------------------------------------------
   *                                                        Do the job
   * -------------------------------------------------------------- */
  flags  = padding ;
  flags |= VL_TRANSPOSE ;

  switch (classid) {
    case mxSINGLE_CLASS:
      _vl_imsmooth_smooth_f ((float*) mxGetPr(OUT(J)),
                             M_, N_,
                             (float const*) mxGetPr(IN(I)),
                             M, N, K,
                             kernel, sigma, step, flags) ;
      break ;

    case mxDOUBLE_CLASS:
      _vl_imsmooth_smooth_d ((double*) mxGetPr(OUT(J)),
                             M_, N_,
                             (double const*) mxGetPr(IN(I)),
                             M, N, K,
                             kernel, sigma, step, flags) ;
      break ;

    default:
      abort() ;
  }
}
示例#22
0
文件: vl_slic.c 项目: 19test/sandbox
void
mexFunction(int nout, mxArray *out[],
            int nin, const mxArray *in[])
{
  enum {IN_IMAGE, IN_REGIONSIZE, IN_REGULARIZER, IN_END} ;
  enum {OUT_SEGMENTATION = 0} ;

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

  float const * image ;
  vl_size width ;
  vl_size height ;
  vl_size numChannels ;
  vl_size regionSize ;
  double regularizer ;
  vl_uint32 * segmentation ;
  int minRegionSize = -1 ;

  VL_USE_MATLAB_ENV ;

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

  if (nin < 3) {
    vlmxError(vlmxErrInvalidArgument,
              "At least three arguments are required.") ;
  } else if (nout > 1) {
    vlmxError(vlmxErrInvalidArgument,
              "Too many output arguments.");
  }

  image = mxGetData(IN(IMAGE)) ;
  if (!mxIsNumeric(IN(IMAGE)) || mxIsComplex(IN(IMAGE))) {
    vlmxError(vlmxErrInvalidArgument, "IMAGE is not a real matrix.") ;
  }
  if (mxGetClassID(IN(IMAGE)) != mxSINGLE_CLASS) {
    vlmxError(vlmxErrInvalidArgument, "IMAGE is not of class SINGLE.") ;
  }
  if (mxGetNumberOfDimensions(IN(IMAGE)) > 3) {
    vlmxError(vlmxErrInvalidArgument, "IMAGE has more than three dimensions.") ;
  }

  width = mxGetDimensions(IN(IMAGE))[1] ;
  height = mxGetDimensions(IN(IMAGE))[0] ;
  if (mxGetNumberOfDimensions(IN(IMAGE)) == 2) {
    numChannels = 1 ;
  } else {
    numChannels = mxGetDimensions(IN(IMAGE))[2] ;
  }

  if (!vlmxIsPlainScalar(IN(REGIONSIZE))) {
    vlmxError(vlmxErrInvalidArgument, "REGIONSIZE is not a plain scalar.") ;
  }
  regionSize = mxGetScalar(IN(REGIONSIZE)) ;
  if (regionSize < 1) {
    vlmxError(vlmxErrInvalidArgument, "REGIONSIZE=%d is smaller than one.", regionSize) ;
  }

  if (!vlmxIsPlainScalar(IN(REGULARIZER))) {
    vlmxError(vlmxErrInvalidArgument, "REGULARIZER is not a plain scalar.") ;
  }
  regularizer = mxGetScalar(IN(REGULARIZER)) ;
  if (regularizer < 0) {
    vlmxError(vlmxErrInvalidArgument, "REGULARIZER=%g is smaller than one.", regularizer) ;
  }

  while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
    switch (opt) {
      case opt_verbose :
        ++ verbose ;
        break ;
      case opt_min_segment_size :
        if (!vlmxIsPlainScalar(optarg)) {
          vlmxError(vlmxErrInvalidArgument, "MINREGIONSIZE is not a plain scalar.") ;
        }
        minRegionSize = mxGetScalar(optarg) ;
        if (minRegionSize < 0) {
          vlmxError(vlmxErrInvalidArgument, "MINREGIONSIZE=%d is smaller than zero.", minRegionSize) ;
        }
        break ;
    }
  }

  if (minRegionSize < 0) {
    minRegionSize = (regionSize * regionSize) / (6*6) ;
  }

  if (verbose) {
    mexPrintf("vl_slic: image = [%d x %d x %d]\n",
              width, height, numChannels) ;
    mexPrintf("vl_slic: regionSize = %d\n", regionSize) ;
    mexPrintf("vl_slic: regularizer = %g\n", regularizer) ;
    mexPrintf("vl_slic: minRegionSize = %d\n", minRegionSize) ;
  }

  /* -----------------------------------------------------------------
   *                                                           Do work
   * -------------------------------------------------------------- */

  OUT(SEGMENTATION) = mxCreateNumericMatrix((mwSize)height, (mwSize)width, mxUINT32_CLASS, mxREAL) ;
  segmentation = mxGetData(OUT(SEGMENTATION)) ;

  vl_slic_segment(segmentation,
                  image, height, width, numChannels, /* the image is transposed */
                  regionSize, regularizer, minRegionSize) ;
}