void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum { X=0,Y } ; enum { U } ; int NP, NCP ; int i,j ; double *X_pt, *Y_pt, *U_pt ; #undef small const double small = 2.220446049250313e-16 ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin != 2) { vlmxError(vlmxErrNotEnoughInputArguments, NULL) ; } else if (nout > 1) { vlmxError(vlmxErrTooManyOutputArguments, NULL) ; } if(!vlmxIsMatrix(in[X], 2, -1)) { mexErrMsgTxt("X must be a 2xNP real matrix") ; } if(!vlmxIsMatrix(in[Y], 2, -1)) { mexErrMsgTxt("Y must be a 2xNCP real matrix") ; } NP = getN(X) ; NCP = getN(Y) ; X_pt = getPr(X); Y_pt = getPr(Y) ; /* Allocate the result. */ out[U] = mxCreateDoubleMatrix(NP, NCP, mxREAL) ; U_pt = mxGetPr(out[U]) ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ for(j = 0 ; j < NCP ; ++j) { double xcp = *Y_pt++ ; double ycp = *Y_pt++ ; for(i = 0 ; i < NP ; ++i) { double dx = *X_pt++ - xcp ; double dy = *X_pt++ - ycp ; double r2 = dx*dx + dy*dy ; *U_pt++ = (r2 <= small) ? 0 : r2 * log (r2) ; } X_pt -= 2*NP ; } }
static VlHIKMNode * xcreate (VlHIKMTree *tree, mxArray const *mnode, int i) { mxArray const *mcenters, *msub ; VlHIKMNode *node ; vl_size M, node_K ; vl_uindex k ; /* sanity checks */ mcenters = mxGetField(mnode, i, "centers") ; msub = mxGetField(mnode, i, "sub") ; if (!mcenters || mxGetClassID (mcenters) != mxINT32_CLASS || !vlmxIsMatrix (mcenters, -1, -1) ) { mexErrMsgTxt("NODE.CENTERS must be a INT32 matrix.") ; } M = mxGetM (mcenters) ; node_K = mxGetN (mcenters) ; if (node_K > (vl_size)tree->K) { mexErrMsgTxt("A node has more clusters than TREE.K.") ; } if (tree->M < 0) { tree->M = M ; } else if (M != (vl_size)tree->M) { mexErrMsgTxt("A node CENTERS field has inconsistent dimensionality.") ; } node = mxMalloc (sizeof(VlHIKMNode)) ; node->filter = vl_ikm_new (tree->method) ; node->children = 0 ; vl_ikm_init (node->filter, mxGetData(mcenters), M, node_K) ; /* has any childer? */ if (msub) { /* sanity checks */ if (mxGetClassID (msub) != mxSTRUCT_CLASS) { mexErrMsgTxt("NODE.SUB must be a MATLAB structure array.") ; } if (mxGetNumberOfElements (msub) != node_K) { mexErrMsgTxt("NODE.SUB size must correspond to NODE.CENTERS.") ; } node-> children = mxMalloc (sizeof(VlHIKMNode *) * node_K) ; for(k = 0 ; k < node_K ; ++ k) { node-> children [k] = xcreate (tree, msub, k) ; } } return node ; }
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 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) ; }
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_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_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) ; }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { vl_size M, N ; enum {IN_I = 0, IN_PARAM, IN_END} ; enum {OUT_DT = 0, OUT_INDEXES} ; vl_uindex * indexes = NULL ; mxClassID classId ; double const defaultParam [] = {1.0, 0.0, 1.0, 0.0} ; double const * param = defaultParam ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 1) { vlmxError(vlmxErrNotEnoughInputArguments, NULL) ; } if (nin > 2) { vlmxError(vlmxErrTooManyInputArguments, NULL) ; } if (nout > 2) { vlmxError(vlmxErrTooManyOutputArguments, NULL) ; } classId = mxGetClassID(IN(I)) ; if (! vlmxIsMatrix(IN(I), -1, -1) || (classId != mxSINGLE_CLASS && classId != mxDOUBLE_CLASS)) { vlmxError(vlmxErrInvalidArgument, "I is not a SINGLE or DOUBLE matrix.") ; } if (nin == 2) { if (! vlmxIsPlainVector(IN(PARAM), 4)) { vlmxError(vlmxErrInvalidArgument, "PARAM is not a 4-dimensional vector.") ; } param = mxGetPr (IN(PARAM)) ; if (param[0] < 0.0 || param[2] < 0.0) { vlmxError(vlmxErrInvalidArgument, "Either PARAM[0] or PARAM[2] is negative.") ; } } M = mxGetM (IN(I)) ; N = mxGetN (IN(I)) ; OUT(DT) = mxCreateNumericMatrix (M, N, classId, mxREAL) ; if (nout > 1) { vl_uindex i ; OUT(INDEXES) = mxCreateDoubleMatrix (M, N, mxREAL) ; indexes = mxMalloc(sizeof(vl_uindex) * M * N) ; for (i = 0 ; i < M * N ; ++i) indexes[i] = i + 1 ; } /* ----------------------------------------------------------------- * Do the job * -------------------------------------------------------------- */ switch (classId) { case mxSINGLE_CLASS: vl_image_distance_transform_f((float const*)mxGetData(IN(I)), M, N, 1, M, (float*)mxGetPr(OUT(DT)), indexes, param[2], param[3]) ; vl_image_distance_transform_f((float*)mxGetPr(OUT(DT)), N, M, M, 1, (float*)mxGetPr(OUT(DT)), indexes, param[0], param[1]) ; break ; case mxDOUBLE_CLASS: vl_image_distance_transform_d((double const*)mxGetData(IN(I)), M, N, 1, M, (double*)mxGetPr(OUT(DT)), indexes, param[2], param[3]) ; vl_image_distance_transform_d((double*)mxGetPr(OUT(DT)), N, M, M, 1, (double*)mxGetPr(OUT(DT)), indexes, param[0], param[1]) ; break; default: abort() ; } if (indexes) { vl_uindex i ; double * pt = mxGetPr(OUT(INDEXES)) ; for (i = 0 ; i < M * N ; ++i) pt[i] = indexes[i] ; mxFree(indexes) ; } }
/* 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[]) { float * image ; vl_size width, height ; vl_size cellSize = 16 ; enum {IN_I = 0, IN_CELLSIZE} ; enum {OUT_FEATURES = 0} ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin > 2) { vlmxError(vlmxErrTooManyInputArguments, NULL) ; } if (nin < 2) { vlmxError(vlmxErrNotEnoughInputArguments, NULL) ; } if (nout > 1) { vlmxError(vlmxErrTooManyOutputArguments, NULL) ; } if (! mxIsNumeric(IN(I)) || ! vlmxIsReal(IN(I)) || ! vlmxIsMatrix(IN(I), -1, -1)) { vlmxError(vlmxErrInvalidArgument, "I is not a numeric matrix.") ; } if (mxGetClassID(IN(I)) != mxSINGLE_CLASS) { vlmxError(vlmxErrInvalidArgument, "I is not of class SINGLE.") ; } if (! vlmxIsPlainScalar(IN(CELLSIZE))) { vlmxError(vlmxErrInvalidArgument, "CELLSIZE is not a plain scalar.") ; } if (mxGetScalar(IN(CELLSIZE)) < 1.0) { vlmxError(vlmxErrInvalidArgument, "CELLSIZE is less than 1.") ; } cellSize = (vl_size) mxGetScalar(IN(CELLSIZE)) ; image = mxGetData(IN(I)) ; width = mxGetN(IN(I)) ; height = mxGetM(IN(I)) ; /* do job */ { /* recall that MATLAB images are transposed */ mwSize dimensions [3] ; /* get LBP object */ VlLbp * lbp = vl_lbp_new (VlLbpUniform, VL_TRUE) ; if (lbp == NULL) { vlmxError(vlmxErrAlloc, NULL) ; } /* get output buffer */ dimensions[0] = height / cellSize ; dimensions[1] = width / cellSize ; dimensions[2] = vl_lbp_get_dimension(lbp) ; OUT(FEATURES) = mxCreateNumericArray(3, dimensions, mxSINGLE_CLASS, mxREAL) ; vl_lbp_process(lbp, mxGetData(OUT(FEATURES)), image, height, width, cellSize) ; vl_lbp_delete(lbp) ; } }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_I=0,IN_END} ; enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; vl_sift_pix const *data ; int M, N ; int O = - 1 ; int S = 3 ; int o_min = 0 ; double edge_thresh = -1 ; double peak_thresh = -1 ; double norm_thresh = -1 ; double magnif = -1 ; double window_size = -1 ; mxArray *ikeys_array = 0 ; double *ikeys = 0 ; int nikeys = -1 ; vl_bool force_orientations = 0 ; vl_bool floatDescriptors = 0 ; VL_USE_MATLAB_ENV ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 1) { mexErrMsgTxt("One argument required.") ; } else if (nout > 2) { mexErrMsgTxt("Too many output arguments."); } if (mxGetNumberOfDimensions (in[IN_I]) != 2 || mxGetClassID (in[IN_I]) != mxSINGLE_CLASS ) { mexErrMsgTxt("I must be a matrix of class SINGLE") ; } data = (vl_sift_pix*) mxGetData (in[IN_I]) ; M = mxGetM (in[IN_I]) ; N = mxGetN (in[IN_I]) ; while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_frames : if (!vlmxIsMatrix(optarg, 4, -1)) { mexErrMsgTxt("'Frames' must be a 4 x N matrix.") ; } ikeys_array = mxDuplicateArray (optarg) ; nikeys = mxGetN (optarg) ; ikeys = mxGetPr (ikeys_array) ; if (! check_sorted (ikeys, nikeys)) { qsort (ikeys, nikeys, 4 * sizeof(double), korder) ; } break ; default : mexPrintf("F**k you!"); abort() ; } } /* ----------------------------------------------------------------- * Do job * -------------------------------------------------------------- */ { VlSiftFilt *filt ; vl_bool first ; double *frames = 0 ; void *descr = 0 ; int nframes = 0, reserved = 0, i,j,q ; /* create a filter to process the image */ filt = vl_sift_new (M, N, O, S, o_min) ; //mexPrintf("%f %f %f \n%f %f %f %f %f\n",(float)O,(float)S,(float)o_min,(float)peak_thresh // ,(float)edge_thresh,(float)norm_thresh,(float)magnif,(float)window_size); /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (first == 1) { int err ; VlSiftKeypoint const *keys = 0 ; int nkeys = 0 ; err = vl_sift_process_first_octave (filt, data) ; first = 0 ; if (err) break ; /* Run detector ............................................. */ nkeys = nikeys ; //mexPrintf("Zhu: entering sweeping nkeys, nkeys = %d, i = %d \n", nkeys, i); /* For each keypoint ........................................ */ for (; i < nkeys ; ++i) { int h; vl_sift_pix buf[128]; vl_sift_pix rbuf[128]; double angle; VlSiftKeypoint ik ; VlSiftKeypoint const *k ; /* Obtain keypoint orientations ........................... */ vl_sift_keypoint_init (filt, &ik, ikeys [4 * i + 1] - 1, ikeys [4 * i + 0] - 1, ikeys [4 * i + 2]) ; //mexPrintf("ikeys: [%f, %f, %f]\n", (float)(ikeys [4 * i + 1] - 1), (float)(ikeys [4 * i + 0] - 1), (float)(ikeys [4 * i + 2]) ); k = &ik ; /* optionally compute orientations too */ angle = VL_PI / 2 - ikeys [4 * i + 3] ; q = 0; /* compute descriptor (if necessary) */ //int h; //mexPrintf("M = %d, N = %d.\n",M,N); //for (h = 0; h < 300; h++) //{ // mexPrintf("%f ",data[h]); // if (h % 8 == 7) mexPrintf("\n"); //} if (nout > 1) { //mexPrintf("angles = %f, x = %f(%d), y = %f(%d), s = %f(%d), o = %d, sigma = %f.\n buf = [", //angle,k->x,k->ix,k->y,k->iy,k->s,k->is,k->o,k->sigma); vl_sift_calc_keypoint_descriptor (filt, buf, k, angle) ; //for (h = 0; h < 128; h++) //{ // mexPrintf("%f ",(float)buf[h]); // if (h % 8 == 7) mexPrintf("\n"); //} //mexPrintf("...].\nrbuf = ["); transpose_descriptor (rbuf, buf) ; //for (h = 0; h < 128; h++) //{ // mexPrintf("%f ",(float)rbuf[h]); // if (h % 8 == 7) mexPrintf("\n"); //} //mexPrintf("...].\n"); } /* make enough room for all these keypoints and more */ if (reserved < nframes + 1) { reserved += 2 * nkeys ; frames = mxRealloc (frames, 4 * sizeof(double) * reserved) ; if (nout > 1) { if (! floatDescriptors) { descr = mxRealloc (descr, 128 * sizeof(vl_uint8) * reserved) ; } else { descr = mxRealloc (descr, 128 * sizeof(float) * reserved) ; } } } /* Save back with MATLAB conventions. Notice tha the input * image was the transpose of the actual image. */ frames [4 * nframes + 0] = k -> y + 1 ; frames [4 * nframes + 1] = k -> x + 1 ; frames [4 * nframes + 2] = k -> sigma ; frames [4 * nframes + 3] = VL_PI / 2 - angle; //mexPrintf("Zhu: %d\n", nframes); if (nout > 1) { if (! floatDescriptors) { for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; x = (x < 255.0F) ? x : 255.0F ; ((vl_uint8*)descr) [128 * nframes + j] = (vl_uint8) x ; } } else { for (j = 0 ; j < 128 ; ++j) { float x = 512.0F * rbuf [j] ; ((float*)descr) [128 * nframes + j] = x ; } } } ++ nframes ; /* next orientation */ } /* next keypoint */ //break; //mexPrintf("Zhu: skip subsequent octave\n"); } /* next octave */ //mexPrintf("nframes_tot = %d\n",nframes); /* ............................................................... * Save back * ............................................................ */ { mwSize dims [2] ; /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_FRAMES] = mxCreateNumericArray (2, dims, mxDOUBLE_CLASS, mxREAL) ; /* set array content to be the frames buffer */ dims [0] = 4 ; dims [1] = nframes ; mxSetPr (out[OUT_FRAMES], frames) ; mxSetDimensions (out[OUT_FRAMES], dims, 2) ; if (nout > 1) { /* create an empty array */ dims [0] = 0 ; dims [1] = 0 ; out[OUT_DESCRIPTORS]= mxCreateNumericArray (2, dims, floatDescriptors ? mxSINGLE_CLASS : mxUINT8_CLASS, mxREAL) ; /* set array content to be the descriptors buffer */ dims [0] = 128 ; dims [1] = nframes ; mxSetData (out[OUT_DESCRIPTORS], descr) ; mxSetDimensions (out[OUT_DESCRIPTORS], dims, 2) ; } } /* cleanup */ vl_sift_delete (filt) ; if (ikeys_array) mxDestroyArray(ikeys_array) ; } /* end: do job */ }
void 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)) ; } }