00001
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <mexutils.h>
00017
00018 #include <vl/quickshift.h>
00019 #include <string.h>
00020
00021 enum {
00022 opt_medoid,
00023 opt_verbose
00024 } ;
00025
00026 vlmxOption options [] = {
00027 {"Medoid", 0, opt_medoid },
00028 {"Verbose", 0, opt_verbose },
00029 {0, 0, 0 }
00030 } ;
00031
00036 void
00037 mexFunction(int nout, mxArray *out[],
00038 int nin, const mxArray *in[])
00039 {
00040 enum {
00041 IN_I=0,
00042 IN_KERNEL_SIZE,
00043 IN_MAX_DIST,
00044
00045 IN_END
00046 } ;
00047 enum {
00048 OUT_PARENTS=0,
00049 OUT_DISTS,
00050 OUT_DENSITY
00051 } ;
00052
00053 int verb = 0 ;
00054 int opt ;
00055 int next = IN_END ;
00056 mxArray const *optarg ;
00057
00058 double const *I ;
00059 double *parents, *dists, *density ;
00060 int *parentsi;
00061 double sigma ;
00062 double tau ;
00063
00064 int K,N1,N2;
00065
00066 int medoid = 0 ;
00067
00068 mwSize const *dims ;
00069 int ndims ;
00070
00071 int i;
00072
00073 VlQS * q;
00074
00075 VL_USE_MATLAB_ENV ;
00076
00077
00078
00079
00080
00081 if (nin < 2) {
00082 mexErrMsgTxt("At least two arguments.") ;
00083 }
00084
00085 if (nout > 3) {
00086 mexErrMsgTxt("At most three output arguments.") ;
00087 }
00088
00089 ndims = mxGetNumberOfDimensions(in[IN_I]) ;
00090 dims = mxGetDimensions(in[IN_I]) ;
00091
00092 if (ndims > 3) {
00093 mexErrMsgTxt("I must have at most 3 dimensions.") ;
00094 }
00095
00096 if (mxGetClassID(in[IN_I]) != mxDOUBLE_CLASS) {
00097 mexErrMsgTxt("I must be DOUBLE.") ;
00098 }
00099
00100 N1 = dims [0] ;
00101 N2 = dims [1] ;
00102 K = (ndims == 3) ? dims [2] : 1 ;
00103
00104 I = mxGetPr (in[IN_I]) ;
00105 sigma = *mxGetPr (in[IN_KERNEL_SIZE]) ;
00106 tau = 3*sigma;
00107 if (nin > 2)
00108 tau = *mxGetPr (in[IN_MAX_DIST]) ;
00109
00110 while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00111 switch (opt) {
00112 case opt_medoid:
00113 medoid = 1 ;
00114 break ;
00115 case opt_verbose :
00116 ++ verb ;
00117 break ;
00118 }
00119 }
00120
00121
00122 out[OUT_PARENTS] = mxCreateDoubleMatrix(N1, N2, mxREAL) ;
00123 parents = mxGetPr (out[OUT_PARENTS]) ;
00124
00125 out[OUT_DISTS] = mxCreateDoubleMatrix(N1, N2, mxREAL) ;
00126 dists = mxGetPr (out[OUT_DISTS]) ;
00127
00128 out[OUT_DENSITY] = mxCreateDoubleMatrix(N1, N2, mxREAL) ;
00129 density = mxGetPr (out[OUT_DENSITY]) ;
00130
00131 if (verb) {
00132 mexPrintf("quickshift: [N1,N2,K]: [%d,%d,%d]\n", N1,N2,K) ;
00133 mexPrintf("quickshift: type: %s\n", medoid ? "medoid" : "quick");
00134 mexPrintf("quickshift: kernel size: %g\n", sigma) ;
00135 mexPrintf("quickshift: maximum gap: %g\n", tau) ;
00136 }
00137
00138
00139 q = vl_quickshift_new(I, N1, N2, K);
00140
00141 vl_quickshift_set_kernel_size (q, sigma) ;
00142 vl_quickshift_set_max_dist (q, tau) ;
00143 vl_quickshift_set_medoid (q, medoid) ;
00144
00145 vl_quickshift_process(q);
00146
00147 parentsi = vl_quickshift_get_parents(q);
00148
00149 for(i = 0; i < N1*N2; i++) parents[i] = parentsi[i] + 1;
00150 memcpy(dists, vl_quickshift_get_dists(q), sizeof(double)*N1*N2);
00151 memcpy(density, vl_quickshift_get_density(q), sizeof(double)*N1*N2);
00152
00153
00154 vl_quickshift_delete(q);
00155 }