vl_hog.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/hog.h>
00016 
00017 /* option codes */
00018 enum {
00019   opt_verbose, opt_variant,
00020   opt_num_orientations,
00021   opt_directed_polar_field,
00022   opt_undirected_polar_field,
00023   opt_bilinear_orientations
00024 } ;
00025 
00026 /* options */
00027 vlmxOption  options [] = {
00028   {"Verbose",              0,   opt_verbose                      },
00029   {"Variant",              1,   opt_variant                      },
00030   {"NumOrientations",      1,   opt_num_orientations             },
00031   {"DirectedPolarField",   0,   opt_directed_polar_field         },
00032   {"UndirectedPolarField", 0,   opt_undirected_polar_field       },
00033   {"BilinearOrientations", 0,   opt_bilinear_orientations        },
00034   {0,                      0,   0                                }
00035 } ;
00036 
00037 enum Mode {ExtractFeatures, Render, GetPermutation} ;
00038 enum InputType {Image, DirectedPolarField, UndirectedPolarField} ;
00039 
00040 static char const * inputTypeNames [] = {
00041   "Image",
00042   "DirectedPolarField",
00043   "UndirectedPolarField"
00044 } ;
00045 
00046 void
00047 mexFunction(int nout, mxArray *out[],
00048             int nin, const mxArray *in[])
00049 {
00050   mxArray const * descriptor_array ;
00051   float const * descriptor = NULL ;
00052   float const * image = NULL ;
00053   vl_size width = 0, height = 0, numChannels = 0 ;
00054   vl_size cellSize = 16 ;
00055   vl_size numOrientations = 9 ;
00056   vl_bool bilinearOrientations = VL_FALSE ;
00057   VlHogVariant variant = VlHogVariantUoctti ;
00058   char const * variantName ;
00059   enum {IN_I = 0, IN_CELLSIZE, IN_END} ;
00060   enum {OUT_FEATURES = 0} ;
00061 
00062   vl_bool verbose = 0 ;
00063   int opt, next ;
00064   mxArray const *optarg ;
00065 
00066   enum Mode mode = ExtractFeatures ;
00067   enum InputType inputType = Image ;
00068 
00069 
00070   /* -----------------------------------------------------------------
00071    *                                               Check the arguments
00072    * -------------------------------------------------------------- */
00073 
00074   if (nin < 1) {
00075     vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
00076   }
00077   if (nout > 1) {
00078     vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
00079   }
00080 
00081   if (vlmxIsString(IN(I), -1)) {
00082     mxArray const * string_array = IN(I) ;
00083     if (vlmxIsEqualToStringI(string_array, "permutation")) {
00084       /* perm = vl_hog('permutation') */
00085       mode = GetPermutation ;
00086       next = 1 ;
00087 
00088     } else if (vlmxIsEqualToStringI(string_array, "render")) {
00089       /* image = vl_hog('render', descriptor) */
00090       mode = Render ;
00091       descriptor_array = IN(CELLSIZE) ;
00092       next = 2 ;
00093       if (! mxIsNumeric(descriptor_array) ||
00094           ! vlmxIsReal(descriptor_array) ||
00095           mxGetClassID(descriptor_array) != mxSINGLE_CLASS) {
00096         vlmxError(vlmxErrInvalidArgument,
00097         "DESCRIPTOR is not a real numeric array of class SINGLE.") ;
00098       }
00099       if (mxGetNumberOfDimensions(descriptor_array) > 3) {
00100         vlmxError(vlmxErrInvalidArgument,
00101                   "DESCRIPTOR has more than three dimensions.") ;
00102       }
00103       if (mxGetNumberOfDimensions(descriptor_array) == 3) {
00104         numChannels = mxGetDimensions(descriptor_array)[2] ;
00105       } else {
00106         numChannels = 1 ;
00107       }
00108       descriptor = mxGetData(descriptor_array) ;
00109       height = mxGetDimensions(descriptor_array)[0] ;
00110       width = mxGetDimensions(descriptor_array)[1] ;
00111     } else {
00112       vlmxError(vlmxErrInvalidArgument,
00113                 "The first argument is neither an image nor a recognized command.") ;
00114     }
00115   } else {
00116     /* descriptor = vl_hog(image, cellSize) */
00117     mode = ExtractFeatures ;
00118     next = 2 ;
00119     if (nin < 2) {
00120       vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
00121     }
00122     if (! mxIsNumeric(IN(I)) ||
00123         ! vlmxIsReal(IN(I)) ||
00124         mxGetClassID(IN(I)) != mxSINGLE_CLASS) {
00125       vlmxError(vlmxErrInvalidArgument,
00126                 "I is not a real numeric array of class SINGLE.") ;
00127     }
00128     if (mxGetNumberOfDimensions(IN(I)) > 3) {
00129       vlmxError(vlmxErrInvalidArgument,
00130                 "I has more than three dimensions.") ;
00131     }
00132     if (mxGetNumberOfDimensions(IN(I)) == 3) {
00133       numChannels = mxGetDimensions(IN(I))[2] ;
00134     } else {
00135       numChannels = 1 ;
00136     }
00137     if (! vlmxIsPlainScalar(IN(CELLSIZE))) {
00138       vlmxError(vlmxErrInvalidArgument,
00139                 "CELLSIZE is not a plain scalar.") ;
00140     }
00141     if (mxGetScalar(IN(CELLSIZE)) < 1.0) {
00142       vlmxError(vlmxErrInvalidArgument,
00143                 "CELLSIZE is less than 1.") ;
00144     }
00145     cellSize = (vl_size) mxGetScalar(IN(CELLSIZE)) ;
00146     image = mxGetData(IN(I)) ;
00147     height = mxGetDimensions(IN(I))[0] ;
00148     width = mxGetDimensions(IN(I))[1] ;
00149   }
00150 
00151   /* parse the options */
00152   while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00153     switch (opt) {
00154       case opt_variant :
00155         if (! vlmxIsString(optarg, -1)) {
00156           vlmxError(vlmxErrInvalidArgument, "VARIANT must be a string") ;
00157         }
00158         if (vlmxIsEqualToStringI(optarg, "uoctti")) {
00159           variant = VlHogVariantUoctti ;
00160         } else if (vlmxIsEqualToStringI(optarg, "dalaltriggs")) {
00161           variant = VlHogVariantDalalTriggs ;
00162         } else {
00163           vlmxError(vlmxErrInvalidArgument, "The option VARIANT has an unknown value.") ;
00164         }
00165         break ;
00166 
00167       case opt_num_orientations :
00168         if (! vlmxIsPlainScalar(optarg)) {
00169           vlmxError(vlmxErrInvalidArgument, "NUMORIENTATIONS is not a plain scalar.") ;
00170         }
00171         if (mxGetScalar(optarg) < 1) {
00172           vlmxError(vlmxErrInvalidArgument, "NUMORIENTATIONS is smaller than one.") ;
00173         }
00174         numOrientations = mxGetScalar(optarg) ;
00175         break;
00176 
00177       case opt_directed_polar_field :
00178         inputType = DirectedPolarField ;
00179         break ;
00180 
00181       case opt_undirected_polar_field :
00182         inputType = UndirectedPolarField ;
00183         break ;
00184 
00185       case opt_bilinear_orientations :
00186         bilinearOrientations = VL_TRUE ;
00187         break ;
00188 
00189       case opt_verbose :
00190         ++ verbose ;
00191         break ;
00192     }
00193   }
00194 
00195   /* -----------------------------------------------------------------
00196    *                                                        Do the job
00197    * -------------------------------------------------------------- */
00198 
00199   switch (variant) {
00200     case VlHogVariantUoctti : variantName = "UOCTTI" ; break ;
00201     case VlHogVariantDalalTriggs : variantName = "DalalTriggs" ; break ;
00202     default: abort() ; break ;
00203   }
00204 
00205   switch (mode) {
00206     case ExtractFeatures :
00207     {
00208       /* recall that MATLAB images are transposed */
00209       VlHog * hog = vl_hog_new (variant, numOrientations, VL_TRUE) ;
00210       mwSize dimensions [3] ;
00211 
00212       vl_hog_set_use_bilinear_orientation_assignments (hog, bilinearOrientations) ;
00213 
00214       if ((inputType == DirectedPolarField ||
00215            inputType == UndirectedPolarField) &&
00216           numChannels != 2) {
00217         vlmxError(vlmxErrInvalidArgument,
00218                   "NUMCHANNELS=%d is not equal to two with input of type %s.",
00219                   numChannels, inputTypeNames[inputType]) ;
00220       }
00221 
00222       switch (inputType) {
00223       case Image:
00224         vl_hog_put_image(hog, image, height, width, numChannels, cellSize) ;
00225         break ;
00226       case DirectedPolarField:
00227       case UndirectedPolarField:
00228         vl_hog_put_polar_field(hog, image, image + height*width,
00229                                inputType == DirectedPolarField,
00230                                height, width, cellSize) ;
00231           break ;
00232       default:
00233         abort() ;
00234       }
00235 
00236       dimensions[0] = vl_hog_get_width(hog) ;
00237       dimensions[1] = vl_hog_get_height(hog) ;
00238       dimensions[2] = vl_hog_get_dimension(hog) ;
00239 
00240       if (verbose) {
00241         mexPrintf("vl_hog: image: [%d x %d x %d]\n", height, width, numChannels) ;
00242         mexPrintf("vl_hog: descriptor: [%d x %d x %d]\n", dimensions[0], dimensions[1], dimensions[2]) ;
00243         mexPrintf("vl_hog: number of orientations: %d\n", numOrientations) ;
00244         mexPrintf("vl_hog: bilinear orientation assignments: %s\n", VL_YESNO(vl_hog_get_use_bilinear_orientation_assignments(hog))) ;
00245         mexPrintf("vl_hog: variant: %s\n", variantName) ;
00246         mexPrintf("vl_hog: input type: %s\n", inputTypeNames[inputType]) ;
00247       }
00248 
00249       OUT(FEATURES) = mxCreateNumericArray(3, dimensions, mxSINGLE_CLASS, mxREAL) ;
00250       vl_hog_extract (hog, mxGetData(OUT(FEATURES))) ;
00251       vl_hog_delete(hog) ;
00252       break ;
00253     }
00254 
00255     case GetPermutation :
00256     {
00257       VlHog * hog = vl_hog_new(variant, numOrientations, VL_TRUE) ;
00258       vl_size dimension = vl_hog_get_dimension(hog) ;
00259       vl_uindex k ;
00260       vl_uint32 * permutationOut ;
00261       vl_index const * permutation ;
00262 
00263       if (verbose) {
00264         mexPrintf("vl_hog: number of orientations: %d\n", numOrientations) ;
00265         mexPrintf("vl_hog: variant: %s\n", variantName) ;
00266       }
00267 
00268       OUT(FEATURES) = mxCreateNumericMatrix(dimension, 1, mxUINT32_CLASS, mxREAL) ;
00269       permutationOut = mxGetData(OUT(FEATURES)) ;
00270       permutation = vl_hog_get_permutation(hog) ;
00271       for (k = 0 ; k < dimension ; ++k) {
00272         permutationOut[k] = permutation[k] + 1 ;
00273       }
00274       break ;
00275     }
00276 
00277     case Render :
00278     {
00279       VlHog * hog = vl_hog_new(variant, numOrientations, VL_TRUE) ;
00280       vl_size glyphSize = vl_hog_get_glyph_size(hog) ;
00281       vl_size imageHeight = glyphSize * height ;
00282       vl_size imageWidth = glyphSize * width ;
00283 
00284       if (numChannels != vl_hog_get_dimension(hog)) {
00285         vlmxError(vlmxErrInvalidArgument,
00286                   "The third dimension of DESCRIPTOR is not equal to the dimension of a HOG descriptor.");
00287       }
00288 
00289       if (verbose) {
00290         mexPrintf("vl_hog: descriptor: [%d x %d x %d]\n", height, width, numChannels) ;
00291         mexPrintf("vl_hog: glyph image: [%d x %d]\n", imageHeight, imageWidth) ;
00292         mexPrintf("vl_hog: number of orientations: %d\n", numOrientations) ;
00293         mexPrintf("vl_hog: variant: %s\n", variantName) ;
00294       }
00295 
00296       OUT(FEATURES) = mxCreateNumericMatrix(imageHeight, imageWidth, mxSINGLE_CLASS, mxREAL) ;
00297       vl_hog_render(hog,
00298                     mxGetData(OUT(FEATURES)),
00299                     descriptor, height, width) ;
00300       break ;
00301     }
00302   }
00303 }


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