Exemple #1
0
int mxIsLogicalScalarTrue(const mxArray *ptr)
{
    if (mxIsLogicalScalar(ptr) == false)
    {
        return 0;
    }

    if (*mxGetLogicals(ptr) == 0)
    {
        return 0;
    }

    return 1;
}
Exemple #2
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) ;
}
Exemple #3
0
	bool BoolParameter::validate(const mxArray* input)
	{
		return mxIsLogicalScalar(input);
	}
int isFunctionHandle( const mxArray* const M )
{
	if ( M == NULL )
		return 0;

	if ( mxIsCell(M) )
		return 0;

	if ( mxIsChar(M) )
		return 0;

	if ( mxIsComplex(M) )
		return 0;

	if ( mxIsDouble(M) )
		return 0;

	if ( mxIsEmpty(M) )
		return 0;

	if ( mxIsInt8(M) )
		return 0;

	if ( mxIsInt16(M) )
		return 0;

	if ( mxIsInt32(M) )
		return 0;

	if ( mxIsLogical(M) )
		return 0;

	if ( mxIsLogicalScalar(M) )
		return 0;

	if ( mxIsLogicalScalarTrue(M) )
		return 0;

	if ( mxIsNumeric(M) )
		return 0;

	if ( mxIsSingle(M) )
		return 0;

	if ( mxIsSparse(M) )
		return 0;

	if ( mxIsStruct(M) )
		return 0;

	if ( mxIsUint8(M) )
		return 0;

	if ( mxIsUint16(M) )
		return 0;

	if ( mxIsUint32(M) )
		return 0;

	// assume to be a function handle iff it is nothing else
	return 1;
}
//parse the matlab struct to get all the options for training
CvRTParams* parse_struct_to_forest_config(const mxArray *trainingOptions) {
    int numFields = 0;
    if (trainingOptions != NULL) {
        numFields = mxGetNumberOfFields(trainingOptions);
    }

    mexPrintf("%d training fields provided\n", numFields);

    //these should be the default values that we would get from instantiating
    //a CvRTParams object.
    int maxDepth = DEFAULT_MAX_DEPTH;
    int minSampleCount = DEFAULT_MIN_SAMPLE_COUNT;
    float regressionAccuracy = DEFAULT_REGRESSION_ACCURACY;
    bool useSurrogates = DEFAULT_USE_SURROGATES;
    int maxCategories = DEFAULT_MAX_CATEGORIES;
    float* priors = DEFAULT_PRIORS;
    bool calcVarImportance = DEFAULT_CALC_VAR_IMPORTANCE;
    int numActiveVars = DEFAULT_NUM_ACTIVE_VARS;
    int maxTreeCount = DEFAULT_MAX_TREE_COUNT;
    float forestAccuracy = DEFAULT_FOREST_ACCURACY;
    int termCriteriaType = DEFAULT_TERM_CRITERIA_TYPE;

    for (int i=0; i < numFields; i++) {
        const char *name = mxGetFieldNameByNumber(trainingOptions, i);
        mexPrintf("field %d is %s\n",i,name);
        mxArray *field = mxGetFieldByNumber(trainingOptions, 0, i);
        if (num_elements(field) != 1) { 
            mexWarnMsgIdAndTxt("train_random_forest:non_scalar_option", 
                               "field is not a scalar! cannot parse into Random Forest options.");
            continue;
        }
        
        //now need to compare against all the names we recognise
        if (strcmp(name, "max_depth") == 0) {
            if (mxIsInt32(field)) {
                maxDepth = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","max_depth field must be a int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "min_sample_count") == 0) {
            if (mxIsInt32(field)) {
                minSampleCount = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","min_sample_count field must be a int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "regression_accuracy") == 0) {
            if (mxIsDouble(field)) {
                regressionAccuracy = (float)SCALAR_GET_DOUBLE(field);
            }
            else if (mxIsSingle(field)) {
                regressionAccuracy = SCALAR_GET_SINGLE(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_float","regression_accuracy field must be a single or double. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "use_surrogates") == 0) {
            if (mxIsLogicalScalar(field)) {
                useSurrogates = mxIsLogicalScalarTrue(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_bool","use_surrogates field must be a boolean/logical. skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "max_categories") == 0) {
            if (mxIsInt32(field)) {
                maxCategories = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","max_categories field must be an int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "calc_var_importance") == 0) {
            if (mxIsLogicalScalar(field)) {
                calcVarImportance = mxIsLogicalScalarTrue(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_bool","calc_var_importance field must be a boolean/logical. skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "num_active_vars") == 0) {
            if (mxIsInt32(field)) {
                numActiveVars = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","num_active_vars field must be an int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "max_tree_count") == 0) {
            if (mxIsInt32(field)) {
                maxTreeCount = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","max_tree_count field must be an int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "forest_accuracy") == 0) {
            if (mxIsDouble(field)) {
                forestAccuracy = (float)SCALAR_GET_DOUBLE(field);
            }
            else if (mxIsSingle(field)) {
                forestAccuracy = SCALAR_GET_SINGLE(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_float","forest_accuracy field must be a float. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "term_criteria_type") == 0) {
            if (mxIsInt32(field)) {
                termCriteriaType = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","term_critera_type field must be an int32. Skipping...\n");
            }
            continue;
        }
        else {
            char msgbuf[ERR_MSG_SIZE];
            sprintf(msgbuf,"field provided was not recognised: %s",name);
            mexWarnMsgIdAndTxt("train_random_forest:unrecognised_field",msgbuf);
        }
    }

    return new CvRTParams(maxDepth, minSampleCount, regressionAccuracy,
                          useSurrogates, maxCategories, priors,
                          calcVarImportance, numActiveVars, maxTreeCount,
                          forestAccuracy, termCriteriaType);
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // Get the command string
    char cmd[64];
    if(nrhs < 1 || mxGetString(prhs[0], cmd, sizeof(cmd)))
    {
        mexErrMsgTxt("GaussianKernel: First input should be a command string less than 64 characters long.");
    }
    
    // New
    if (!strcmp(cmd, "new"))
    {
        // Check output parameters
        if (nlhs != 1)
        {
            mexErrMsgTxt("GaussianKernel: new: One output expected.");
        }
        
        // Check input parameters
        if (nrhs == 1)
        {
            plhs[0] = convertPtr2Mat(new GaussianKernel());
        }
        else if (nrhs == 3)
        {
            if(!mxIsDouble(prhs[1]) || !mxIsDouble(prhs[2])) {
                mexErrMsgTxt("GaussianKernel: new: Invalid data type.");
            }
            
            double lowerBound = mxGetScalar(prhs[1]);
            double upperBound = mxGetScalar(prhs[2]);
            
            plhs[0] = convertPtr2Mat(new GaussianKernel(lowerBound, upperBound));
        }
        else if (nrhs == 4)
        {
            if(!mxIsDouble(prhs[1]) || !mxIsDouble(prhs[2]) || !mxIsLogicalScalar(prhs[3])) {
                mexErrMsgTxt("GaussianKernel: new: Invalid data type.");
            }
            
            double lowerBound = mxGetScalar(prhs[1]);
            double upperBound = mxGetScalar(prhs[2]);
            bool interpolation = mxIsLogicalScalarTrue(prhs[3]);
            
            plhs[0] = convertPtr2Mat(new GaussianKernel(lowerBound, upperBound, interpolation));
        }
        else
            mexErrMsgTxt("GaussianKernel: new: Invalid parameter number.");
        
        return;
    }
    
    // Check there is a second input, which should be the class instance handle
    if (nrhs < 2)
		mexErrMsgTxt("GaussianKernel: Second input should be a class instance handle.");
    
    // Delete
    if (!strcmp(cmd, "delete"))
    {
        // Destroy the C++ object
        destroyObject<GaussianKernel>(prhs[1]);
        
        // Warn if other commands were ignored
        if (nlhs != 0 || nrhs != 2)
            mexWarnMsgTxt("Delete: Unexpected arguments ignored.");
        
        return;
    }
}
Exemple #7
0
_mps_matlab_options
mps_parse_matlab_options (const mxArray * optionStruct)
{
    _mps_matlab_options options = {
        MPS_ALGORITHM_SECULAR_GA,
        MPS_OUTPUT_GOAL_APPROXIMATE,
        16,
        false
    };

    if (!optionStruct)
        return options;

    if (mxIsChar (optionStruct))
    {
        mxChar * value = mxGetChars (optionStruct);
        if (strcmp ((char*) value, "s") == 0)
            options.algorithm = MPS_ALGORITHM_SECULAR_GA;
        else if (strcmp ((char*) value, "u") == 0)
            options.algorithm = MPS_ALGORITHM_STANDARD_MPSOLVE;
        else
            mexErrMsgTxt ("Invalid value specified for the algorithm. Only 'u' or 's' are allowed.\n");
    }
    else if (! mxIsStruct (optionStruct))
        mexErrMsgTxt ("Only chars and struct values are allowed as MPSolve options\n");

    if (optionStruct)
    {
        int nFields = mxGetNumberOfFields (optionStruct);
        int i;

        for (i = 0; i < nFields; i++)
        {
            const char * optionName = mxGetFieldNameByNumber (optionStruct, i);
            mxArray * field = mxGetFieldByNumber (optionStruct, 0, i);

            if (strcmp (optionName, "algorithm") == 0)
            {
                if (! mxIsChar (field))
                    mexErrMsgTxt ("Please specify only 'u' or 's' for the algorithm property\n");
                else
                {
                    mxChar * value = mxGetChars (field);
                    if (strcmp ((char*) value, "s") == 0)
                        options.algorithm = MPS_ALGORITHM_SECULAR_GA;
                    else if (strcmp ((char*) value, "u") == 0)
                        options.algorithm = MPS_ALGORITHM_STANDARD_MPSOLVE;
                    else
                        mexErrMsgTxt ("Invalid value specified for the property: 'algorithm'. Only 'u' or 's' are allowed.\n");
                }
            }
            else if (strcmp (optionName, "digits") == 0)
            {
                if (! mxIsNumeric (field))
                    mexErrMsgTxt ("Please specify a positive integer for the digits property\n");
                else
                {
                    double digits = mxGetScalar (field);

                    if (digits <= 0)
                        mexErrMsgTxt ("Please specify a positive integer for the digits property\n");
                    else
                        options.digits = (int) digits;
                }
            }
            else if (strcmp (optionName, "goal") == 0)
            {
                if (! mxIsChar (field))
                    mexErrMsgTxt ("Please specify only 'a' or 'i' as value for the goal property\n");
                else
                {
                    mxChar * value = mxGetChars (field);
                    if (strcmp ((char*) value, "i") == 0)
                        options.goal = MPS_OUTPUT_GOAL_ISOLATE;
                    else if (strcmp ((char*) value, "a") == 0)
                        options.goal = MPS_OUTPUT_GOAL_APPROXIMATE;
                    else
                        mexErrMsgTxt ("Please specify only 'a' or 'i' as value for the goal property\n");
                }
            }
            else if (strcmp (optionName, "radius") == 0)
            {
                if (! mxIsLogicalScalar (field))
                    mexErrMsgTxt ("Please specify 'true' or 'false' as a value for the radius property\n");
                else
                {
                    options.radius = *mxGetLogicals (field);
                }
            }
            else
            {
                char * buffer = (char*) mxMalloc (sizeof (char) * (strlen ("The property '' is invalid\n") + strlen ((char*) optionName) + 1));
                sprintf (buffer, "The property '%s' is invalid\n", optionName);
                mexErrMsgTxt (buffer);
                mxFree (buffer);
            }
        }
    }

    return options;
}
void mexFunction( const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) {
	/* Check for proper number of arguments. */
	if (nrhs != 1) {
		mexErrMsgIdAndTxt( "MATLAB:Graph:IsConnected:invalidNumInputs",
			"One input required.");
	} else if (nlhs > 1) {
		mexErrMsgIdAndTxt( "MATLAB:Graph:IsConnected:invalidNumOutputs",
			"At most one output is allowed.");
	}

	const mxArray *numberOfNodesArray = mxGetProperty(prhs[0], 0, "numberOfNodes");
	if (!mxIsNumeric(numberOfNodesArray) || mxGetNumberOfElements(numberOfNodesArray) != 1) {
		mexErrMsgIdAndTxt( "MATLAB:Graph:IsConnected:invalidNumberOfNodes", "Number of nodes is not numeric scalar.");
	}
	const int numberOfNodes = mxGetScalar(numberOfNodesArray);
	if (numberOfNodes < 1) {
		mexErrMsgIdAndTxt( "MATLAB:Graph:IsConnected:emptyGraph",
			"Graph is empty.");
	}

	const mxArray *pAdjacencyMatrix = mxGetProperty(prhs[0], 0, "pAdjacencyMatrix");
	if (!mxIsLogical(pAdjacencyMatrix) || mxGetN(pAdjacencyMatrix) != numberOfNodes || mxGetM(pAdjacencyMatrix) != numberOfNodes) {
		mexErrMsgIdAndTxt("MATLAB:Graph:IsConnected:invalidAdjacencyMatrix", "Adjacency matrix is not logical square matrix");
	}
	const bool *adjacencyMatrix = mxGetLogicals(pAdjacencyMatrix);

	const mxArray *pIsDirectedArray = mxGetProperty(prhs[0], 0, "pIsDirected");
	if (!mxIsLogicalScalar(pIsDirectedArray)) {
		mexErrMsgIdAndTxt( "MATLAB:Graph:IsConnected:invalidIsDirected", "Direction is not logical scalar");
	}
	const bool isDirected = mxIsLogicalScalarTrue(pIsDirectedArray);

	bool *reachable = new bool[numberOfNodes];


	if (mxIsSparse(pAdjacencyMatrix)) {
		// Sparse adjacency matrix
		std::vector<std::vector<mwIndex> > graph(numberOfNodes), rgraph(numberOfNodes);
		const mwIndex* row = mxGetIr(pAdjacencyMatrix);
		const mwIndex* col = mxGetJc(pAdjacencyMatrix);
		const size_t nz = col[mxGetN(pAdjacencyMatrix)];
		mwIndex c = 0;
		for(size_t i = 0; i<nz; ++i) {
			while(col[c+1]<=i) ++c;
			if(adjacencyMatrix[i]) {
				graph[row[i]].push_back(c);
				rgraph[c].push_back(row[i]);
			}
		}
		memset(reachable, false, numberOfNodes * sizeof(bool));
		reachable[0] = true;
		int nReachable = 1;
		std::queue<int> nodeQueue;
		nodeQueue.push(0);

		while(!nodeQueue.empty() && nReachable < numberOfNodes) {
			const int i = nodeQueue.front(); nodeQueue.pop();
			std::vector<mwIndex>::const_iterator it = graph[i].begin();

			for (; it != graph[i].end(); ++it) {
				if(!reachable[*it]) {
					reachable[*it] = true;
					nReachable++;
					nodeQueue.push(*it);
				}
			}
		}
		if (!isDirected || nReachable != numberOfNodes) {
			plhs[0] = mxCreateLogicalScalar(nReachable == numberOfNodes);
		} else {
			memset(reachable, false, numberOfNodes * sizeof(bool));
			reachable[0] = true;
			int nReachable2 = 1;
			nodeQueue = std::queue<int>(); // Clear queue
			nodeQueue.push(0);
			while(!nodeQueue.empty() && nReachable2 < numberOfNodes) {
				const int i = nodeQueue.front(); nodeQueue.pop();
				std::vector<mwIndex>::const_iterator it = rgraph[i].begin();
				for (; it != rgraph[i].end(); ++it) {
					if(!reachable[*it]) {
						mexPrintf("Reachable 2 is %lu\n", *it);
						reachable[*it] = true;
						nReachable2++;
						nodeQueue.push(*it);
					}
				}
			}
			plhs[0] = mxCreateLogicalScalar(nReachable2 == numberOfNodes);
		}
	} else {
		// Full adjacency matrix
		memset(reachable, false, numberOfNodes * sizeof(bool));
		reachable[0] = true;
		int nReachable = 1;
		std::queue<int> nodeQueue;
		nodeQueue.push(0);

		while(!nodeQueue.empty() && nReachable < numberOfNodes) {
			const int i = nodeQueue.front(); nodeQueue.pop();
			for (int j=0; j<numberOfNodes; ++j) {
				if(adjacencyMatrix[i*numberOfNodes+j] && !reachable[j]) {
					reachable[j] = true;
					nReachable++;
					nodeQueue.push(j);
				}
			}
		}
		if (!isDirected || nReachable != numberOfNodes) {
			plhs[0] = mxCreateLogicalScalar(nReachable == numberOfNodes);
		} else {
			memset(reachable, false, numberOfNodes * sizeof(bool));
			reachable[0] = true;
			int nReachable2 = 1;
			nodeQueue = std::queue<int>(); // Clear queue
			nodeQueue.push(0);
			while(!nodeQueue.empty() && nReachable2 < numberOfNodes) {
				const int i = nodeQueue.front(); nodeQueue.pop();
				for (int j=0; j<numberOfNodes; ++j) {
					if(adjacencyMatrix[j*numberOfNodes+i] && !reachable[j]) {
						reachable[j] = true;
						nReachable2++;
						nodeQueue.push(j);
					}
				}
			}
			plhs[0] = mxCreateLogicalScalar(nReachable2 == numberOfNodes);
		}
	}

	delete [] reachable;
}