00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <mexutils.h>
00015 #include <vl/mser.h>
00016 #include <vl/mathop.h>
00017 #include <assert.h>
00018
00019 enum {
00020 opt_delta = 0,
00021 opt_max_area,
00022 opt_min_area,
00023 opt_max_variation,
00024 opt_min_diversity,
00025 opt_bright_on_dark,
00026 opt_dark_on_bright,
00027 opt_verbose
00028 } ;
00029
00030 vlmxOption options [] = {
00031 {"Delta", 1, opt_delta },
00032 {"MaxArea", 1, opt_max_area },
00033 {"MinArea", 1, opt_min_area },
00034 {"MaxVariation", 1, opt_max_variation },
00035 {"MinDiversity", 1, opt_min_diversity },
00036 {"BrightOnDark", 1, opt_bright_on_dark },
00037 {"DarkOnBright", 1, opt_dark_on_bright },
00038 {"Verbose", 0, opt_verbose },
00039 {0, 0, 0 }
00040 } ;
00041
00043 void
00044 mexFunction(int nout, mxArray *out[],
00045 int nin, const mxArray *in[])
00046 {
00047 enum {IN_I = 0,
00048 IN_END } ;
00049 enum {OUT_SEEDS = 0,
00050 OUT_FRAMES } ;
00051
00052 int verbose = 0 ;
00053 int opt ;
00054 int next = IN_END ;
00055 mxArray const *optarg ;
00056
00057
00058 double delta = -1 ;
00059 double max_area = -1 ;
00060 double min_area = -1 ;
00061 double max_variation = -1 ;
00062 double min_diversity = -1 ;
00063 int bright_on_dark = 1 ;
00064 int dark_on_bright = 1 ;
00065
00066 int nel ;
00067 int ndims ;
00068 mwSize const* dims ;
00069
00070 vl_mser_pix const *data ;
00071 vl_mser_pix *datainv = 0;
00072
00073 VlMserFilt *filt, *filtinv ;
00074 vl_uint const *regions = 0 ;
00075 vl_uint const *regionsinv = 0 ;
00076 float const *frames = 0;
00077 float const *framesinv = 0 ;
00078 int nregions = 0, nregionsinv = 0;
00079 int nframes = 0, nframesinv = 0;
00080 int i, j, dof = 0 ;
00081 mwSize odims [2] ;
00082 double *pt ;
00083
00084 VL_USE_MATLAB_ENV ;
00085
00090 if (nin < 1) {
00091 mexErrMsgTxt("At least one input argument is required.") ;
00092 }
00093
00094 if (nout > 2) {
00095 mexErrMsgTxt("Too many output arguments.");
00096 }
00097
00098 if(mxGetClassID(in[IN_I]) != mxUINT8_CLASS) {
00099 mexErrMsgTxt("I must be of class UINT8") ;
00100 }
00101
00102
00103 nel = mxGetNumberOfElements(in[IN_I]) ;
00104 ndims = mxGetNumberOfDimensions(in[IN_I]) ;
00105 dims = mxGetDimensions(in[IN_I]) ;
00106 data = mxGetData(in[IN_I]) ;
00107
00108 while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00109 switch (opt) {
00110
00111 case opt_verbose :
00112 ++ verbose ;
00113 break ;
00114
00115 case opt_delta :
00116 if (!vlmxIsPlainScalar(optarg) || (delta = *mxGetPr(optarg)) < 0) {
00117 mexErrMsgTxt("'Delta' must be non-negative.") ;
00118 }
00119 break ;
00120
00121 case opt_max_area :
00122 if (!vlmxIsPlainScalar(optarg) ||
00123 (max_area = *mxGetPr(optarg)) < 0 ||
00124 max_area > 1) {
00125 mexErrMsgTxt("'MaxArea' must be in the range [0,1].") ;
00126 }
00127 break ;
00128
00129 case opt_min_area :
00130 if (!vlmxIsPlainScalar(optarg) ||
00131 (min_area = *mxGetPr(optarg)) < 0 ||
00132 min_area > 1) {
00133 mexErrMsgTxt("'MinArea' must be in the range [0,1].") ;
00134 }
00135 break ;
00136
00137 case opt_max_variation :
00138 if (!vlmxIsPlainScalar(optarg) ||
00139 (max_variation = *mxGetPr(optarg)) < 0) {
00140 mexErrMsgTxt("'MaxVariation' must be non negative.") ;
00141 }
00142 break ;
00143
00144 case opt_min_diversity :
00145 if (!vlmxIsPlainScalar(optarg) ||
00146 (min_diversity = *mxGetPr(optarg)) < 0 ||
00147 min_diversity > 1.0) {
00148 mexErrMsgTxt("'MinDiversity' must be in the [0,1] range.") ;
00149 }
00150 break ;
00151
00152 case opt_bright_on_dark :
00153 if (!vlmxIsPlainScalar(optarg) ||
00154 ((bright_on_dark = *mxGetPr(optarg)) != 0 &&
00155 bright_on_dark != 1)) {
00156 mexErrMsgTxt("'BrightOnDark' must be in 0 or 1.") ;
00157 }
00158 break ;
00159
00160 case opt_dark_on_bright :
00161 if (!vlmxIsPlainScalar(optarg) ||
00162 ((dark_on_bright = *mxGetPr(optarg)) != 0 &&
00163 dark_on_bright != 1)) {
00164 mexErrMsgTxt("'DarkOnBright' must be in 0 or 1.") ;
00165 }
00166 break ;
00167
00168 default :
00169 abort() ;
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178 {
00179 int * vlDims = mxMalloc(sizeof(int) * ndims) ;
00180 for (i = 0 ; i < ndims ; ++i) vlDims [i] = dims [i] ;
00181 filt = vl_mser_new (ndims, vlDims) ;
00182 filtinv = vl_mser_new (ndims, vlDims) ;
00183 mxFree(vlDims) ;
00184 }
00185 if (!filt || !filtinv) {
00186 mexErrMsgTxt("Could not create an MSER filter.") ;
00187 }
00188
00189 if (delta >= 0) vl_mser_set_delta (filt, (vl_mser_pix) delta) ;
00190 if (max_area >= 0) vl_mser_set_max_area (filt, max_area) ;
00191 if (min_area >= 0) vl_mser_set_min_area (filt, min_area) ;
00192 if (max_variation >= 0) vl_mser_set_max_variation (filt, max_variation) ;
00193 if (min_diversity >= 0) vl_mser_set_min_diversity (filt, min_diversity) ;
00194 if (delta >= 0) vl_mser_set_delta (filtinv, (vl_mser_pix) delta) ;
00195 if (max_area >= 0) vl_mser_set_max_area (filtinv, max_area) ;
00196 if (min_area >= 0) vl_mser_set_min_area (filtinv, min_area) ;
00197 if (max_variation >= 0) vl_mser_set_max_variation (filtinv, max_variation) ;
00198 if (min_diversity >= 0) vl_mser_set_min_diversity (filtinv, min_diversity) ;
00199
00200 if (verbose) {
00201 mexPrintf("mser: parameters:\n") ;
00202 mexPrintf("mser: delta = %d\n", vl_mser_get_delta (filt)) ;
00203 mexPrintf("mser: max_area = %g\n", vl_mser_get_max_area (filt)) ;
00204 mexPrintf("mser: min_area = %g\n", vl_mser_get_min_area (filt)) ;
00205 mexPrintf("mser: max_variation = %g\n", vl_mser_get_max_variation (filt)) ;
00206 mexPrintf("mser: min_diversity = %g\n", vl_mser_get_min_diversity (filt)) ;
00207 }
00208
00209
00210 if (dark_on_bright)
00211 {
00212
00213 vl_mser_process (filt, data) ;
00214
00215
00216 nregions = vl_mser_get_regions_num (filt) ;
00217 regions = vl_mser_get_regions (filt) ;
00218
00219 if (nout > 1) {
00220 vl_mser_ell_fit (filt) ;
00221
00222 dof = vl_mser_get_ell_dof (filt) ;
00223 nframes = vl_mser_get_ell_num (filt) ;
00224 frames = vl_mser_get_ell (filt) ;
00225 }
00226 }
00227
00228 if (bright_on_dark)
00229 {
00230 datainv = mxMalloc(sizeof(vl_uint)*nel) ;
00231 for(i=0; i<nel; i++) datainv[i] = ~data[i];
00232
00233
00234 vl_mser_process (filtinv, datainv) ;
00235
00236
00237 nregionsinv = vl_mser_get_regions_num (filtinv) ;
00238 regionsinv = vl_mser_get_regions (filtinv) ;
00239
00240 if (nout > 1) {
00241 vl_mser_ell_fit (filtinv) ;
00242
00243 dof = vl_mser_get_ell_dof (filtinv) ;
00244 nframesinv = vl_mser_get_ell_num (filtinv) ;
00245 framesinv = vl_mser_get_ell (filtinv) ;
00246 }
00247 }
00248
00249 odims [0] = nregions + nregionsinv ;
00250 out [OUT_SEEDS] = mxCreateNumericArray (1, odims, mxDOUBLE_CLASS,mxREAL) ;
00251 pt = mxGetPr (out [OUT_SEEDS]) ;
00252
00253 for (i = 0 ; i < nregions ; ++i)
00254 pt [i] = (int)regions [i] + 1 ;
00255
00256 for (i = nregions; i < nregions + nregionsinv; ++i)
00257 pt [i] = -((int)regionsinv [i-nregions] + 1) ;
00258
00259
00260 if (nout > 1) {
00261
00262 odims [0] = dof ;
00263 odims [1] = nframes + nframesinv;
00264
00265 out [OUT_FRAMES] = mxCreateNumericArray (2, odims, mxDOUBLE_CLASS, mxREAL) ;
00266 pt = mxGetPr (out [OUT_FRAMES]) ;
00267
00268 for (i = 0 ; i < nframes ; ++i) {
00269 for (j = 0 ; j < dof ; ++j) {
00270 pt [i * dof + j] = frames [i * dof + j] + ((j < ndims)?1.0:0.0) ;
00271 }
00272 }
00273
00274 for (i = nframes ; i < nframes + nframesinv ; ++i) {
00275 for (j = 0 ; j < dof ; ++j) {
00276 pt [i * dof + j] = framesinv [(i-nframes) * dof + j] + ((j < ndims)?1.0:0.0) ;
00277 }
00278 }
00279 }
00280
00281 if (verbose) {
00282 VlMserStats const* s = vl_mser_get_stats (filt) ;
00283 VlMserStats const* sinv = vl_mser_get_stats (filtinv) ;
00284 int tot = s-> num_extremal + sinv-> num_extremal ;
00285
00286 mexPrintf("mser: statistics:\n") ;
00287 mexPrintf("mser: %d extremal regions of which\n", tot) ;
00288
00289 #define REMAIN(test,num) \
00290 mexPrintf("mser: %5d (%7.3g %% of previous) " test "\n", \
00291 tot-(num),100.0*(double)(tot-(num))/(tot+VL_EPSILON_D)) ; \
00292 tot -= (num) ;
00293
00294 REMAIN("maximally stable,", s-> num_unstable + sinv-> num_unstable ) ;
00295 REMAIN("stable enough,", s-> num_abs_unstable + sinv-> num_abs_unstable ) ;
00296 REMAIN("small enough,", s-> num_too_big + sinv->num_too_big ) ;
00297 REMAIN("big enough,", s-> num_too_small + sinv->num_too_small ) ;
00298 REMAIN("diverse enough.", s-> num_duplicates + sinv->num_duplicates ) ;
00299
00300 }
00301
00302
00303 if (datainv) mxFree(datainv);
00304 vl_mser_delete (filt) ;
00305 vl_mser_delete (filtinv) ;
00306 }