00001
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <mexutils.h>
00016 #include <vl/liop.h>
00017 #include <vl/mathop.h>
00018
00019 #include <assert.h>
00020
00021
00022 enum {
00023 opt_num_neighbours,
00024 opt_num_spatial_bins,
00025 opt_radius,
00026 opt_intensity_threshold,
00027 opt_verbose
00028 } ;
00029
00030
00031 vlmxOption options [] = {
00032 {"NumNeighbours", 1, opt_num_neighbours },
00033 {"NumSpatialBins", 1, opt_num_spatial_bins },
00034 {"Radius", 1, opt_radius },
00035 {"IntensityThreshold", 1, opt_intensity_threshold },
00036 {"Verbose", 0, opt_verbose },
00037 {0, 0, 0 }
00038 } ;
00039
00044 void
00045 mexFunction(int nout, mxArray *out[],
00046 int nin, const mxArray *in[])
00047 {
00048 enum {IN_I=0, IN_END} ;
00049 enum {OUT_DESCRIPTOR = 0} ;
00050
00051 int verbose = 0 ;
00052 int opt ;
00053 int next = IN_END ;
00054 mxArray const *optarg ;
00055
00056 float *data ;
00057 vl_size M, N ;
00058
00059 int numNeighbours = 4 ;
00060 int numSpatialBins = 6 ;
00061 float radius = 6.0 ;
00062 float intensityThreshold = VL_NAN_F ;
00063 vl_size numPatches = 1 ;
00064 mwSize const * dimensions ;
00065
00066 VL_USE_MATLAB_ENV ;
00067
00068
00069
00070
00071
00072 if (nin < 1) {
00073 vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
00074 } else if (nout > 2) {
00075 vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
00076 }
00077
00078 if (mxGetClassID(in[IN_I]) != mxSINGLE_CLASS ) {
00079 vlmxError(vlmxErrInvalidArgument,
00080 "I must be a matrix of class SINGLE.") ;
00081 }
00082
00083 dimensions = mxGetDimensions(IN(I)) ;
00084 if(mxGetNumberOfDimensions(IN(I)) == 2){
00085 numPatches = 1 ;
00086 } else if (mxGetNumberOfDimensions(IN(I)) == 3) {
00087 numPatches = (vl_size) dimensions [2] ;
00088 } else {
00089 vlmxError(vlmxErrInvalidArgument,
00090 "I must be a matrix with 2 or 3 dimensions.") ;
00091 }
00092
00093 data = (float*) mxGetData (in[IN_I]) ;
00094 M = (vl_size) dimensions[0] ;
00095 N = (vl_size) dimensions[1] ;
00096
00097 if((N != M) || (N % 2 == 0)){
00098 vlmxError(vlmxErrInvalidArgument,
00099 "I is not square or does not have an odd side length.") ;
00100 }
00101
00102 while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00103 switch (opt) {
00104
00105 case opt_verbose :
00106 ++ verbose ;
00107 break ;
00108
00109 case opt_num_neighbours :
00110 if (!vlmxIsPlainScalar(optarg) || (numNeighbours = (int) *mxGetPr(optarg)) < 2) {
00111 vlmxError(vlmxErrInvalidArgument,"NUMNEIGHBOURS is not a scalar or it is less than two.") ;
00112 }
00113 break ;
00114
00115 case opt_num_spatial_bins :
00116 if (!vlmxIsPlainScalar(optarg) || (numSpatialBins = (int) *mxGetPr(optarg)) <= 0) {
00117 vlmxError(vlmxErrInvalidArgument,"NUMSPATIALBINS is not a positive integer.") ;
00118 }
00119 break ;
00120
00121 case opt_radius :
00122 if (!vlmxIsPlainScalar(optarg) || (radius = (int) *mxGetPr(optarg)) <= 0) {
00123 vlmxError(vlmxErrInvalidArgument,"RADIUS is not a positive scalar.") ;
00124 }
00125 break ;
00126
00127 case opt_intensity_threshold :
00128 if (!vlmxIsPlainScalar(optarg)) {
00129 vlmxError(vlmxErrInvalidArgument,"INTENSITYTHRESHOLD is not a scalar.") ;
00130 }
00131 intensityThreshold = *mxGetPr(optarg) ;
00132 break ;
00133
00134 default :
00135 abort() ;
00136 }
00137 }
00138
00139 if (radius >= M / 2) {
00140 vlmxError(vlmxErrInconsistentData, "RADIUS is larger than half the width of I.") ;
00141 }
00142
00143
00144
00145
00146 {
00147
00148 VlLiopDesc *liop ;
00149 float * desc ;
00150 vl_size dimension ;
00151 vl_index i ;
00152
00153 liop = vl_liopdesc_new (numNeighbours, numSpatialBins, radius, M) ;
00154 if (!vl_is_nan_f(intensityThreshold)) {
00155 vl_liopdesc_set_intensity_threshold(liop, intensityThreshold) ;
00156 }
00157 dimension = vl_liopdesc_get_dimension(liop) ;
00158
00159 out[OUT_DESCRIPTOR] = mxCreateNumericMatrix(dimension, numPatches, mxSINGLE_CLASS, mxREAL);
00160 desc = mxGetData(out[OUT_DESCRIPTOR]) ;
00161
00162 for (i = 0 ; i < (signed)numPatches ; ++i) {
00163 vl_liopdesc_process(liop, desc + dimension * i, data + (M*M) * i) ;
00164 }
00165
00166 if (verbose) {
00167 mexPrintf("vl_liop: image size: [W, H] = [%d, %d]\n", N, M) ;
00168 mexPrintf("vl_liop: num images: %d\n", numPatches) ;
00169 mexPrintf("vl_liop: num neighbours: %d\n", vl_liopdesc_get_num_neighbours(liop)) ;
00170 mexPrintf("vl_liop: num spatial bins: %d\n", vl_liopdesc_get_num_spatial_bins(liop)) ;
00171 mexPrintf("vl_liop: neighbourhood radius: %f\n", vl_liopdesc_get_neighbourhood_radius(liop)) ;
00172 mexPrintf("vl_liop: intensity threshold %f\n", vl_liopdesc_get_intensity_threshold(liop)) ;
00173 mexPrintf("vl_liop: descriptor dimension: %d\n", vl_liopdesc_get_dimension(liop)) ;
00174 }
00175 }
00176 }