/* driver */ void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum { MANIP_STATE, RUN_GENERATOR } mode ; VlRand * rand ; VL_USE_MATLAB_ENV ; rand = vl_get_rand() ; /** ----------------------------------------------------------------- ** Check the arguments ** -------------------------------------------------------------- */ if (nout > 1) { vlmxError(vlmxErrTooManyInputArguments, NULL) ; } if (nin > 0 && ! mxIsNumeric(in[0])) { mode = MANIP_STATE ; } else { mode = RUN_GENERATOR ; } switch (mode) { case RUN_GENERATOR: { enum { maxNumDimensions = 30 } ; vl_size numDimensions = 2, n ; vl_uindex k ; mwSize dimensions [maxNumDimensions] = {1, 1} ; double * x ; if (nin > 1) { /* TWISTER(N1 N2 ...) style */ if (nin >= maxNumDimensions) { vlmxError(vlmxErrTooManyInputArguments, "Too many dimensions specified.") ; } for (k = 0 ; k < (unsigned)nin ; ++k) { if (! vlmxIsPlainScalar(in[k])) { vlmxError(vlmxErrInvalidArgument, "The %d-th argument is not a plain scalar.", k + 1) ; } if (mxGetScalar(in[k]) < 0) { vlmxError(vlmxErrInvalidArgument, "The %d-th argument is negative.", k + 1) ; } dimensions[k] = mxGetScalar(in[k]) ; } numDimensions = k ; } else if (nin == 1) { /* TWISTER([N1 N2 ...]) style */ if (! vlmxIsPlainVector(in[0], -1)) { vlmxError(vlmxErrInvalidArgument, "The argument is not a plain vector.") ; } x = mxGetPr(in[0]) ; n = mxGetNumberOfElements(in[0]) ; numDimensions = VL_MAX(2, n) ; if (numDimensions > maxNumDimensions) { vlmxError(vlmxErrInvalidArgument, "Too many dimensions specified.") ; } if (n == 1) { if (*x < 0) { vlmxError(vlmxErrInvalidArgument, "The specified dimension is negative.") ; } dimensions[0] = dimensions[1] = *x ; } else { for (k = 0 ; k < n ; ++k) { if (x[k] < 0) { vlmxError(vlmxErrInvalidArgument, "One of the specified dimensions is negative.") ; } dimensions[k] = x[k] ; } } } out[0] = mxCreateNumericArray (numDimensions, dimensions, mxDOUBLE_CLASS, mxREAL) ; n = mxGetNumberOfElements (out[0]) ; x = mxGetPr (out[0]) ; for (k = 0 ; k < n ; ++k) { x[k] = vl_rand_res53(rand) ; } } break ; case MANIP_STATE: { enum { buff_size = 32 } ; char buff [buff_size] ; /* check for 'state' string */ if (! vlmxIsString(in[0], -1) || mxGetString(in[0], buff, buff_size) || vl_string_casei_cmp ("state", buff) != 0 ) { vlmxError(vlmxErrInvalidArgument, NULL) ; } /* TWISTER('state') */ if (nin == 1) { vl_uindex i ; vl_uint32 * data ; out[0] = mxCreateNumericMatrix (625, 1, mxUINT32_CLASS, mxREAL) ; data = mxGetData(out[0]) ; for (i = 0 ; i < 624 ; ++i) data[i] = rand->mt[i] ; data[624] = (vl_uint32) rand->mti ; } else { if (vlmxIsPlainScalar(in[1])) { /* TWISTER('state', X) */ vl_uint32 x = (vl_uint32) mxGetScalar(in[1]) ; vl_rand_seed (rand, x) ; } else if (mxIsNumeric(in[1]) && mxGetClassID(in[1]) == mxUINT32_CLASS && mxGetNumberOfElements(in[1]) == 624+1 && ((vl_uint32 const*)mxGetData(in[1]))[624] <= 624 ) { /* TWISTER('state', STATE) */ vl_uindex i ; vl_uint32 * data = mxGetData(in[1]) ; for (i = 0 ; i < 624 ; ++i) rand->mt[i] = data[i] ; rand->mti = data [624] ; } else if (mxIsNumeric(in[1]) && mxGetClassID(in[1]) == mxDOUBLE_CLASS && mxGetNumberOfElements(in[1]) <= 624) { /* TWISTER('state', KEY) */ vl_uint32 key [624] ; double const * x = mxGetPr(in[1]) ; vl_size n = mxGetNumberOfElements(in[1]) ; vl_uindex k ; for (k = 0 ; k < n ; ++k) { key [k] = x [k] ; } vl_rand_seed_by_array (rand, key, n) ; } } } break ; default: abort() ; } }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { vl_size M, N ; enum {IN_I = 0, IN_PARAM, IN_END} ; enum {OUT_DT = 0, OUT_INDEXES} ; vl_uindex * indexes = NULL ; mxClassID classId ; double const defaultParam [] = {1.0, 0.0, 1.0, 0.0} ; double const * param = defaultParam ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 1) { vlmxError(vlmxErrNotEnoughInputArguments, NULL) ; } if (nin > 2) { vlmxError(vlmxErrTooManyInputArguments, NULL) ; } if (nout > 2) { vlmxError(vlmxErrTooManyOutputArguments, NULL) ; } classId = mxGetClassID(IN(I)) ; if (! vlmxIsMatrix(IN(I), -1, -1) || (classId != mxSINGLE_CLASS && classId != mxDOUBLE_CLASS)) { vlmxError(vlmxErrInvalidArgument, "I is not a SINGLE or DOUBLE matrix.") ; } if (nin == 2) { if (! vlmxIsPlainVector(IN(PARAM), 4)) { vlmxError(vlmxErrInvalidArgument, "PARAM is not a 4-dimensional vector.") ; } param = mxGetPr (IN(PARAM)) ; if (param[0] < 0.0 || param[2] < 0.0) { vlmxError(vlmxErrInvalidArgument, "Either PARAM[0] or PARAM[2] is negative.") ; } } M = mxGetM (IN(I)) ; N = mxGetN (IN(I)) ; OUT(DT) = mxCreateNumericMatrix (M, N, classId, mxREAL) ; if (nout > 1) { vl_uindex i ; OUT(INDEXES) = mxCreateDoubleMatrix (M, N, mxREAL) ; indexes = mxMalloc(sizeof(vl_uindex) * M * N) ; for (i = 0 ; i < M * N ; ++i) indexes[i] = i + 1 ; } /* ----------------------------------------------------------------- * Do the job * -------------------------------------------------------------- */ switch (classId) { case mxSINGLE_CLASS: vl_image_distance_transform_f((float const*)mxGetData(IN(I)), M, N, 1, M, (float*)mxGetPr(OUT(DT)), indexes, param[2], param[3]) ; vl_image_distance_transform_f((float*)mxGetPr(OUT(DT)), N, M, M, 1, (float*)mxGetPr(OUT(DT)), indexes, param[0], param[1]) ; break ; case mxDOUBLE_CLASS: vl_image_distance_transform_d((double const*)mxGetData(IN(I)), M, N, 1, M, (double*)mxGetPr(OUT(DT)), indexes, param[2], param[3]) ; vl_image_distance_transform_d((double*)mxGetPr(OUT(DT)), N, M, M, 1, (double*)mxGetPr(OUT(DT)), indexes, param[0], param[1]) ; break; default: abort() ; } if (indexes) { vl_uindex i ; double * pt = mxGetPr(OUT(INDEXES)) ; for (i = 0 ; i < M * N ; ++i) pt[i] = indexes[i] ; mxFree(indexes) ; } }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum { X=0,Y,I,iwXp,iwYp } ; enum { wI=0, wIx, wIy } ; int M, N, Mp, Np, ip, jp ; double *X_pt, *Y_pt, *I_pt, *iwXp_pt, *iwYp_pt, *wI_pt, *wIx_pt = 0, *wIy_pt = 0 ; double Xmin, Xmax, Ymin, Ymax ; const double NaN = mxGetNaN() ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 5) { vlmxError (vlmxErrNotEnoughInputArguments, NULL) ; } if (nin > 5) { vlmxError (vlmxErrTooManyOutputArguments, NULL) ; } if (nout > 3) { vlmxError (vlmxErrTooManyOutputArguments, NULL) ; } if (! vlmxIsPlainMatrix(in[I], -1, -1)) { vlmxError (vlmxErrInvalidArgument, "I is not a plain matrix.") ; } if (! vlmxIsPlainMatrix(in[iwXp], -1, -1)) { vlmxError(vlmxErrInvalidArgument, "iwXp is not a plain matrix.") ; } M = getM(I) ; N = getN(I) ; Mp = getM(iwXp) ; Np = getN(iwXp) ; if(!vlmxIsPlainMatrix(in[iwYp], Mp, Np)) { vlmxError(vlmxErrInvalidArgument, "iwXp is not a plain matrix of the same idmension of iwYp.") ; } if(!vlmxIsPlainVector(in[X],N) || !vlmxIsPlainVector(in[Y],M)) { vlmxError(vlmxErrInvalidArgument, "X and Y are not plain vectors with a length equal to the" " number of columns and rows of I.") ; } X_pt = getPr(X); Y_pt = getPr(Y) ; I_pt = getPr(I) ; iwXp_pt = getPr(iwXp) ; iwYp_pt = getPr(iwYp) ; /* Allocate the result. */ out[wI] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ; wI_pt = mxGetPr(out[wI]) ; if (nout > 1) { out[wIx] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ; out[wIy] = mxCreateDoubleMatrix(Mp, Np, mxREAL) ; wIx_pt = mxGetPr (out[wIx]) ; wIy_pt = mxGetPr (out[wIy]) ; } /* ----------------------------------------------------------------- * Do the job * -------------------------------------------------------------- */ Xmin = X_pt [0] ; Xmax = X_pt [N - 1] ; Ymin = Y_pt [0] ; Ymax = Y_pt [M - 1] ; if (nout <= 1) { /* optimized for only image output */ for(jp = 0 ; jp < Np ; ++jp) { for(ip = 0 ; ip < Mp ; ++ip) { /* Search for the four neighbors of the backprojected point. */ double x = *iwXp_pt++ ; double y = *iwYp_pt++ ; double z = NaN ; /* This messy code allows the identity transformation * to be processed as expected. */ if(x >= Xmin && x <= Xmax && y >= Ymin && y <= Ymax) { int j = findNeighbor(x, X_pt, N) ; int i = findNeighbor(y, Y_pt, M) ; double* pt = I_pt + j*M + i ; /* Weights. */ double x0 = X_pt[j] ; double x1 = (j < N-1) ? X_pt[j+1] : x0 + 1; double y0 = Y_pt[i] ; double y1 = (i < M-1) ? Y_pt[i+1] : y0 + 1; double wx = (x-x0)/(x1-x0) ; double wy = (y-y0)/(y1-y0) ; /* Load all possible neighbors. */ double z00 = 0.0 ; double z10 = 0.0 ; double z01 = 0.0 ; double z11 = 0.0 ; if(j > -1) { if(i > -1 ) z00 = *pt ; pt++ ; if(i < M-1) z10 = *pt ; } else { pt++ ; } pt += M - 1; if(j < N-1) { if(i > -1 ) z01 = *pt ; pt++ ; if(i < M-1) z11 = *pt ; } /* Bilinear interpolation. */ z = (1 - wy) * ((1-wx) * z00 + wx * z01) + ( wy) * ((1-wx) * z10 + wx * z11) ; } *(wI_pt + jp*Mp + ip) = z ; } } } /* do also the derivatives */ else { /* optimized for only image output */ for(jp = 0 ; jp < Np ; ++jp) { for(ip = 0 ; ip < Mp ; ++ip) { /* Search for the four neighbors of the backprojected point. */ double x = *iwXp_pt++ ; double y = *iwYp_pt++ ; double z = NaN, zx = NaN, zy = NaN ; /* This messy code allows the identity transformation * to be processed as expected. */ if(x >= Xmin && x <= Xmax && y >= Ymin && y <= Ymax) { int j = findNeighbor(x, X_pt, N) ; int i = findNeighbor(y, Y_pt, M) ; double* pt = I_pt + j*M + i ; /* Weights. */ double x0 = X_pt[j] ; double x1 = X_pt[j+1] ; double y0 = Y_pt[i] ; double y1 = Y_pt[i+1] ; double wx = (x-x0)/(x1-x0) ; double wy = (y-y0)/(y1-y0) ; /* Load all possible neighbors. */ double z00 = 0.0 ; double z10 = 0.0 ; double z01 = 0.0 ; double z11 = 0.0 ; if(j > -1) { if(i > -1 ) z00 = *pt ; pt++ ; if(i < M-1) z10 = *pt ; } else { pt++ ; } pt += M - 1; if(j < N-1) { if(i > -1 ) z01 = *pt ; pt++ ; if(i < M-1) z11 = *pt ; } /* Bilinear interpolation. */ z = (1-wy)*( (1-wx) * z00 + wx * z01) + wy*( (1-wx) * z10 + wx * z11) ; zx = (1-wy) * (z01 - z00) + wy * (z11 - z10) ; zy = (1-wx) * (z10 - z00) + wx * (z11 - z01) ; } *(wI_pt + jp*Mp + ip) = z ; *(wIx_pt + jp*Mp + ip) = zx ; *(wIy_pt + jp*Mp + ip) = zy ; } } } }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_I=0, IN_END} ; enum {OUT_FRAMES=0, OUT_DESCRIPTORS} ; int verbose = 0 ; int opt ; int next = IN_END ; mxArray const *optarg ; float const *data ; int M, N ; int step [2] = {1,1} ; vl_bool norm = 0 ; vl_bool floatDescriptors = VL_FALSE ; vl_bool useFlatWindow = VL_FALSE ; double windowSize = -1.0 ; double *bounds = NULL ; double boundBuffer [4] ; VlDsiftDescriptorGeometry geom ; VL_USE_MATLAB_ENV ; geom.numBinX = 4 ; geom.numBinY = 4 ; geom.numBinT = 8 ; geom.binSizeX = 3 ; geom.binSizeY = 3 ; /* ----------------------------------------------------------------- * Check the arguments * -------------------------------------------------------------- */ if (nin < 1) { vlmxError(vlmxErrNotEnoughInputArguments, NULL) ; } else if (nout > 2) { vlmxError(vlmxErrTooManyOutputArguments, NULL) ; } if (mxGetNumberOfDimensions (in[IN_I]) != 2 || mxGetClassID (in[IN_I]) != mxSINGLE_CLASS ) { vlmxError(vlmxErrInvalidArgument, "I must be a matrix of class SINGLE.") ; } data = (float*) mxGetData (in[IN_I]) ; M = mxGetM (in[IN_I]) ; N = mxGetN (in[IN_I]) ; while ((opt = vlmxNextOption (in, nin, options, &next, &optarg)) >= 0) { switch (opt) { case opt_verbose : ++ verbose ; break ; case opt_fast : useFlatWindow = 1 ; break ; case opt_norm : norm = 1 ; break ; case opt_bounds : if (!vlmxIsPlainVector(optarg, 4)) { mexErrMsgTxt("BOUNDS must be a 4-dimensional vector.") ; } bounds = boundBuffer ; bounds [0] = mxGetPr(optarg)[0] - 1 ; bounds [1] = mxGetPr(optarg)[1] - 1 ; bounds [2] = mxGetPr(optarg)[2] - 1 ; bounds [3] = mxGetPr(optarg)[3] - 1 ; break ; case opt_size : if (!vlmxIsPlainVector(optarg,-1)) { vlmxError(vlmxErrInvalidArgument,"SIZE is not a plain vector.") ; } if (mxGetNumberOfElements(optarg) == 1) { geom.binSizeX = (int) mxGetPr(optarg)[0] ; geom.binSizeY = (int) mxGetPr(optarg)[0] ; } else if (mxGetNumberOfElements(optarg) == 2) { geom.binSizeX = (int) mxGetPr(optarg)[1] ; geom.binSizeY = (int) mxGetPr(optarg)[0] ; } else { vlmxError(vlmxErrInvalidArgument,"SIZE is neither a scalar or a 2D vector.") ; } if (geom.binSizeX < 1 || geom.binSizeY < 1) { vlmxError(vlmxErrInvalidArgument,"SIZE value is invalid.") ; } break ; case opt_step : if (!vlmxIsPlainVector(optarg,-1)) { vlmxError(vlmxErrInvalidArgument,"STEP is not a plain vector.") ; } if (mxGetNumberOfElements(optarg) == 1) { step[0] = (int) mxGetPr(optarg)[0] ; step[1] = (int) mxGetPr(optarg)[0] ; } else if (mxGetNumberOfElements(optarg) == 2) { step[0] = (int) mxGetPr(optarg)[1] ; step[1] = (int) mxGetPr(optarg)[0] ; } else { vlmxError(vlmxErrInvalidArgument,"STEP is neither a scalar or a 2D vector.") ; } if (step[0] < 1 || step[1] < 1) { vlmxError(vlmxErrInvalidArgument,"STEP value is invalid.") ; } break ; case opt_window_size : if (!vlmxIsPlainScalar(optarg) || (windowSize = *mxGetPr(optarg)) < 0) { vlmxError(vlmxErrInvalidArgument,"WINDOWSIZE is not a scalar or it is negative.") ; } break ; case opt_float_descriptors : floatDescriptors = VL_TRUE ; break ; case opt_geometry : if (!vlmxIsPlainVector(optarg,3)) { vlmxError(vlmxErrInvalidArgument, "GEOMETRY is not a 3D vector.") ; } geom.numBinY = (int)mxGetPr(optarg)[0] ; geom.numBinX = (int)mxGetPr(optarg)[1] ; geom.numBinT = (int)mxGetPr(optarg)[2] ; if (geom.numBinX < 1 || geom.numBinY < 1 || geom.numBinT < 1) { vlmxError(vlmxErrInvalidArgument, "GEOMETRY value is invalid.") ; } break ; default : abort() ; } } /* ----------------------------------------------------------------- * Do job * -------------------------------------------------------------- */ { int numFrames ; int descrSize ; VlDsiftKeypoint const *frames ; float const *descrs ; int k, i ; VlDsiftFilter *dsift ; /* note that the image received from MATLAB is transposed */ dsift = vl_dsift_new (M, N) ; vl_dsift_set_geometry(dsift, &geom) ; vl_dsift_set_steps(dsift, step[0], step[1]) ; if (bounds) { vl_dsift_set_bounds(dsift, VL_MAX(bounds[1], 0), VL_MAX(bounds[0], 0), VL_MIN(bounds[3], M - 1), VL_MIN(bounds[2], N - 1)); } vl_dsift_set_flat_window(dsift, useFlatWindow) ; if (windowSize >= 0) { vl_dsift_set_window_size(dsift, windowSize) ; } numFrames = vl_dsift_get_keypoint_num (dsift) ; descrSize = vl_dsift_get_descriptor_size (dsift) ; geom = *vl_dsift_get_geometry (dsift) ; if (verbose) { int stepX ; int stepY ; int minX ; int minY ; int maxX ; int maxY ; vl_bool useFlatWindow ; vl_dsift_get_steps (dsift, &stepY, &stepX) ; vl_dsift_get_bounds (dsift, &minY, &minX, &maxY, &maxX) ; useFlatWindow = vl_dsift_get_flat_window(dsift) ; mexPrintf("vl_dsift: image size [W, H] = [%d, %d]\n", N, M) ; mexPrintf("vl_dsift: bounds: [minX,minY,maxX,maxY] = [%d, %d, %d, %d]\n", minX+1, minY+1, maxX+1, maxY+1) ; mexPrintf("vl_dsift: subsampling steps: stepX=%d, stepY=%d\n", stepX, stepY) ; mexPrintf("vl_dsift: num bins: [numBinT, numBinX, numBinY] = [%d, %d, %d]\n", geom.numBinT, geom.numBinX, geom.numBinY) ; mexPrintf("vl_dsift: descriptor size: %d\n", descrSize) ; mexPrintf("vl_dsift: bin sizes: [binSizeX, binSizeY] = [%d, %d]\n", geom.binSizeX, geom.binSizeY) ; mexPrintf("vl_dsift: flat window: %s\n", VL_YESNO(useFlatWindow)) ; mexPrintf("vl_dsift: window size: %g\n", vl_dsift_get_window_size(dsift)) ; mexPrintf("vl_dsift: num of features: %d\n", numFrames) ; } vl_dsift_process (dsift, data) ; frames = vl_dsift_get_keypoints (dsift) ; descrs = vl_dsift_get_descriptors (dsift) ; /* --------------------------------------------------------------- * Create output arrays * ------------------------------------------------------------ */ { mwSize dims [2] ; dims [0] = descrSize ; dims [1] = numFrames ; if (floatDescriptors) { out[OUT_DESCRIPTORS] = mxCreateNumericArray (2, dims, mxSINGLE_CLASS, mxREAL) ; } else { out[OUT_DESCRIPTORS] = mxCreateNumericArray (2, dims, mxUINT8_CLASS, mxREAL) ; } dims [0] = norm ? 3 : 2 ; out[OUT_FRAMES] = mxCreateNumericArray (2, dims, mxDOUBLE_CLASS, mxREAL) ; } /* --------------------------------------------------------------- * Copy back * ------------------------------------------------------------ */ { float *tmpDescr = mxMalloc(sizeof(float) * descrSize) ; double *outFrameIter = mxGetPr(out[OUT_FRAMES]) ; void *outDescrIter = mxGetData(out[OUT_DESCRIPTORS]) ; for (k = 0 ; k < numFrames ; ++k) { *outFrameIter++ = frames[k].y + 1 ; *outFrameIter++ = frames[k].x + 1 ; /* We have an implied / 2 in the norm, because of the clipping below */ if (norm) *outFrameIter++ = frames [k].norm ; vl_dsift_transpose_descriptor (tmpDescr, descrs + descrSize * k, geom.numBinT, geom.numBinX, geom.numBinY) ; if (floatDescriptors) { for (i = 0 ; i < descrSize ; ++i) { float * pt = (float*) outDescrIter ; *pt++ = VL_MIN(512.0F * tmpDescr[i], 255.0F) ; outDescrIter = pt ; } } else { for (i = 0 ; i < descrSize ; ++i) { vl_uint8 * pt = (vl_uint8*) outDescrIter ; *pt++ = (vl_uint8) (VL_MIN(512.0F * tmpDescr[i], 255.0F)) ; outDescrIter = pt ; } } } mxFree(tmpDescr) ; } vl_dsift_delete (dsift) ; } }