00001
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <mexutils.h>
00015 #include <vl/slic.h>
00016
00017 #include <assert.h>
00018 #include <string.h>
00019
00020
00021 enum {
00022 opt_verbose,
00023 opt_min_segment_size
00024 } ;
00025
00026
00027 vlmxOption options [] = {
00028 {"Verbose", 0, opt_verbose },
00029 {"MinRegionSize", 1, opt_min_segment_size },
00030 {0, 0, 0 }
00031 } ;
00032
00037 void
00038 mexFunction(int nout, mxArray *out[],
00039 int nin, const mxArray *in[])
00040 {
00041 enum {IN_IMAGE, IN_REGIONSIZE, IN_REGULARIZER, IN_END} ;
00042 enum {OUT_SEGMENTATION = 0} ;
00043
00044 int verbose = 0 ;
00045 int opt ;
00046 int next = IN_END ;
00047 mxArray const *optarg ;
00048
00049 float const * image ;
00050 vl_size width ;
00051 vl_size height ;
00052 vl_size numChannels ;
00053 vl_size regionSize ;
00054 double regularizer ;
00055 vl_uint32 * segmentation ;
00056 int minRegionSize = -1 ;
00057
00058 VL_USE_MATLAB_ENV ;
00059
00060
00061
00062
00063
00064 if (nin < 3) {
00065 vlmxError(vlmxErrInvalidArgument,
00066 "At least three arguments are required.") ;
00067 } else if (nout > 1) {
00068 vlmxError(vlmxErrInvalidArgument,
00069 "Too many output arguments.");
00070 }
00071
00072 image = mxGetData(IN(IMAGE)) ;
00073 if (!mxIsNumeric(IN(IMAGE)) || mxIsComplex(IN(IMAGE))) {
00074 vlmxError(vlmxErrInvalidArgument, "IMAGE is not a real matrix.") ;
00075 }
00076 if (mxGetClassID(IN(IMAGE)) != mxSINGLE_CLASS) {
00077 vlmxError(vlmxErrInvalidArgument, "IMAGE is not of class SINGLE.") ;
00078 }
00079 if (mxGetNumberOfDimensions(IN(IMAGE)) > 3) {
00080 vlmxError(vlmxErrInvalidArgument, "IMAGE has more than three dimensions.") ;
00081 }
00082
00083 width = mxGetDimensions(IN(IMAGE))[1] ;
00084 height = mxGetDimensions(IN(IMAGE))[0] ;
00085 if (mxGetNumberOfDimensions(IN(IMAGE)) == 2) {
00086 numChannels = 1 ;
00087 } else {
00088 numChannels = mxGetDimensions(IN(IMAGE))[2] ;
00089 }
00090
00091 if (!vlmxIsPlainScalar(IN(REGIONSIZE))) {
00092 vlmxError(vlmxErrInvalidArgument, "REGIONSIZE is not a plain scalar.") ;
00093 }
00094 regionSize = mxGetScalar(IN(REGIONSIZE)) ;
00095 if (regionSize < 1) {
00096 vlmxError(vlmxErrInvalidArgument, "REGIONSIZE=%d is smaller than one.", regionSize) ;
00097 }
00098
00099 if (!vlmxIsPlainScalar(IN(REGULARIZER))) {
00100 vlmxError(vlmxErrInvalidArgument, "REGULARIZER is not a plain scalar.") ;
00101 }
00102 regularizer = mxGetScalar(IN(REGULARIZER)) ;
00103 if (regularizer < 0) {
00104 vlmxError(vlmxErrInvalidArgument, "REGULARIZER=%g is smaller than one.", regularizer) ;
00105 }
00106
00107 while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) {
00108 switch (opt) {
00109 case opt_verbose :
00110 ++ verbose ;
00111 break ;
00112 case opt_min_segment_size :
00113 if (!vlmxIsPlainScalar(optarg)) {
00114 vlmxError(vlmxErrInvalidArgument, "MINREGIONSIZE is not a plain scalar.") ;
00115 }
00116 minRegionSize = mxGetScalar(optarg) ;
00117 if (minRegionSize < 0) {
00118 vlmxError(vlmxErrInvalidArgument, "MINREGIONSIZE=%d is smaller than zero.", minRegionSize) ;
00119 }
00120 break ;
00121 }
00122 }
00123
00124 if (minRegionSize < 0) {
00125 minRegionSize = (regionSize * regionSize) / (6*6) ;
00126 }
00127
00128 if (verbose) {
00129 mexPrintf("vl_slic: image = [%d x %d x %d]\n",
00130 width, height, numChannels) ;
00131 mexPrintf("vl_slic: regionSize = %d\n", regionSize) ;
00132 mexPrintf("vl_slic: regularizer = %g\n", regularizer) ;
00133 mexPrintf("vl_slic: minRegionSize = %d\n", minRegionSize) ;
00134 }
00135
00136
00137
00138
00139
00140 OUT(SEGMENTATION) = mxCreateNumericMatrix((mwSize)height, (mwSize)width, mxUINT32_CLASS, mxREAL) ;
00141 segmentation = mxGetData(OUT(SEGMENTATION)) ;
00142
00143 vl_slic_segment(segmentation,
00144 image, height, width, numChannels,
00145 regionSize, regularizer, minRegionSize) ;
00146 }