Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
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
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
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
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
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
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
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 }