vl_mser.c
Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00008 All rights reserved.
00009 
00010 This file is part of the VLFeat library and is made available under
00011 the terms of the BSD license (see the COPYING file).
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   /* algorithm parameters */
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   /* get dimensions */
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    *                                                     Run algorithm
00175    * -------------------------------------------------------------- */
00176 
00177   /* new filter */
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     /* process the image */
00213     vl_mser_process (filt, data) ;
00214 
00215     /* save regions back to array */
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]; /* 255 - data */
00232 
00233     /* process the image */
00234     vl_mser_process (filtinv, datainv) ;
00235 
00236     /* save regions back to array */
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) ; /* Inverted seed means dark on bright */
00258 
00259   /* optionally compute and save ellipsoids */
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   /* cleanup */
00303   if (datainv) mxFree(datainv);
00304   vl_mser_delete (filt) ;
00305   vl_mser_delete (filtinv) ;
00306 }


libvlfeat
Author(s): Andrea Vedaldi
autogenerated on Thu Jun 6 2019 20:25:51