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 */ }
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 */ }
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) ; }
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); }
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) ; }
/* 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) ; }
/* 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() ; } }
/* 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 */ }
/** @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] ++ ; } }
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) ; } }
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)) ; } }
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); }
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) ; }
/** ------------------------------------------------------------------ ** @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) ; */ }
/* 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") ; } }
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) ; }
/* 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) ; }
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() ; } }
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) ; }