vl_inthist.c
Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2007-12 Andrea Vedaldi and Brian Fulkerson.
00009 All rights reserved.
00010 
00011 This file is part of the VLFeat library and is made available under
00012 the terms of the BSD license (see the COPYING file).
00013 */
00014 
00015 #include <mexutils.h>
00016 
00017 #include <vl/generic.h>
00018 
00019 #include <stdlib.h>
00020 #include <string.h>
00021 #include <math.h>
00022 
00023 enum {opt_mass = 1, opt_numLabels, opt_verbose} ;
00024 
00025 /* options */
00026 vlmxOption  options [] = {
00027   {"Mass",         1,   opt_mass,         },
00028   {"NumLabels",    1,   opt_numLabels     },
00029   {"Verbose",      0,   opt_verbose       },
00030   {0,              0,   0                 }
00031 } ;
00032 
00033 #undef T
00034 #undef SFX
00035 #define T vl_int32
00036 #define SFX i
00037 #include "inthist.tc"
00038 
00039 #undef T
00040 #undef SFX
00041 #define T vl_uint32
00042 #define SFX ui
00043 #include "inthist.tc"
00044 
00045 #undef T
00046 #undef SFX
00047 #define T double
00048 #define SFX d
00049 #include "inthist.tc"
00050 
00051 #undef T
00052 #undef SFX
00053 #define T float
00054 #define SFX f
00055 #include "inthist.tc"
00056 
00057 void
00058 mexFunction(int nout, mxArray *out[],
00059             int nin, const mxArray *in[])
00060 {
00061   mwSize dims [3] ;
00062   vl_size numDims ;
00063   mwSize const * dimsPt = 0 ;
00064 
00065   vl_uint32* labelsPt  = 0 ;
00066   void*      massPt    = 0 ;
00067   void*      histPt    = 0 ;
00068   vl_uint32  numLabels = 0 ;
00069   mxClassID  dataClass = mxUINT32_CLASS ;
00070   vl_size width, height, numMaps ;
00071   vl_uindex k, q ;
00072 
00073   enum {IN_LABELS = 0, IN_END} ;
00074   enum {OUT_HIST = 0} ;
00075   int opt ;
00076   int nextOpt = IN_END ;
00077   mxArray const  *optArg ;
00078   int verb = 0 ;
00079 
00080   /* ------------------------------------------------------------------
00081   **                                                Check the arguments
00082   ** --------------------------------------------------------------- */
00083   if (nin < 1) {
00084     mexErrMsgTxt("At least one input argument is required.") ;
00085   } else if (nout > 1) {
00086     mexErrMsgTxt("Too many output arguments.");
00087   }
00088 
00089   if (mxGetClassID(IN(LABELS)) != mxUINT32_CLASS) {
00090     mexErrMsgTxt("LABELS must be of class UINT32.") ;
00091   }
00092   labelsPt = mxGetData(IN(LABELS)) ;
00093 
00094   numDims = mxGetNumberOfDimensions(IN(LABELS)) ;
00095   if (numDims > 3) {
00096     mexErrMsgTxt("LABELS must be a MxNxK array.") ;
00097   }
00098 
00099   labelsPt = mxGetData(IN(LABELS)) ;
00100   dimsPt   = mxGetDimensions(IN(LABELS)) ;
00101   height   = dimsPt [0] ;
00102   width    = dimsPt [1] ;
00103   if (numDims > 2) {
00104     numMaps = dimsPt [2] ;
00105   } else {
00106     numMaps = 1 ;
00107   }
00108 
00109   while ((opt = vlmxNextOption (in, nin, options, &nextOpt, &optArg)) >= 0) {
00110     switch (opt) {
00111     case opt_mass :
00112       {
00113         massPt = mxGetData(optArg) ;
00114         dimsPt = mxGetDimensions(optArg) ;
00115 
00116         if (mxGetNumberOfDimensions(optArg) != numDims ||
00117             height != dimsPt [0] ||
00118             width  != dimsPt [1] ||
00119             ((numDims > 2) && numMaps < dimsPt[2])) {
00120           mexErrMsgTxt("MASS must have the same dimensions of LABELS.") ;
00121         }
00122 
00123         /* the data is DOUBLE or UINT32 depending on the class of MASS */
00124         dataClass = mxGetClassID(optArg) ;
00125         if (dataClass != mxDOUBLE_CLASS &&
00126             dataClass != mxUINT32_CLASS) {
00127           mexErrMsgTxt("MASS must be of either class DOUBLE or UINT32.") ;
00128         }
00129         break ;
00130       }
00131 
00132     case opt_numLabels :
00133       if (!vlmxIsPlainScalar(optArg)) {
00134         mexErrMsgTxt("NUMLABELS must be a real scalar.") ;
00135       }
00136       numLabels = *mxGetPr(optArg) ;
00137       break ;
00138 
00139     case opt_verbose :
00140       ++ verb ;
00141       break ;
00142 
00143     default:
00144       abort() ;
00145     }
00146   }
00147 
00148   /* If numLabels is not specified, guess it from LABELS */
00149   if (numLabels == 0) {
00150     for (k = 0 ; k < width*height ; ++k) {
00151       numLabels = VL_MAX(numLabels, labelsPt [k]) ;
00152     }
00153   } else {
00154     for (k = 0 ; k < width*height ; ++k) {
00155       if (labelsPt [k] > numLabels) {
00156         mexErrMsgTxt("LABELS contains an element greater than NUMLABELS.") ;
00157       }
00158     }
00159   }
00160 
00161   /* Allocate space for the integral histogram */
00162   dims [0] = height ;
00163   dims [1] = width ;
00164   dims [2] = numLabels ;
00165   OUT(HIST) = mxCreateNumericArray(3, dims, dataClass, mxREAL) ;
00166   histPt = mxGetData(OUT(HIST)) ;
00167 
00168   if (verb) {
00169     mexPrintf("inthist: integrating %d x %d label map with %d labels\n", width, height, numLabels) ;
00170     mexPrintf("         custom mass map: %s\n", VL_YESNO(massPt)) ;
00171   }
00172 
00173   /* ------------------------------------------------------------------
00174    *                                                    Distribute data
00175    * --------------------------------------------------------------- */
00176 
00177 #define PROCESS(T, INTEGRAL)                                            \
00178   size_t const K = width*height ;                                       \
00179   T* dataPt = histPt ;                                                  \
00180   if (massPt == 0) {                                                    \
00181     for (q = 0 ; q < numMaps ; ++ q) {                                  \
00182       for (k = 0 ; k < K ; ++ k) {                                      \
00183         size_t label = *labelsPt++ ;                                    \
00184         if (label) dataPt [k + (label - 1) * K] += (T) 1 ;              \
00185       }                                                                 \
00186     }                                                                   \
00187   } else {                                                              \
00188     for (q = 0 ; q < numMaps ; ++q) {                                   \
00189       for (k = 0 ; k < K ; ++ k) {                                      \
00190         size_t label = *labelsPt++ ;                                    \
00191         if (label) dataPt [k + (label - 1) * K]                         \
00192                      += ((T*)massPt) [k] ;                              \
00193       }                                                                 \
00194     }                                                                   \
00195   }                                                                     \
00196   for (k = 0 ; k < numLabels ; ++k) {                                   \
00197     INTEGRAL (dataPt + k*K, height,                                     \
00198               dataPt + k*K, height, width, height) ;                    \
00199   }
00200 
00201   switch (dataClass) {
00202   case mxUINT32_CLASS: { PROCESS(vl_uint32, integral_ui) } ; break ;
00203   case mxDOUBLE_CLASS: { PROCESS(double,    integral_d)  } ; break ;
00204   default :
00205     abort() ;
00206   }
00207 }


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