00001
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <mexutils.h>
00016
00017 #include <vl/generic.h>
00018 #include <vl/mathop.h>
00019 #include <vl/imopv.h>
00020
00021 void
00022 mexFunction(int nout, mxArray *out[],
00023 int nin, const mxArray *in[])
00024 {
00025 vl_size M, N ;
00026 enum {IN_I = 0, IN_PARAM, IN_END} ;
00027 enum {OUT_DT = 0, OUT_INDEXES} ;
00028 vl_uindex * indexes = NULL ;
00029 mxClassID classId ;
00030 double const defaultParam [] = {1.0, 0.0, 1.0, 0.0} ;
00031 double const * param = defaultParam ;
00032
00033
00034
00035
00036
00037 if (nin < 1) {
00038 vlmxError(vlmxErrNotEnoughInputArguments, NULL) ;
00039 }
00040 if (nin > 2) {
00041 vlmxError(vlmxErrTooManyInputArguments, NULL) ;
00042 }
00043 if (nout > 2) {
00044 vlmxError(vlmxErrTooManyOutputArguments, NULL) ;
00045 }
00046 classId = mxGetClassID(IN(I)) ;
00047 if (! vlmxIsMatrix(IN(I), -1, -1) ||
00048 (classId != mxSINGLE_CLASS && classId != mxDOUBLE_CLASS)) {
00049 vlmxError(vlmxErrInvalidArgument,
00050 "I is not a SINGLE or DOUBLE matrix.") ;
00051 }
00052 if (nin == 2) {
00053 if (! vlmxIsPlainVector(IN(PARAM), 4)) {
00054 vlmxError(vlmxErrInvalidArgument,
00055 "PARAM is not a 4-dimensional vector.") ;
00056 }
00057 param = mxGetPr (IN(PARAM)) ;
00058 if (param[0] < 0.0 ||
00059 param[2] < 0.0) {
00060 vlmxError(vlmxErrInvalidArgument,
00061 "Either PARAM[0] or PARAM[2] is negative.") ;
00062 }
00063 }
00064
00065 M = mxGetM (IN(I)) ;
00066 N = mxGetN (IN(I)) ;
00067
00068 OUT(DT) = mxCreateNumericMatrix (M, N, classId, mxREAL) ;
00069 if (nout > 1) {
00070 vl_uindex i ;
00071 OUT(INDEXES) = mxCreateDoubleMatrix (M, N, mxREAL) ;
00072 indexes = mxMalloc(sizeof(vl_uindex) * M * N) ;
00073 for (i = 0 ; i < M * N ; ++i) indexes[i] = i + 1 ;
00074 }
00075
00076
00077
00078
00079
00080 switch (classId) {
00081 case mxSINGLE_CLASS:
00082 vl_image_distance_transform_f((float const*)mxGetData(IN(I)),
00083 M, N,
00084 1, M,
00085 (float*)mxGetPr(OUT(DT)),
00086 indexes,
00087 param[2],
00088 param[3]) ;
00089
00090 vl_image_distance_transform_f((float*)mxGetPr(OUT(DT)),
00091 N, M,
00092 M, 1,
00093 (float*)mxGetPr(OUT(DT)),
00094 indexes,
00095 param[0],
00096 param[1]) ;
00097 break ;
00098
00099 case mxDOUBLE_CLASS:
00100 vl_image_distance_transform_d((double const*)mxGetData(IN(I)),
00101 M, N,
00102 1, M,
00103 (double*)mxGetPr(OUT(DT)),
00104 indexes,
00105 param[2],
00106 param[3]) ;
00107
00108 vl_image_distance_transform_d((double*)mxGetPr(OUT(DT)),
00109 N, M,
00110 M, 1,
00111 (double*)mxGetPr(OUT(DT)),
00112 indexes,
00113 param[0],
00114 param[1]) ;
00115 break;
00116
00117 default:
00118 abort() ;
00119 }
00120
00121 if (indexes) {
00122 vl_uindex i ;
00123 double * pt = mxGetPr(OUT(INDEXES)) ;
00124 for (i = 0 ; i < M * N ; ++i) pt[i] = indexes[i] ;
00125 mxFree(indexes) ;
00126 }
00127 }