00001
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <mexutils.h>
00016 #include <vl/mathop.h>
00017 #include <vl/dsift.h>
00018
00019 #include <math.h>
00020 #include <assert.h>
00021
00022
00023 enum {
00024 opt_step = 0,
00025 opt_bounds,
00026 opt_size,
00027 opt_fast,
00028 opt_norm,
00029 opt_window_size,
00030 opt_float_descriptors,
00031 opt_geometry,
00032 opt_verbose
00033 } ;
00034
00035
00036 vlmxOption options [] = {
00037 {"Bounds", 1, opt_bounds },
00038 {"Step", 1, opt_step },
00039 {"Size", 1, opt_size },
00040 {"Fast", 0, opt_fast },
00041 {"Norm", 0, opt_norm },
00042 {"WindowSize", 1, opt_window_size },
00043 {"FloatDescriptors", 0, opt_float_descriptors},
00044 {"Geometry", 1, opt_geometry },
00045 {"Verbose", 0, opt_verbose },
00046 {0, 0, 0 }
00047 } ;
00048
00053 void
00054 mexFunction(int nout, mxArray *out[],
00055 int nin, const mxArray *in[])
00056 {
00057 enum {IN_I=0, IN_END} ;
00058 enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ;
00059
00060 int verbose = 0 ;
00061 int opt ;
00062 int next = IN_END ;
00063 mxArray const *optarg ;
00064
00065 float const *data ;
00066 int M, N ;
00067
00068 int step [2] = {1,1} ;
00069 vl_bool norm = 0 ;
00070
00071 vl_bool floatDescriptors = VL_FALSE ;
00072 vl_bool useFlatWindow = VL_FALSE ;
00073 double windowSize = -1.0 ;
00074
00075 double *bounds = NULL ;
00076 double boundBuffer [4] ;
00077 VlDsiftDescriptorGeometry geom ;
00078
00079 VL_USE_MATLAB_ENV ;
00080
00081 geom.numBinX = 4 ;
00082 geom.numBinY = 4 ;
00083 geom.numBinT = 8 ;
00084 geom.binSizeX = 3 ;
00085 geom.binSizeY = 3 ;
00086
00087
00088
00089
00090
00091 if (nin < 1) {
00092 vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
00093 } else if (nout > 2) {
00094 vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
00095 }
00096
00097 if (mxGetNumberOfDimensions (in[IN_I]) != 2 ||
00098 mxGetClassID (in[IN_I]) != mxSINGLE_CLASS ) {
00099 vlmxError(vlmxErrInvalidArgument,
00100 "I must be a matrix of class SINGLE.") ;
00101 }
00102
00103 data = (float*) mxGetData (in[IN_I]) ;
00104 M = mxGetM (in[IN_I]) ;
00105 N = mxGetN (in[IN_I]) ;
00106
00107 while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00108 switch (opt) {
00109
00110 case opt_verbose :
00111 ++ verbose ;
00112 break ;
00113
00114 case opt_fast :
00115 useFlatWindow = 1 ;
00116 break ;
00117
00118 case opt_norm :
00119 norm = 1 ;
00120 break ;
00121
00122 case opt_bounds :
00123 if (!vlmxIsPlainVector(optarg, 4)) {
00124 mexErrMsgTxt("BOUNDS must be a 4-dimensional vector.") ;
00125 }
00126 bounds = boundBuffer ;
00127 bounds [0] = mxGetPr(optarg)[0] - 1 ;
00128 bounds [1] = mxGetPr(optarg)[1] - 1 ;
00129 bounds [2] = mxGetPr(optarg)[2] - 1 ;
00130 bounds [3] = mxGetPr(optarg)[3] - 1 ;
00131 break ;
00132
00133 case opt_size :
00134 if (!vlmxIsPlainVector(optarg,-1)) {
00135 vlmxError(vlmxErrInvalidArgument,"SIZE is not a plain vector.") ;
00136 }
00137 if (mxGetNumberOfElements(optarg) == 1) {
00138 geom.binSizeX = (int) mxGetPr(optarg)[0] ;
00139 geom.binSizeY = (int) mxGetPr(optarg)[0] ;
00140 } else if (mxGetNumberOfElements(optarg) == 2) {
00141 geom.binSizeX = (int) mxGetPr(optarg)[1] ;
00142 geom.binSizeY = (int) mxGetPr(optarg)[0] ;
00143 } else {
00144 vlmxError(vlmxErrInvalidArgument,"SIZE is neither a scalar or a 2D vector.") ;
00145 }
00146 if (geom.binSizeX < 1 || geom.binSizeY < 1) {
00147 vlmxError(vlmxErrInvalidArgument,"SIZE value is invalid.") ;
00148 }
00149 break ;
00150
00151 case opt_step :
00152 if (!vlmxIsPlainVector(optarg,-1)) {
00153 vlmxError(vlmxErrInvalidArgument,"STEP is not a plain vector.") ;
00154 }
00155 if (mxGetNumberOfElements(optarg) == 1) {
00156 step[0] = (int) mxGetPr(optarg)[0] ;
00157 step[1] = (int) mxGetPr(optarg)[0] ;
00158 } else if (mxGetNumberOfElements(optarg) == 2) {
00159 step[0] = (int) mxGetPr(optarg)[1] ;
00160 step[1] = (int) mxGetPr(optarg)[0] ;
00161 } else {
00162 vlmxError(vlmxErrInvalidArgument,"STEP is neither a scalar or a 2D vector.") ;
00163 }
00164 if (step[0] < 1 || step[1] < 1) {
00165 vlmxError(vlmxErrInvalidArgument,"STEP value is invalid.") ;
00166 }
00167 break ;
00168
00169 case opt_window_size :
00170 if (!vlmxIsPlainScalar(optarg) || (windowSize = *mxGetPr(optarg)) < 0) {
00171 vlmxError(vlmxErrInvalidArgument,"WINDOWSIZE is not a scalar or it is negative.") ;
00172 }
00173 break ;
00174
00175 case opt_float_descriptors :
00176 floatDescriptors = VL_TRUE ;
00177 break ;
00178
00179 case opt_geometry :
00180 if (!vlmxIsPlainVector(optarg,3)) {
00181 vlmxError(vlmxErrInvalidArgument, "GEOMETRY is not a 3D vector.") ;
00182 }
00183 geom.numBinY = (int)mxGetPr(optarg)[0] ;
00184 geom.numBinX = (int)mxGetPr(optarg)[1] ;
00185 geom.numBinT = (int)mxGetPr(optarg)[2] ;
00186 if (geom.numBinX < 1 ||
00187 geom.numBinY < 1 ||
00188 geom.numBinT < 1) {
00189 vlmxError(vlmxErrInvalidArgument, "GEOMETRY value is invalid.") ;
00190 }
00191 break ;
00192
00193 default :
00194 abort() ;
00195 }
00196 }
00197
00198
00199
00200
00201 {
00202 int numFrames ;
00203 int descrSize ;
00204 VlDsiftKeypoint const *frames ;
00205 float const *descrs ;
00206 int k, i ;
00207
00208 VlDsiftFilter *dsift ;
00209
00210
00211 dsift = vl_dsift_new (M, N) ;
00212 vl_dsift_set_geometry(dsift, &geom) ;
00213 vl_dsift_set_steps(dsift, step[0], step[1]) ;
00214
00215 if (bounds) {
00216 vl_dsift_set_bounds(dsift,
00217 VL_MAX(bounds[1], 0),
00218 VL_MAX(bounds[0], 0),
00219 VL_MIN(bounds[3], M - 1),
00220 VL_MIN(bounds[2], N - 1));
00221 }
00222 vl_dsift_set_flat_window(dsift, useFlatWindow) ;
00223
00224 if (windowSize >= 0) {
00225 vl_dsift_set_window_size(dsift, windowSize) ;
00226 }
00227
00228 numFrames = vl_dsift_get_keypoint_num (dsift) ;
00229 descrSize = vl_dsift_get_descriptor_size (dsift) ;
00230 geom = *vl_dsift_get_geometry (dsift) ;
00231
00232 if (verbose) {
00233 int stepX ;
00234 int stepY ;
00235 int minX ;
00236 int minY ;
00237 int maxX ;
00238 int maxY ;
00239 vl_bool useFlatWindow ;
00240
00241 vl_dsift_get_steps (dsift, &stepY, &stepX) ;
00242 vl_dsift_get_bounds (dsift, &minY, &minX, &maxY, &maxX) ;
00243 useFlatWindow = vl_dsift_get_flat_window(dsift) ;
00244
00245 mexPrintf("vl_dsift: image size [W, H] = [%d, %d]\n", N, M) ;
00246 mexPrintf("vl_dsift: bounds: [minX,minY,maxX,maxY] = [%d, %d, %d, %d]\n",
00247 minX+1, minY+1, maxX+1, maxY+1) ;
00248 mexPrintf("vl_dsift: subsampling steps: stepX=%d, stepY=%d\n", stepX, stepY) ;
00249 mexPrintf("vl_dsift: num bins: [numBinT, numBinX, numBinY] = [%d, %d, %d]\n",
00250 geom.numBinT,
00251 geom.numBinX,
00252 geom.numBinY) ;
00253 mexPrintf("vl_dsift: descriptor size: %d\n", descrSize) ;
00254 mexPrintf("vl_dsift: bin sizes: [binSizeX, binSizeY] = [%d, %d]\n",
00255 geom.binSizeX,
00256 geom.binSizeY) ;
00257 mexPrintf("vl_dsift: flat window: %s\n", VL_YESNO(useFlatWindow)) ;
00258 mexPrintf("vl_dsift: window size: %g\n", vl_dsift_get_window_size(dsift)) ;
00259 mexPrintf("vl_dsift: num of features: %d\n", numFrames) ;
00260 }
00261
00262 vl_dsift_process (dsift, data) ;
00263
00264 frames = vl_dsift_get_keypoints (dsift) ;
00265 descrs = vl_dsift_get_descriptors (dsift) ;
00266
00267
00268
00269
00270 {
00271 mwSize dims [2] ;
00272
00273 dims [0] = descrSize ;
00274 dims [1] = numFrames ;
00275
00276 if (floatDescriptors) {
00277 out[OUT_DESCRIPTORS] = mxCreateNumericArray
00278 (2, dims, mxSINGLE_CLASS, mxREAL) ;
00279 } else {
00280 out[OUT_DESCRIPTORS] = mxCreateNumericArray
00281 (2, dims, mxUINT8_CLASS, mxREAL) ;
00282 }
00283
00284 dims [0] = norm ? 3 : 2 ;
00285
00286 out[OUT_FRAMES] = mxCreateNumericArray
00287 (2, dims, mxDOUBLE_CLASS, mxREAL) ;
00288 }
00289
00290
00291
00292
00293 {
00294 float *tmpDescr = mxMalloc(sizeof(float) * descrSize) ;
00295 double *outFrameIter = mxGetPr(out[OUT_FRAMES]) ;
00296 void *outDescrIter = mxGetData(out[OUT_DESCRIPTORS]) ;
00297 for (k = 0 ; k < numFrames ; ++k) {
00298 *outFrameIter++ = frames[k].y + 1 ;
00299 *outFrameIter++ = frames[k].x + 1 ;
00300
00301
00302
00303 if (norm)
00304 *outFrameIter++ = frames [k].norm ;
00305
00306 vl_dsift_transpose_descriptor (tmpDescr,
00307 descrs + descrSize * k,
00308 geom.numBinT,
00309 geom.numBinX,
00310 geom.numBinY) ;
00311
00312 if (floatDescriptors) {
00313 for (i = 0 ; i < descrSize ; ++i) {
00314 float * pt = (float*) outDescrIter ;
00315 *pt++ = VL_MIN(512.0F * tmpDescr[i], 255.0F) ;
00316 outDescrIter = pt ;
00317 }
00318 } else {
00319 for (i = 0 ; i < descrSize ; ++i) {
00320 vl_uint8 * pt = (vl_uint8*) outDescrIter ;
00321 *pt++ = (vl_uint8) (VL_MIN(512.0F * tmpDescr[i], 255.0F)) ;
00322 outDescrIter = pt ;
00323
00324 }
00325 }
00326 }
00327 mxFree(tmpDescr) ;
00328 }
00329 vl_dsift_delete (dsift) ;
00330 }
00331 }