void mexFunction(int nlhs, mxArray *out[], int nrhs, const mxArray *input[]) { // Checking number of arguments if(nlhs > 3){ mexErrMsgTxt("Function has three return values"); return; } if(nrhs != 4){ mexErrMsgTxt("Usage: mexFelzenSegment(UINT8 im, double sigma, double c, int minSize)"); return; } if(!mxIsClass(input[0], "uint8")){ mexErrMsgTxt("Only image arrays of the UINT8 class are allowed."); return; } // Load in arrays and parameters UInt8* matIm = (UInt8*) mxGetPr(input[0]); int nrDims = (int) mxGetNumberOfDimensions(input[0]); int* dims = (int*) mxGetDimensions(input[0]); double* sigma = mxGetPr(input[1]); double* c = mxGetPr(input[2]); double* minSize = mxGetPr(input[3]); int min_size = (int) *minSize; int height = dims[0]; int width = dims[1]; int imSize = height * width; // Convert to image. int idx; image<rgb>* theIm = new image<rgb>(width, height); for (int x = 0; x < width; x++){ for (int y = 0; y < height; y++){ idx = x * height + y; imRef(theIm, x, y).r = matIm[idx]; imRef(theIm, x, y).g = matIm[idx + imSize]; imRef(theIm, x, y).b = matIm[idx + 2 * imSize]; } } // KOEN: Disable randomness of the algorithm srand(12345); // Call Felzenswalb segmentation algorithm int num_css; //image<rgb>* segIm = segment_image(theIm, *sigma, *c, min_size, &num_css); double* segIndices = segment_image_index(theIm, *sigma, *c, min_size, &num_css); //mexPrintf("numCss: %d\n", num_css); // The segmentation index image out[0] = mxCreateDoubleMatrix(dims[0], dims[1], mxREAL); double* outSegInd = mxGetPr(out[0]); // Keep track of minimum and maximum of each blob out[1] = mxCreateDoubleMatrix(num_css, 4, mxREAL); double* minmax = mxGetPr(out[1]); for (int i=0; i < num_css; i++) minmax[i] = dims[0]; for (int i= num_css; i < 2 * num_css; i++) minmax[i] = dims[1]; // Keep track of neighbouring blobs using square matrix out[2] = mxCreateDoubleMatrix(num_css, num_css, mxREAL); double* nn = mxGetPr(out[2]); // Copy the contents of segIndices // Keep track of neighbours // Get minimum and maximum // These actually comprise of the bounding boxes double currDouble; int mprev, curr, prevHori, mcurr; for(int x = 0; x < width; x++){ mprev = segIndices[x * height]-1; for(int y=0; y < height; y++){ //mexPrintf("x: %d y: %d\n", x, y); idx = x * height + y; //mexPrintf("idx: %d\n", idx); //currDouble = segIndices[idx]; //mexPrintf("currDouble: %d\n", currDouble); curr = segIndices[idx]; //mexPrintf("curr: %d\n", curr); outSegInd[idx] = curr; // copy contents //mexPrintf("outSegInd: %f\n", outSegInd[idx]); mcurr = curr-1; // Get neighbours (vertical) //mexPrintf("idx: %d", curr * num_css + mprev); //mexPrintf(" %d\n", curr + num_css * mprev); //mexPrintf("mprev: %d\n", mprev); nn[(mcurr) * num_css + mprev] = 1; nn[(mcurr) + num_css * mprev] = 1; // Get horizontal neighbours //mexPrintf("Get horizontal neighbours\n"); if (x > 0){ prevHori = outSegInd[(x-1) * height + y] - 1; nn[mcurr * num_css + prevHori] = 1; nn[mcurr + num_css * prevHori] = 1; } // Keep track of min and maximum index of blobs //mexPrintf("Keep track of min and maximum index\n"); if (minmax[mcurr] > y) minmax[mcurr] = y; if (minmax[mcurr + num_css] > x) minmax[mcurr + num_css] = x; if (minmax[mcurr + 2 * num_css] < y) minmax[mcurr + 2 * num_css] = y; if (minmax[mcurr + 3 * num_css] < x) minmax[mcurr + 3 * num_css] = x; //mexPrintf("Mprev = mcurr"); mprev = mcurr; } } // Do minmax plus one for Matlab for (int i=0; i < 4 * num_css; i++) minmax[i] += 1; delete theIm; delete [] segIndices; return; }
// Main function =============================================================== void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { double *X, *Y, Nd, *Space, UnitSpace = 1.0; mwSize nX, nDX, ndimX, N, Step, nSpace; const mwSize *dimX; int Order2 = 0; // Check number and type of inputs and outputs: ------------------------------ if (nrhs == 0 || nrhs > 4) { mexErrMsgIdAndTxt(ERR_ID "BadNInput", ERR_HEAD "1 or 4 inputs required."); } if (nlhs > 1) { mexErrMsgIdAndTxt(ERR_ID "BadNOutput", ERR_HEAD "1 output allowed."); } if (!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0])) { mexErrMsgIdAndTxt(ERR_ID "BadTypeInput1", ERR_HEAD "Input must be a full real double array."); } // Pointers and dimension to input array: ------------------------------------ X = mxGetPr(prhs[0]); nX = mxGetNumberOfElements(prhs[0]); ndimX = mxGetNumberOfDimensions(prhs[0]); dimX = mxGetDimensions(prhs[0]); // Return fast on empty input matrix: if (nX == 0) { plhs[0] = COPY_ARRAY(prhs[0]); return; } // Get spacing, if defined: -------------------------------------------------- if (nrhs < 2) { // No 2nd input defined - scalar unit spacing: nSpace = 1; Space = &UnitSpace; } else { // Get pointer to spacing vector: if (!mxIsDouble(prhs[1])) { mexErrMsgIdAndTxt(ERR_ID "BadTypeInput2", ERR_HEAD "2nd input [Spacing] must be a DOUBLE."); } Space = mxGetPr(prhs[1]); nSpace = mxGetNumberOfElements(prhs[1]); if (nSpace == 0) { nSpace = 1; Space = &UnitSpace; } } // Determine dimension to operate on: ---------------------------------------- if (nrhs < 3) { N = FirstNonSingeltonDim(ndimX, dimX); // Zero based Step = 1; nDX = dimX[N]; } else if (mxIsNumeric(prhs[2])) { // 3rd input used: switch (mxGetNumberOfElements(prhs[2])) { case 0: // Use 1st non-singelton dim if 3rd input is []: N = FirstNonSingeltonDim(ndimX, dimX); Step = 1; nDX = dimX[N]; break; case 1: // Numerical scalar: Nd = mxGetScalar(prhs[2]); N = (mwSize) Nd - 1; if (Nd < 1.0 || Nd != floor(Nd)) { mexErrMsgIdAndTxt(ERR_ID "BadValueInput3", ERR_HEAD "Dimension must be a positive integer scalar."); } if (N < ndimX) { Step = GetStep(dimX, N); nDX = dimX[N]; } else { // Treat imaginated trailing dimensions as singelton, as usual in // Matlab: Step = nX; nDX = 1; } break; default: mexErrMsgIdAndTxt(ERR_ID "BadSizeInput3", ERR_HEAD "3rd input [Dim] must be scalar index."); } } else { // 2nd input is not numeric: mexErrMsgIdAndTxt(ERR_ID "BadTypeInput3", ERR_HEAD "3rd input must be scalar index."); } // Check matching sizes of X and Spacing: if (nSpace != 1 && nSpace != nDX) { mexErrMsgIdAndTxt(ERR_ID "BadSizeInput2", ERR_HEAD "2nd input [Spacing] does not match the dimensions."); } // Check 4th input: ---------------------------------------------------------- if (nrhs >= 4) { // "2ndOrder", but accept everything starting with "2": if (mxIsChar(prhs[3]) && !mxIsEmpty(prhs[3])) { Order2 = (*(mxChar *) mxGetData(prhs[3]) == L'2'); } else { mexErrMsgIdAndTxt(ERR_ID "BadTypeInput4", ERR_HEAD "4th input must be a string."); } } // Create output matrix: ----------------------------------------------------- plhs[0] = mxCreateNumericArray(ndimX, dimX, mxDOUBLE_CLASS, mxREAL); Y = mxGetPr(plhs[0]); // Reply ZEROS, if the length of the processed dimension is 1: if (nDX == 1) { return; } // Calculate the gradient: --------------------------------------------------- if (nSpace == 1) { // Scalar spacing if (Step == 1) { // Operate on 1st dimension CoreDim1Space1(X, nX, nDX, *Space, Y); } else { // Step >= 1, operate on any dimension CoreDimNSpace1(X, Step, nX, nDX, *Space, Y); } } else if (Order2) { // Spacing defined as vector, 2nd order method: if (nX == nDX) { // Single vector only - dynamic spacing factors: CoreDim1SpaceNOrder2(X, nX, nDX, Space, Y); } else { WrapSpaceNOrder2(X, Step, nX, nDX, Space, Y); } } else { // Spacing defined as vector, 1st order method: if (nX == nDX) { // Single vector only - dynamic spacing factors: CoreDim1SpaceN(X, nX, nDX, Space, Y); } else { WrapSpaceN(X, Step, nX, nDX, Space, Y); } } return; }
void mexFunction(const int nlhs, mxArray *plhs[], const int nrhs, const mxArray *prhs[]) { if (nlhs > 1 ) mexErrMsgTxt( "Too many output arguments."); if (nrhs < 1 || nrhs > 3) mexErrMsgTxt( "Wrong number of input arguments." ); { double *x, *w=NULL, *r, rsum, *bbm; mxArray *R, *MN[2]; const int *dims; int B, b, i, j, m, n; dims = mxGetDimensions(prhs[0]); x = mxGetPr(prhs[0]); m = dims[0]; n = dims[1]; if (nrhs>1) { dims = mxGetDimensions(prhs[1]); if (dims[0]>1 || dims[1]>1) mexErrMsgTxt("B must be a scalar."); B = mxGetScalar(prhs[1]); } else { B = 1; } if (nrhs>2) { dims = mxGetDimensions(prhs[2]); if (dims[1]>1) mexErrMsgTxt("W must be a column vector."); if (dims[0]!=m) mexErrMsgTxt("W must have same length as X."); w = mxGetPr(prhs[2]); } plhs[0]=mxCreateDoubleMatrix(B, n, mxREAL); bbm = mxGetPr(plhs[0]); MN[0]=mxCreateDoubleScalar((double)m); MN[1]=mxCreateDoubleScalar(1.0); if (w!=NULL) { for (b = 0; b < B; b++) { mexCallMATLAB(1,&R,2,MN,"rand"); r = mxGetPr(R); for (i = 0, rsum=0; i < m; i++) { r[i] = -log(r[i])*w[i]; rsum += r[i]; } for (i = 0; i < m; i++) { r[i] /= rsum; for (j = 0; j < n; j++) { bbm[b+j*B] += x[i+j*m]*r[i]; } } } } else { for (b = 0; b < B; b++) { mexCallMATLAB(1,&R,2,MN,"rand"); r = mxGetPr(R); for (i = 0, rsum=0; i < m; i++) { r[i] = -log(r[i]); rsum += r[i]; } for (i = 0; i < m; i++) { r[i] /= rsum; for (j = 0; j < n; j++) { bbm[b+j*B] += x[i+j*m]*r[i]; } } } } mxDestroyArray(MN[0]); mxDestroyArray(MN[1]); mxDestroyArray(R); } return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Variables */ int i,n, s, f, e, n1, n2, s1, s2, nInstances,nNodes, nEdges, nNodeFeatures, nEdgeFeatures, *nStates, maxState, *nodeMap, *edgeMap, *edgeEnds, dims[3]; double *w, *Xnode, *Xedge, *nodePot, *edgePot; /* Input */ w = mxGetPr(prhs[0]); Xnode = mxGetPr(prhs[1]); Xedge = mxGetPr(prhs[2]); nodeMap = (int*)mxGetPr(prhs[3]); edgeMap = (int*)mxGetPr(prhs[4]); nStates = (int*)mxGetPr(prhs[5]); edgeEnds = (int*)mxGetPr(prhs[6]); i = (int)mxGetScalar(prhs[7]); i--; if (!mxIsClass(prhs[3],"int32")||!mxIsClass(prhs[4],"int32")||!mxIsClass(prhs[5],"int32")||!mxIsClass(prhs[6],"int32")||!mxIsClass(prhs[7],"int32")) mexErrMsgTxt("edgeEnds, nStates, nodeMap, edgeMap, i must be int32"); /* Compute Sizes */ nNodes = mxGetDimensions(prhs[3])[0]; nEdges = mxGetDimensions(prhs[6])[0]; nInstances = mxGetDimensions(prhs[1])[0]; nNodeFeatures = mxGetDimensions(prhs[1])[1]; nEdgeFeatures = mxGetDimensions(prhs[2])[1]; maxState = getMaxState(nStates, nNodes); /*printf("%d,%d,%d,%d,%d\n", nNodes, nEdges, nNodeFeatures, nEdgeFeatures, maxState);*/ /*printf("%d,%d\n",nInstances,i);*/ /* Make output */ plhs[0] = mxCreateDoubleMatrix(nNodes,maxState,mxREAL); nodePot = mxGetPr(plhs[0]); dims[0] = maxState; dims[1] = maxState; dims[2] = nEdges; plhs[1] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL); edgePot = mxGetPr(plhs[1]); for(n = 0; n < nNodes; n++) { for(s = 0; s < nStates[n]; s++) { for(f = 0; f < nNodeFeatures; f++) { if(nodeMap[n + nNodes*(s + maxState*f)] > 0) { nodePot[n+nNodes*s] += w[nodeMap[n+nNodes*(s+maxState*f)]-1]*Xnode[i + nInstances*(f + nNodeFeatures*n)]; } } nodePot[n+nNodes*s] = exp(nodePot[n+nNodes*s]); } } for(e = 0; e < nEdges; e++) { n1 = edgeEnds[e]-1; n2 = edgeEnds[e+nEdges]-1; for (s1 = 0; s1 < nStates[n1]; s1++) { for (s2 = 0; s2 < nStates[n2]; s2++) { for (f = 0; f < nEdgeFeatures; f++) { if (edgeMap[s1 + maxState*(s2 + maxState*(e + nEdges*f))] > 0) { edgePot[s1+maxState*(s2+maxState*e)] += w[edgeMap[s1+maxState*(s2+maxState*(e+nEdges*f))]-1]*Xedge[i + nInstances*(f+nEdgeFeatures*e)]; } } edgePot[s1+maxState*(s2+maxState*e)] = exp(edgePot[s1+maxState*(s2+maxState*e)]); } } } }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { const double* Loc_Max_ptr ; const double* DoGs_ptr ; const int* dims; double threshold = 0.01 ; //0.01 the extrema not less than threshold. double r = 10.0 ; // Eliminating edge responses, threshold. double* result ; enum {IN_LOC=0,IN_DOGS,IN_THRESHOLD,IN_R} ; enum {OUT_Q=0} ; if(nin >= 3) { threshold = *mxGetPr(in[IN_THRESHOLD]) ; } if(nin >= 4) { r = *mxGetPr(in[IN_R]); } // DoGs int M,N,S; dims = mxGetDimensions(in[IN_DOGS]); M = dims[0] ; //y range [1,M] N = dims[1] ; //x range [1,N] S = dims[2] ; //scale [1,S] if(S < 3 || M < 3 || N < 3) { mexErrMsgTxt("All dimensions of DOG must be not less than 3.") ; } DoGs_ptr = mxGetPr(in[IN_DOGS]) ; // head pointer of DoGs vectors (M*N*S) // Local Max Points int LOCAL_MAX_NUM = mxGetN(in[IN_LOC]) ; //the number of Local Maximum points . Loc_Max_ptr = mxGetPr(in[IN_LOC]) ; // head pointer of Local Max vector (3*LOCAL_MAX_NUM) // If the input array is empty, then output an empty array as well. if( LOCAL_MAX_NUM == 0) { out[OUT_Q] = mxDuplicateArray(in[IN_LOC]) ; return ; } /////////////////////////////////////////////////////////////////////// double* buffer = (double*) mxMalloc(LOCAL_MAX_NUM*3*sizeof(double)) ; double* buffer_iterator = buffer ; // (M,N,S) const int Y_OFFSET = 1; const int X_OFFSET = M; const int S_OFFSET = M*N ; for(int p = 0 ; p < LOCAL_MAX_NUM ; ++p) { int x = ((int)*Loc_Max_ptr++) ; int y = ((int)*Loc_Max_ptr++) ; int s = ((int)*Loc_Max_ptr++) ; double _offset[3] ; #define at(dx,dy,ds) (*(pt + (dx)*X_OFFSET + (dy)*Y_OFFSET + (ds)*S_OFFSET)) const double* pt = DoGs_ptr + y*Y_OFFSET + x*X_OFFSET + s*S_OFFSET; double Dx=0,Dy=0,Ds=0,Dxx=0,Dyy=0,Dss=0,Dxy=0,Dxs=0,Dys=0 ; int dx = 0; int dy = 0; // find the sample point that th offset (dx,dy,ds) for(int iter = 0 ; iter < MAX_ITER ; ++iter) { double H[3*3] ; x += dx ; y += dy ; pt = DoGs_ptr + y*Y_OFFSET + x*X_OFFSET + s*S_OFFSET ; // Compute the gradient. Dx = 0.5 * (at(+1,0,0) - at(-1,0,0)) ; Dy = 0.5 * (at(0,+1,0) - at(0,-1,0)); Ds = 0.5 * (at(0,0,+1) - at(0,0,-1)) ; // Compute the Hessian. Dxx = (at(+1,0,0) + at(-1,0,0) - 2.0 * at(0,0,0)) ; Dyy = (at(0,+1,0) + at(0,-1,0) - 2.0 * at(0,0,0)) ; Dss = (at(0,0,+1) + at(0,0,-1) - 2.0 * at(0,0,0)) ; Dxy = 0.25 * ( at(+1,+1,0) + at(-1,-1,0) - at(-1,+1,0) - at(+1,-1,0) ) ; Dxs = 0.25 * ( at(+1,0,+1) + at(-1,0,-1) - at(-1,0,+1) - at(+1,0,-1) ) ; Dys = 0.25 * ( at(0,+1,+1) + at(0,-1,-1) - at(0,-1,+1) - at(0,+1,-1) ) ; //Hessian matrix H[0+3*0] = Dxx; H[1+3*1] = Dyy; H[2+3*2] = Dss; H[0+3*1] = H[1+3*0] = Dxy; H[0+3*2] = H[2+3*0] = Dxs; H[1+3*2] = H[2+3*1] = Dys; // solve linear system _offset[0] = - Dx ; _offset[1] = - Dy ; _offset[2] = - Ds ; // Gauss elimination //row reduction int i,j,ii,jj; for(j = 0 ; j < 3 ; ++j) { double Max_h = 0 ; double Max_abs_h = 0 ; int max_idx = -1 ; // look for the maximally stable pivot for (i = j ; i < 3 ; ++i) { if ( abs(H[i+3*j]) > Max_abs_h) { Max_h = H[i+3*j]; Max_abs_h = abs(H[i+3*j]) ; max_idx = i; } } // if singular give up if (Max_abs_h < 1e-10f) { _offset[0] = 0 ; _offset[1] = 0 ; _offset[2] = 0 ; break ; } double tmp; // swap j-th row with i-th row and normalize j-th row for(jj = j ; jj < 3 ; ++jj) { tmp = H[max_idx+3*jj] ; H[max_idx+3*jj] = H[j+3*jj] ; H[j+3*jj] = tmp ; H[j+3*jj] /= Max_h; } tmp = _offset[j] ; _offset[j] = _offset[max_idx] ; _offset[max_idx] = tmp ; _offset[j] /= Max_h ; // elimination for (ii = j+1 ; ii < 3 ; ++ii) { double x = H[ii+3*j] ; for (jj = j ; jj < 3 ; ++jj) { H[ii+3*jj] -= x * H[j+3*jj] ; } _offset[ii] -= x * _offset[j] ; } } // backward substitution for (i = 2 ; i > 0 ; --i) { double x = _offset[i] ; for (ii = i-1 ; ii >= 0 ; --ii) { _offset[ii] -= x * H[ii+3*i] ; } } // If the translation of the keypoint is big, move the keypoint // and re-iterate the computation. Otherwise we are all set. // // 0.6 -> 0.5 double thes = 0.6; dx= ((_offset[0] > thes && x < N-2) ? 1 : 0 ) + ((_offset[0] < -thes && x > 1 ) ? -1 : 0 ) ; dy= ((_offset[1] > thes && y < M-2) ? 1 : 0 ) + ((_offset[1] < -thes && y > 1 ) ? -1 : 0 ) ; if( dx == 0 && dy == 0 ) break ; } // the extrema value double val = at(0,0,0) + 0.5 * (Dx * _offset[0] + Dy * _offset[1] + Ds * _offset[2]) ; double score = (Dxx+Dyy)*(Dxx+Dyy) / (Dxx*Dyy - Dxy*Dxy) ; double xn = x + _offset[0] ; double yn = y + _offset[1] ; double sn = s + _offset[2] ; if( fabs(val) > threshold && fabs(_offset[0]) < 1.5 && fabs(_offset[1]) < 1.5 && fabs(_offset[2]) < 1.5 && xn >= 0 && xn <= N-1 && yn >= 0 && yn <= M-1 && sn >= 0 && sn <= S-1) { *buffer_iterator++ = xn; *buffer_iterator++ = yn; *buffer_iterator++ = sn; } } // Copy the result into an array. { int NL = (buffer_iterator - buffer)/3 ; out[OUT_Q] = mxCreateDoubleMatrix(3, NL, mxREAL) ; result = mxGetPr(out[OUT_Q]); memcpy(result, buffer, sizeof(double) * 3 * NL) ; } mxFree(buffer) ; }
/* The matlab mex function */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { float *Fx, *Fy, *Fz, *Bx, *By, *Bz, *H, *Num; /* Size of input transformation fields */ mwSize Bsizex, Bsizey, Bsizez; const mwSize *Bdims; /* Size of the input kernel */ mwSize Hsizex, Hsizey, Hsizez; const mwSize *Hdims; int hx_center, hy_center, hz_center; /* Variables to store 1D index */ int index; /* Variable to store vector */ float valx, valy, valz; /* Loop variable */ int i, t, iHx, iHy, iHz; /* Linear interpolation variables */ int xBas0, xBas1,yBas0,yBas1,zBas0,zBas1; float perc[8], perct; float xCom, yCom, zCom; float Tlocalx, Tlocaly, Tlocalz; /* X,Y coordinates of current pixel */ int x,y, z, tx, ty, tz; /* Check for proper number of arguments. */ if(nrhs!=4) { mexErrMsgTxt("Four inputs are required."); } else if(nlhs!=3) { mexErrMsgTxt("Three outputs are required"); } /* Get the sizes of the kernel */ Hdims = mxGetDimensions(prhs[3]); Hsizex = Hdims[0]; Hsizey = Hdims[1]; Hsizez = Hdims[2]; /* Get the sizes of the input transformation fields */ Bdims = mxGetDimensions(prhs[0]); Bsizex = Bdims[0]; Bsizey = Bdims[1]; Bsizez = Bdims[2]; /* Create output array */ plhs[0] = mxCreateNumericArray(3, Bdims, mxSINGLE_CLASS, mxREAL); plhs[1] = mxCreateNumericArray(3, Bdims, mxSINGLE_CLASS, mxREAL); plhs[2] = mxCreateNumericArray(3, Bdims, mxSINGLE_CLASS, mxREAL); /* Create array to count number of kernels added */ Num = (float *)malloc(Bsizex*Bsizey*Bsizez*sizeof(float)); for (i=0; i<(Bsizex*Bsizey*Bsizez); i++){ Num[i] = 0;} /* Assign pointers to each input. */ Bx=(float *)mxGetData(prhs[0]); By=(float *)mxGetData(prhs[1]); Bz=(float *)mxGetData(prhs[2]); H=(float *)mxGetData(prhs[3]); /* Assign pointer to output. */ Fx = (float *)mxGetData(plhs[0]); Fy = (float *)mxGetData(plhs[1]); Fz = (float *)mxGetData(plhs[2]); /* Gaussian kernel center */ hx_center=(int)-floor((double)Hsizex/2); hy_center=(int)-floor((double)Hsizey/2); hz_center=(int)-floor((double)Hsizez/2); /* Loop through all image pixel coordinates */ for (z=0; z<Bsizez; z++) { for (y=0; y<Bsizey; y++) { for (x=0; x<Bsizex; x++) { valx=-Bx[mindex3(x,y,z,Bsizex,Bsizey)]; valy=-By[mindex3(x,y,z,Bsizex,Bsizey)]; valz=-Bz[mindex3(x,y,z,Bsizex,Bsizey)]; Tlocalx =x-valx; Tlocaly =y-valy; Tlocalz =z-valz; /* Determine the coordinates of the pixel(s) which will be come the current pixel */ /* (using linear interpolation) */ xBas0=(int) floor(Tlocalx); yBas0=(int) floor(Tlocaly); zBas0=(int) floor(Tlocalz); xBas1=xBas0+1; yBas1=yBas0+1; zBas1=zBas0+1; /* Linear interpolation constants (percentages) */ xCom=Tlocalx-(float)floor((double)Tlocalx); yCom=Tlocaly-(float)floor((double)Tlocaly); zCom=Tlocalz-(float)floor((double)Tlocalz); perc[0]=(1-xCom) * (1-yCom) * (1-zCom); perc[1]=(1-xCom) * (1-yCom) * zCom; perc[2]=(1-xCom) * yCom * (1-zCom); perc[3]=(1-xCom) * yCom * zCom; perc[4]=xCom * (1-yCom) * (1-zCom); perc[5]=xCom * (1-yCom) * zCom; perc[6]=xCom * yCom * (1-zCom); perc[7]=xCom * yCom * zCom; /* Loop through the whole kernel */ for (iHx=0; iHx<Hsizex; iHx++) { for (iHy=0; iHy<Hsizey; iHy++) { for (iHz=0; iHz<Hsizez; iHz++) { /* Process all 4 neighbors */ for(t=0; t<8; t++) { if(t==0){ tx=xBas0+iHx+hx_center; ty=yBas0+iHy+hy_center; tz=zBas0+iHz+hz_center; perct=perc[0]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)]; } else if(t==1){ tx=xBas0+iHx+hx_center; ty=yBas0+iHy+hy_center; tz=zBas1+iHz+hz_center; perct=perc[1]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)]; } else if(t==2){ tx=xBas0+iHx+hx_center; ty=yBas1+iHy+hy_center; tz=zBas0+iHz+hz_center; perct=perc[2]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)]; } else if(t==3){ tx=xBas0+iHx+hx_center; ty=yBas1+iHy+hy_center; tz=zBas1+iHz+hz_center; perct=perc[3]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)]; } else if(t==4){ tx=xBas1+iHx+hx_center; ty=yBas0+iHy+hy_center; tz=zBas0+iHz+hz_center; perct=perc[4]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)]; } else if(t==5){ tx=xBas1+iHx+hx_center; ty=yBas0+iHy+hy_center; tz=zBas1+iHz+hz_center; perct=perc[5]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)]; } else if(t==6){ tx=xBas1+iHx+hx_center; ty=yBas1+iHy+hy_center; tz=zBas0+iHz+hz_center; perct=perc[6]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)]; } else{ tx=xBas1+iHx+hx_center; ty=yBas1+iHy+hy_center; tz=zBas1+iHz+hz_center; perct=perc[7]*H[mindex3(iHx,iHy,iHz,Hsizex,Hsizey)]; } if((tx>=0)&&(ty>=0)&&(tz>=0)&&(tx<Bsizex)&&(ty<Bsizey)&&(tz<Bsizez)) { index=mindex3(tx,ty,tz,Bsizex,Bsizey); Fx[index]+=valx*perct; Fy[index]+=valy*perct; Fz[index]+=valz*perct; Num[index]=Num[index]+perct; } } } } } } } } for (z=0; z<Bsizez; z++) { for (y=0; y<Bsizey; y++) { for (x=0; x<Bsizex; x++) { index=mindex3(x,y,z,Bsizex,Bsizey); Fx[index]/=(Num[index]+(float)0.00000001); Fy[index]/=(Num[index]+(float)0.00000001); Fz[index]/=(Num[index]+(float)0.00000001); } } } free(Num); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { int argc, buflen, startPos, endPos, ii,i, numberColours; int counter, nrArgs, rowLen, colLen; char *argString; u8* imgPointer; /*range [0,255]*/ char **argv; const int *dimVec; if (nrhs != 2) mexErrMsgTxt("error: 2 input argument expected."); if (nlhs != 1) mexErrMsgTxt("error: 1 output argument expected."); /* Get the length of the input string. */ buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1; /* printf("buflen = %i\n", buflen); */ /* Allocate memory for input and output strings. */ argString = mxCalloc(buflen, sizeof(char)); mxGetString(prhs[0], argString, buflen); /* printf("argString = %s\n", argString); */ /* count number of white space in argument */ argc = 0; for (i = 0; i < buflen; i++) { if (argString[i] == ' ') argc = argc+1; } argc = argc+1; /* bcs program name counts too */ argc = argc+1; /* bcs last option is not followed by whitespace */ /* printf("argc = %i\n", argc); */ /* now split up string into arguments */ argv = (char**) mxMalloc(argc*sizeof(char*)); startPos = 0; counter = 0; argv[counter] = (char*) mxMalloc(4*sizeof(char)); argv[counter] = "hog"; startPos = 0; for (i = 0; i < buflen; i++) { if (argString[i] == ' ') { endPos = i-1; counter++; argv[counter] = (char*) mxMalloc((endPos-startPos+1+1)*sizeof(char)); for (ii=startPos; ii<=endPos;ii++) { argv[counter][ii-startPos] = argString[ii]; } argv[counter][endPos-startPos+1] = '\0'; startPos = i+1; } } /* add last argument (which is not followed by whitespace) */ endPos = buflen-1; counter++; argv[counter] = (char*) mxMalloc((endPos-startPos+1+1)*sizeof(char)); for (ii=startPos; ii<=endPos;ii++) { argv[counter][ii-startPos] = argString[ii]; } argv[counter][endPos-startPos+1] = '\0'; if (argc!=counter+1) { printf("argc=%d; counter=%d\n",argc,counter); mexErrMsgTxt("UPS something wrong with the arguments\n"); } /* get image */ imgPointer = (u8*) mxGetPr(prhs[1]); dimVec = mxGetDimensions(prhs[1]); if (mxGetNumberOfDimensions(prhs[1])==2) { rowLen = dimVec[0]; /* (int) mxGetM(prhs[1]); */ colLen = dimVec[1]; /* (int) mxGetN(prhs[1]); */ numberColours = 1; } else { rowLen = dimVec[1]; /* (int) mxGetM(prhs[1]); */ colLen = dimVec[2]; /* (int) mxGetN(prhs[1]); */ numberColours = dimVec[0]; } /* mexPrintf("numberColours=%d\n;rowLen=%d\n;colLen=%d\n",numberColours,rowLen,colLen); */ /* call original main */ mainOrig(argc, argv, plhs, rowLen, colLen, imgPointer, numberColours); /* free argv using loops! */ /*for (i = 0; i < argc; i++) { printf("free argv[%d] = %s %p\n",i,argv[i],argv[i]); mxFree(argv[i]); } mxFree(argv); */ }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){ /* Variable declarations */ unsigned int iNeighbor; signed int dim; unsigned int *nthreads; struct ThreadData *threadData; unsigned int iThread, numPtsPerThread; pthread_t *thread; /* INPUT 0 - UNFILTERED VOLUME */ dims = mxGetDimensions(prhs[0]); nDims = mxGetNumberOfDimensions(prhs[0]); unfiltVol = mxGetPr(prhs[0]); /* INPUT 1 - FILTERED VOLUME */ filtVol = mxGetPr(prhs[1]); /* INPUT 2 - FILTER RADIUS */ filt_radius = mxGetPr(prhs[2]); /* INPUT 3 - PROXIMITY SIGMA */ proximity_sigma = mxGetPr(prhs[3]); /* INPUT 4 - INTENSITY SIGMA */ intensity_sigma = mxGetPr(prhs[4]); /* INPUT 5 - NTHREADS */ nthreads = (unsigned int*)mxGetPr(prhs[5]); threadData = calloc(*nthreads,sizeof(struct ThreadData)); thread = calloc(*nthreads,sizeof(pthread_t)); // Allocate memory for temp variables cur_nhood_idx = calloc(nDims, sizeof(signed int)); idx_convert = calloc(nDims, sizeof(unsigned int)); inv_proximity_sigma_sqr = calloc(nDims, sizeof(double)); //Calculate number of voxels and set starting voxel to first voxel nVox = dims[0]; idx_convert[0] = 1; maxNeighbors = floor(2*filt_radius[0]+1); cur_nhood_idx[0] = -filt_radius[0]; for(dim=1; dim<nDims; dim++){ nVox = nVox * dims[dim]; idx_convert[dim] = idx_convert[dim-1]*dims[dim-1]; maxNeighbors = maxNeighbors*floor(2*filt_radius[dim]+1); cur_nhood_idx[dim] = -filt_radius[dim]; inv_proximity_sigma_sqr[dim] = -0.5/(proximity_sigma[dim]*proximity_sigma[dim]); } inv_intensity_sigma_sqr = -0.5/(intensity_sigma[0]*intensity_sigma[0]); /* allocate */ d_proximity = calloc(maxNeighbors, sizeof(double)); neigh_shift = calloc(maxNeighbors, sizeof(signed int)); for(iNeighbor=0; iNeighbor<maxNeighbors; iNeighbor++){ d_proximity[iNeighbor] = 0; neigh_shift[iNeighbor] = 0; for(dim=0; dim<nDims; dim++){ d_proximity[iNeighbor] = d_proximity[iNeighbor] + (cur_nhood_idx[dim]*cur_nhood_idx[dim]*inv_proximity_sigma_sqr[dim]); neigh_shift[iNeighbor] = neigh_shift[iNeighbor] + cur_nhood_idx[dim]*idx_convert[dim]; } d_proximity[iNeighbor] = exp(d_proximity[iNeighbor]); //Update neighbor inxex for next neighbor for(dim=0; dim<nDims; dim++){ if(cur_nhood_idx[dim]==(filt_radius[dim])){ //Reset that dimmension, then the next dimmension will increment cur_nhood_idx[dim] = -filt_radius[dim]; }else{ cur_nhood_idx[dim]++; break; } } } numPtsPerThread = floor(((float)nVox)/(*nthreads)); for(iThread=0; iThread<*nthreads; iThread++){ threadData[iThread].startVox = iThread*numPtsPerThread; threadData[iThread].endVox = (iThread+1)*numPtsPerThread-1; } threadData[*nthreads-1].endVox = nVox-1; for(iThread=0; iThread<*nthreads; iThread++){ pthread_create(&thread[iThread], NULL, filterVoxels, &threadData[iThread]); } /* Wait for threads to finish */ for(iThread=0; iThread<*nthreads; iThread++){ pthread_join(thread[iThread],NULL); } // Free up temp variables free(cur_nhood_idx); free(idx_convert); free(d_proximity); free(neigh_shift); free(inv_proximity_sigma_sqr); free(threadData); free(thread); }
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray*prhs[]) { int n; if(nlhs < 1) { mexErrMsgTxt("Too few output arguments."); return; } if( nrhs < 5) { mexErrMsgTxt("At least five parameters should be provided."); return ; } /*参数类型核对*/ if(!mxIsUint8(prhs[0]))/*像素值必须是0-255之间*/ { mexErrMsgTxt("The pixels must be a type of uint8"); return; } if(!mxIsEmpty(prhs[1]) && !mxIsInt32(prhs[1])) { mexErrMsgTxt("The position type must be int32"); return; } if(!mxIsEmpty(prhs[2]) && !mxIsInt32(prhs[2])) { mexErrMsgTxt("The position type must be int32"); return; } if((!mxIsEmpty(prhs[1]) && mxGetDimensions(prhs[1])[1]!= 2) ||(!mxIsEmpty(prhs[2]) && mxGetDimensions(prhs[2])[1]!= 2)) { mexErrMsgTxt("The position set must be a matrix of n times 2"); return ; } if(!mxIsInt32(prhs[3])) { mexErrMsgTxt("The windows size must be int32"); return ; } if(!mxIsUint8(prhs[4])) { mexErrMsgTxt("The color board must be a type of uint8"); return; } n =(int) mxGetScalar(prhs[3]);/*size of window*/ if( n%2==0) { mexErrMsgTxt("The size of window must be an odd number."); return ; } /*对于稀疏矩阵,暂且不予考虑*/ if(!mxIsSparse(prhs[0])) { const int*dims = mxGetDimensions(prhs[0]); int i,j,k,height,width; height = dims[0],width = dims[1]; if( height <= n || width <= n) { mexErrMsgTxt("The size of image must be greater than the window size"); return; } PCOLOR colorboard =(PCOLOR) mxGetPr(prhs[4]); int numpixelsA,numpixelsB; numofcolor = (int) mxGetNumberOfElements(prhs[4]); /*Note the max gray value is 255*/ colors = (PCOLOR)mxCalloc(256,sizeof(COLOR)); for( i = 0; i< numofcolor; i++) colors[(int)colorboard[i]] = i; /*extract the pixels values*/ pix = (PCOLOR)mxGetPr(prhs[0]); /*PPCOLOR pixels = (PPCOLOR) mxCalloc(height,sizeof(PCOLOR)); for( i = 0; i < height; i++) pixels[i] = (PCOLOR)mxCalloc(width,sizeof(COLOR));*/ boardx =(int**) mxCalloc(n,sizeof(int*)); boardy = (int**) mxCalloc(n,sizeof(int*)); for( i = 0; i < n; i++) { boardx[i] = (int*) mxCalloc(n,sizeof(int)); boardy[i] = (int*) mxCalloc(n,sizeof(int)); } k = n/2; for( i = 0; i < n; i++) for( j = 0; j<n; j++) { boardx[i][j] = -k + i; boardy[i][j] = -k + j; } /*for( i = 0; i < height; i++) for(j = 0; j< width; j++) { pixels[i][j] = (COLOR)pix[i*width + j]; }*/ PPOSTYPE pixelsposA = NULL; if(!mxIsEmpty(prhs[1])) { pixelsposA = (PPOSTYPE)mxGetPr(prhs[1]); numpixelsA = mxGetDimensions(prhs[1])[0];/*sample size*/ } else numpixelsA = height * width; PPOSTYPE pixelsposB = NULL; if(!mxIsEmpty(prhs[2])) { pixelsposB = (PPOSTYPE)mxGetPr(prhs[2]); numpixelsB = mxGetDimensions(prhs[2])[0]; } else numpixelsB = height * width; /*Alloc memory for all the sample pixels to store their histograms*/ double** histogramsA; double** histogramsB; if( pixelsposA == NULL && pixelsposB == NULL) { histogramsA =(double**) mxCalloc(numpixelsA,sizeof(double*)); for( i = 0; i < numpixelsA; i++) histogramsA[i] =(double*) mxCalloc(numofcolor,sizeof(double)); histogramsB = histogramsA; } else { histogramsA =(double**) mxCalloc(numpixelsA,sizeof(double*)); for( i = 0; i < numpixelsA; i++) histogramsA[i] =(double*) mxCalloc(numofcolor,sizeof(double)); histogramsB = (double**) mxCalloc(numpixelsB, sizeof(double*)); for( i = 0; i< numpixelsB; i++) histogramsB[i] = (double*) mxCalloc(numofcolor,sizeof(double)); } if( pixelsposB== NULL && pixelsposA == NULL) { calc_histograms(histogramsA,pixelsposA,numpixelsA,pix,n,height,width); // calc_histograms(histogramsB,pixelsposB,numpixelsB,pixels,n,height,width); } else { calc_histograms(histogramsA,pixelsposA,numpixelsA,pix,n,height,width); calc_histograms(histogramsB,pixelsposB,numpixelsB,pix,n,height,width); #ifdef DEBUG { FILE* a = fopen("histogramA.txt","w+"); FILE* b = fopen("histogramB.txt","w+"); int i,j; for( i = 0;i<numpixelsA;i++) { for( j = 0; j<numofcolor; j++) fprintf(a,"%.10lf\t\t",histogramsA[i][j]); fprintf(a,"\n"); } for( i = 0;i<numpixelsB;i++) { for( j = 0; j<numofcolor; j++) fprintf(b,"%.10lf\t\t",histogramsB[i][j]); fprintf(b,"\n"); } fclose(a); fclose(b); } #endif } /*Free Memory*/ mxFree(colors); /*for( i = 0; i < height; i++) mxFree(pixels[i]); mxFree(pixels);*/ for( i = 0; i < n; i++) { mxFree(boardx[i]); mxFree(boardy[i]); } mxFree(boardx); mxFree(boardy); /*Now calc the x^2 distance.*/ /*double* ptr = mxGetPr(plhs[0]); mxFree(ptr);*/ plhs[0] = mxCreateDoubleMatrix(1, 2, mxREAL); mxFree(mxGetPr(plhs[0])); double* nptr = calc_tao_distance(histogramsA,histogramsB,numpixelsA,numpixelsB,numofcolor); /*Free mem*/ for( i = 0; i< numpixelsA; i++) mxFree(histogramsA[i]); mxFree(histogramsA); if( !(pixelsposB== NULL && pixelsposA == NULL)) { for( i = 0; i< numpixelsB; i++) mxFree(histogramsB[i]); mxFree(histogramsB); } mxSetPr(plhs[0],nptr); mxSetM(plhs[0],numpixelsA); mxSetN(plhs[0],numpixelsB); } else { mexErrMsgTxt("The color pixels matrix should not be a sparse one!"); } return; }
void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { int M,N,S,smin,K ; const int* dimensions ; const double* P_pt ; const double* D_pt ; double threshold = 0.01 ; /*0.02 ;*/ double r = 10.0 ; double* result ; enum {IN_P=0,IN_D,IN_SMIN,IN_THRESHOLD,IN_R} ; enum {OUT_Q=0} ; /* ----------------------------------------------------------------- ** Check the arguments ** -------------------------------------------------------------- */ if (nin < 3) { mexErrMsgTxt("At least three input arguments required."); } else if (nout > 1) { mexErrMsgTxt("Too many output arguments."); } if( !uIsRealMatrix(in[IN_P],3,-1) ) { mexErrMsgTxt("P must be a 3xK real matrix") ; } if( !mxIsDouble(in[IN_D]) || mxGetNumberOfDimensions(in[IN_D]) != 3) { mexErrMsgTxt("G must be a three dimensional real array.") ; } if( !uIsRealScalar(in[IN_SMIN]) ) { mexErrMsgTxt("SMIN must be a real scalar.") ; } if(nin >= 4) { if(!uIsRealScalar(in[IN_THRESHOLD])) { mexErrMsgTxt("THRESHOLD must be a real scalar.") ; } threshold = *mxGetPr(in[IN_THRESHOLD]) ; } if(nin >= 5) { if(!uIsRealScalar(in[IN_R])) { mexErrMsgTxt("R must be a real scalar.") ; } r = *mxGetPr(in[IN_R]) ; } dimensions = mxGetDimensions(in[IN_D]) ; M = dimensions[0] ; N = dimensions[1] ; S = dimensions[2] ; smin = (int)(*mxGetPr(in[IN_SMIN])) ; if(S < 3 || M < 3 || N < 3) { mexErrMsgTxt("All dimensions of DOG must be not less than 3.") ; } K = mxGetN(in[IN_P]) ; P_pt = mxGetPr(in[IN_P]) ; D_pt = mxGetPr(in[IN_D]) ; /* If the input array is empty, then output an empty array as well. */ if( K == 0) { out[OUT_Q] = mxDuplicateArray(in[IN_P]) ; return ; } /* ----------------------------------------------------------------- * Do the job * -------------------------------------------------------------- */ { double* buffer = (double*) mxMalloc(K*3*sizeof(double)) ; double* buffer_iterator = buffer ; int p ; const int yo = 1 ; const int xo = M ; const int so = M*N ; for(p = 0 ; p < K ; ++p) { int x = ((int)*P_pt++) ; int y = ((int)*P_pt++) ; int s = ((int)*P_pt++) - smin ; int iter ; double b[3] ; /* Local maxima extracted from the DOG * have coorrinates 1<=x<=N-2, 1<=y<=M-2 * and 1<=s-mins<=S-2. This is also the range of the points * that we can refine. */ if(x < 1 || x > N-2 || y < 1 || y > M-2 || s < 1 || s > S-2) { continue ; } #define at(dx,dy,ds) (*(pt + (dx)*xo + (dy)*yo + (ds)*so)) { const double* pt = D_pt + y*yo + x*xo + s*so ; double Dx=0,Dy=0,Ds=0,Dxx=0,Dyy=0,Dss=0,Dxy=0,Dxs=0,Dys=0 ; int dx = 0 ; int dy = 0 ; int j, i, jj, ii ; for(iter = 0 ; iter < max_iter ; ++iter) { double A[3*3] ; #define Aat(i,j) (A[(i)+(j)*3]) x += dx ; y += dy ; pt = D_pt + y*yo + x*xo + s*so ; /* Compute the gradient. */ Dx = 0.5 * (at(+1,0,0) - at(-1,0,0)) ; Dy = 0.5 * (at(0,+1,0) - at(0,-1,0)); Ds = 0.5 * (at(0,0,+1) - at(0,0,-1)) ; /* Compute the Hessian. */ Dxx = (at(+1,0,0) + at(-1,0,0) - 2.0 * at(0,0,0)) ; Dyy = (at(0,+1,0) + at(0,-1,0) - 2.0 * at(0,0,0)) ; Dss = (at(0,0,+1) + at(0,0,-1) - 2.0 * at(0,0,0)) ; Dxy = 0.25 * ( at(+1,+1,0) + at(-1,-1,0) - at(-1,+1,0) - at(+1,-1,0) ) ; Dxs = 0.25 * ( at(+1,0,+1) + at(-1,0,-1) - at(-1,0,+1) - at(+1,0,-1) ) ; Dys = 0.25 * ( at(0,+1,+1) + at(0,-1,-1) - at(0,-1,+1) - at(0,+1,-1) ) ; /* Solve linear system. */ Aat(0,0) = Dxx ; Aat(1,1) = Dyy ; Aat(2,2) = Dss ; Aat(0,1) = Aat(1,0) = Dxy ; Aat(0,2) = Aat(2,0) = Dxs ; Aat(1,2) = Aat(2,1) = Dys ; b[0] = - Dx ; b[1] = - Dy ; b[2] = - Ds ; /* Gauss elimination */ for(j = 0 ; j < 3 ; ++j) { double maxa = 0 ; double maxabsa = 0 ; int maxi = -1 ; double tmp ; /* look for the maximally stable pivot */ for (i = j ; i < 3 ; ++i) { double a = Aat (i,j) ; double absa = abs (a) ; if (absa > maxabsa) { maxa = a ; maxabsa = absa ; maxi = i ; } } /* if singular give up */ if (maxabsa < 1e-10f) { b[0] = 0 ; b[1] = 0 ; b[2] = 0 ; break ; } i = maxi ; /* swap j-th row with i-th row and normalize j-th row */ for(jj = j ; jj < 3 ; ++jj) { tmp = Aat(i,jj) ; Aat(i,jj) = Aat(j,jj) ; Aat(j,jj) = tmp ; Aat(j,jj) /= maxa ; } tmp = b[j] ; b[j] = b[i] ; b[i] = tmp ; b[j] /= maxa ; /* elimination */ for (ii = j+1 ; ii < 3 ; ++ii) { double x = Aat(ii,j) ; for (jj = j ; jj < 3 ; ++jj) { Aat(ii,jj) -= x * Aat(j,jj) ; } b[ii] -= x * b[j] ; } } /* backward substitution */ for (i = 2 ; i > 0 ; --i) { double x = b[i] ; for (ii = i-1 ; ii >= 0 ; --ii) { b[ii] -= x * Aat(ii,i) ; } } /* If the translation of the keypoint is big, move the keypoint * and re-iterate the computation. Otherwise we are all set. */ dx= ((b[0] > 0.6 && x < N-2) ? 1 : 0 ) + ((b[0] < -0.6 && x > 1 ) ? -1 : 0 ) ; dy= ((b[1] > 0.6 && y < M-2) ? 1 : 0 ) + ((b[1] < -0.6 && y > 1 ) ? -1 : 0 ) ; if( dx == 0 && dy == 0 ) break ; } { double val = at(0,0,0) + 0.5 * (Dx * b[0] + Dy * b[1] + Ds * b[2]) ; double score = (Dxx+Dyy)*(Dxx+Dyy) / (Dxx*Dyy - Dxy*Dxy) ; double xn = x + b[0] ; double yn = y + b[1] ; double sn = s + b[2] ; if(fabs(val) > threshold && score < (r+1)*(r+1)/r && score >= 0 && fabs(b[0]) < 1.5 && fabs(b[1]) < 1.5 && fabs(b[2]) < 1.5 && xn >= 0 && xn <= N-1 && yn >= 0 && yn <= M-1 && sn >= 0 && sn <= S-1) { *buffer_iterator++ = xn ; *buffer_iterator++ = yn ; *buffer_iterator++ = sn+smin ; } } } } /* Copy the result into an array. */ { int NL = (buffer_iterator - buffer)/3 ; out[OUT_Q] = mxCreateDoubleMatrix(3, NL, mxREAL) ; result = mxGetPr(out[OUT_Q]); memcpy(result, buffer, sizeof(double) * 3 * NL) ; } mxFree(buffer) ; } }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { if(nrhs != 1 && nrhs != 2 && nrhs != 3) { printf("\nUsage: Df = STderivUp(f,difftyp,factor)\n\n",nrhs); printf(" Computes Spherical Up-Derivative\n"); printf(" Parameters:\n"); printf(" f - complex-interleaved 3D input image of type REAL \n"); printf(" difftyp - central (0) / forward (-1) / backward (1) (optional)\n"); printf(" factor - multiply result with factor (optional)\n\n"); return; } else if(nlhs>1) { printf("Too many output arguments\n"); return; } int pcnt = 0; const mxArray *Img; Img = prhs[pcnt++]; const int numdim = mxGetNumberOfDimensions(Img); const int *dims = mxGetDimensions(Img); int L = dims[0]/2; if (numdim != 4) return; int diff_type = 0; if (nrhs >= 2) { const mxArray *typ; typ = prhs[pcnt++]; diff_type = (int) *mxGetPr(typ); if (diff_type < -1 || diff_type > 1) diff_type = 0; } REAL factor = 1.0; if (nrhs == 3) { const mxArray *mxFactor = prhs[pcnt++]; if (mxGetClassID(mxFactor) == mxDOUBLE_CLASS) factor = (REAL) *((double*) mxGetData(mxFactor)); else if (mxGetClassID(mxFactor) == mxSINGLE_CLASS) factor = (REAL) *((float*) mxGetData(mxFactor)); else return; } REAL *img = (REAL*) mxGetData(Img); int ndims[4]; ndims[0] = (L + 1)*2; ndims[1] = dims[1]; ndims[2] = dims[2]; ndims[3] = dims[3]; plhs[0] = mxCreateNumericArray(4,ndims,mxGetClassID(Img),mxREAL); REAL *result = (REAL*) mxGetData(plhs[0]); if (diff_type == -1) STderivRealForward(img,&(ndims[1]),L,result,factor); else if (diff_type == 1) STderivRealBackward(img,&(ndims[1]),L,result,factor); else if (diff_type == 0) STderivReal(img,&(ndims[1]),L,result,factor); }
// X = get_x_slice32c15(img, ind); // img: [a,b,c]. int16. the CT volume // ind: [M]. linear index to the image for the locations of sampling points // X: [32, 32, 15, M]. single. the slices data batch void mexFunction(int no, mxArray *vo[], int ni, mxArray const *vi[]) { //// Input mxArray const *img = vi[0]; mxArray const *ind = vi[1]; ///// Create Output and set it mwSize M = mxGetM(ind) * mxGetN(ind); mwSize dims[4] = {S,S,C,0}; dims[3] = M; mxArray *X = mxCreateNumericArray(4, dims, mxSINGLE_CLASS, mxREAL); vo[0] = X; //// do the job int16_T *p_img = (int16_T*) mxGetData(img); const mwSize *sz_img; sz_img = mxGetDimensions(img); double *p_ind = (double*) mxGetData(ind); float *p_X = (float*) mxGetData(X); // iterate over center points #pragma omp parallel for for (int64_T m = 0; m < M; ++m) { // center index --> center point mwSize ixcen = mwSize( *(p_ind + m) ); ixcen -= 1; // Matlab 1 base -> C 0 base mwSize pntcen[3]; ix_to_pnt3d(sz_img, ixcen, pntcen); { // dim_1, dim_2, dim_3 (CC planes): inner to outer mwSize stride_X = 0 + S*S*C*m; float *pp = p_X + stride_X; for (int k = 0; k < CC; ++k) { for (int j = (-SS); j < SS; ++j) { for (int i = (-SS); i < SS; ++i) { // the working offset int d[3]; d[0] = i; d[1] = j; d[2] = CHANNNEL_OFFSET_TMPL[k]; // value on the image float val; get_val_from_offset(p_img, sz_img, pntcen, d, val); // write back *pp = val; ++pp; } // for i } // for j } // for k } { // dim_2, dim_3, dim_1(CC planes): inner to outer mwSize stride_X = 1*S*S*CC + S*S*C*m; float *pp = p_X + stride_X; for (int i = 0; i < CC; ++i) { for (int k = (-SS); k < SS; ++k) { for (int j = (-SS); j < SS; ++j) { // the working offset int d[3]; d[0] = CHANNNEL_OFFSET_TMPL[i]; d[1] = j; d[2] = k; // value on the image float val; get_val_from_offset(p_img, sz_img, pntcen, d, val); // write back *pp = val; ++pp; } // for j } // for k } // for i } { // dim_1, dim_3, dim_2(CC planes): inner to outer int stride = 2*S*S*CC + S*S*C*m; float *pp = p_X + stride; for (int j = 0; j < CC; ++j) { for (int k = (-SS); k < SS; ++k) { for (int i = (-SS); i < SS; ++i) { // the working offset int d[3]; d[0] = i; d[1] = CHANNNEL_OFFSET_TMPL[j]; d[2] = k; // value on the image float val; get_val_from_offset(p_img, sz_img, pntcen, d, val); // write back *pp = val; ++pp; } // for i } // for k } // for j } } // for m return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { // ************************************************************************** // variables declaration // ************************************************************************** // variables for both Loopy and GBP double*** initMsg = 0; bool trw = false; bool full = true; double* countingNode = 0; // relevant for loopy, or for gbp if trw = true // variables for Loopy Strategy strategy; SumOrMax sumOrMax; double gbp_alpha; double** rho = 0; // relevant if trw = true bool saveTime = false; // variables for GBP int*** assignInd = 0; double* bethe = 0; GBPPreProcessor* processor = 0; MRF* reg_mrf = 0; RegionLevel* regions = 0; vector<RegionLevel>* allRegions = 0; Potentials* bigRegsPot = 0; bool allLevels = false; bool regBeliefs = false; int num_regs = 0; // variables for Monte-Carlo int burningTime, samplingInterval, num_samples; int* startX = 0; // for Loopy, Mean-Field bool logspace = false; bool logBels = false; // for Loopy,GBP,Mean-Field int maxIter; double threshold; // ************************************************************************** // reading input arguments // ************************************************************************** // check number of input arguments. // arguments should be: // // adjMat - 1xN cell array, each cell {i} is a row vector with the indices of // i's neighbours // // lambda - there are 2 forms for lambda: // 1. in general MRF algorithms (loopy, gbp, gibbs, mean-field) : // lambda should be a cell array of 1xN, each cell {i} is a cell // array of 1xneighbNum(i). each cell {i}{n} is a VixVj matrix, // where j is the n-th neighbour of i // 2. in PottsMRF alhorithms (monte-carlo algorithms which are planned // for Potts model, i.e. metropolis and the cluster algorithms // wolff and swendsen-wang) : // here lambda should be 1xN cell array, each cell {i} is a row // vector with the strength of interaction of i with each of its // neighbours // note: Psi{i,j} = exp( [lambda(i,j), 0; 0, lambda(i,j)] ) // // local - cell array of Nx1, each cell {i} is a row vector of length Vi // // algorithm - integer representing the inference algorithm to use, see the // enumerator algorithmType at the top of this page // // temperature - double scalar, the temperature of the system // // model - integeger representing the model, see the enumerator in "definitions.h" // // trw - use Tree-Reweighted // // for other parameters required for each algorithm see the header of "inference.m" // // // note: N = number of nodes, V = number of possible values if (nrhs < 10 || nrhs > 20) { mexErrMsgTxt("Incorrect number of inputs."); } // get algorithm-type algorithmType algo_type = (algorithmType)((int)(mxGetScalar(prhs[3]))); Model model = (Model)((int)(mxGetScalar(prhs[5]))); bool potts_model = ((model==POTTS) || (algo_type==AT_WOLFF) || (algo_type==AT_SWENDSEN_WANG)); bool monte_carlo = ((algo_type==AT_GIBBS) || (algo_type==AT_WOLFF) || (algo_type==AT_SWENDSEN_WANG) || (algo_type==AT_METROPOLIS)); // check number of output arguments if ((nlhs > 6) || ((nlhs > 2) && (algo_type != AT_GBP) && (algo_type != AT_LOOPY))) { mexErrMsgTxt("Too many output arguments."); } // get number of nodes and adjMat vector<Nodes>* adjMat = new vector<Nodes>(); fillAdjMat(prhs[0],*adjMat); int num_nodes = adjMat->size(); // define the MRF MRF* mrf = 0; if (potts_model) { mrf = new PottsMRF(*adjMat); } else { mrf = new MRF(*adjMat); } // get local potentials fillLocalMat(prhs[2],mrf); // get pairwise potentials if (potts_model) { fillLambdaMat(prhs[1],(PottsMRF*)mrf); } else { fillPsiMat(prhs[1],mrf); } // For monte-carlo algorithms (gibbs, wolff, swendsen-wang), get // the initial state and the sampling parameters if (monte_carlo) { if (nrhs != 10) { mexErrMsgTxt("incorrect number of inputs"); } startX = new int[num_nodes]; fillInitialAssignment(prhs[6], startX, num_nodes); // get burningTime, samplingInterval, num_samples burningTime = (int)(mxGetScalar(prhs[7])); samplingInterval = (int)(mxGetScalar(prhs[8])); num_samples = (int)(mxGetScalar(prhs[9])); } else { // for all non-monte-carlo-algorithms (Mean-Field, BP & GBP) maxIter = (int)(mxGetScalar(prhs[6])); threshold = mxGetScalar(prhs[7]); // get log-space flag logspace = ((int)(mxGetScalar(prhs[8]))) > 0; mrf->logspace = logspace; logBels = ((int)(mxGetScalar(prhs[9]))) > 0; if (algo_type == AT_LOOPY) { // for loopy belief propagation: // get sum-or-max-flag and strategy if (nrhs != 17) { mexErrMsgTxt("incorrect number of inputs"); } sumOrMax = (SumOrMax)((int)(mxGetScalar(prhs[10]))); strategy = (Strategy)((int)(mxGetScalar(prhs[11]))); trw = ((int)(mxGetScalar(prhs[12]))) > 0; if (trw) { rho = new double*[num_nodes]; for (int i=0; i<num_nodes; i++) { rho[i] = new double[mrf->neighbNum(i)]; } fillRhoMat(prhs[13],mrf,rho); } // get save-time flag saveTime = ((int)(mxGetScalar(prhs[15]))) > 0; // get initial messages, if given int initM_nd = mxGetNumberOfDimensions(prhs[14]); const int* initM_dim = mxGetDimensions(prhs[14]); if ((initM_nd == 2) && (initM_dim[0] == 1) && (initM_dim[1] == num_nodes) && mxIsCell(prhs[14])) { initMsg = new double**[num_nodes]; for (int i=0; i<num_nodes; i++) { mxArray* initMsg_i = mxGetCell(prhs[14],i); int Ni = mrf->neighbNum(i); int len = (saveTime ? num_nodes : Ni); initMsg[i] = new double*[len]; if (saveTime) { for (int j=0; j<num_nodes; j++) { initMsg[i][j] = 0; } } for (int n=0; n<Ni; n++) { int j = mrf->adjMat[i][n]; int nei = (saveTime ? j : n); initMsg[i][nei] = new double[mrf->V[j]]; mxArray* initMsg_ij = mxGetCell(initMsg_i,nei); fillDouble(initMsg_ij,initMsg[i][nei],mrf->V[j]); } } } int count_nd = mxGetNumberOfDimensions(prhs[16]); const int* count_dim = mxGetDimensions(prhs[16]); if ((count_nd==2) && (count_dim[0]*count_dim[1]==num_nodes)) { countingNode = new double[num_nodes]; fillDouble(prhs[16], countingNode, num_nodes); // incorporate local potentials into pairwise for (int i=0; i<num_nodes; i++) { if (mrf->neighbNum(i)>0) { int j = mrf->adjMat[i][0]; if (i<j) { for (int xi=0; xi<mrf->V[i]; xi++) { for (int xj=0; xj<mrf->V[j]; xj++) { mrf->lambdaMat[i][0][xi][xj] *= mrf->localMat[i][xi]; } mrf->localMat[i][xi] = 1.0; } } else { int n = 0; while (mrf->adjMat[j][n] != i) { n++; } for (int xi=0; xi<mrf->V[i]; xi++) { for (int xj=0; xj<mrf->V[j]; xj++) { mrf->lambdaMat[j][n][xj][xi] *= mrf->localMat[i][xi]; } mrf->localMat[i][xi] = 1.0; } } } else { mexPrintf("warning: the graph is not connected\n"); } } } } if (algo_type == AT_GBP) { // for generalized belief propagation: // get regions, regions-adj (if given), sum-or-max-flag // and alpha if (nrhs != 20) { mexErrMsgTxt("incorrect number of inputs"); } allLevels = (int)(mxGetScalar(prhs[11])) > 0; if (allLevels) { allRegions = new vector<RegionLevel>(); allRegions->clear(); fillRegionLevels(prhs[10],*allRegions); } else { regions = new RegionLevel(); fillRegions(prhs[10],*regions); } sumOrMax = (SumOrMax)((int)(mxGetScalar(prhs[12]))); gbp_alpha = mxGetScalar(prhs[13]); trw = ((int)(mxGetScalar(prhs[14]))) > 0; if (trw) { countingNode = new double[num_nodes]; fillDouble(prhs[15], countingNode, num_nodes); } full = ((int)(mxGetScalar(prhs[16]))) > 0; // get initial messages, if given int initM_nd = mxGetNumberOfDimensions(prhs[17]); const int* initM_dim = mxGetDimensions(prhs[17]); if ((initM_nd == 2) && mxIsCell(prhs[17])) { num_regs = initM_dim[0] * initM_dim[1]; initMsg = new double**[num_regs]; for (int i=0; i<num_regs; i++) { mxArray* initMsg_i = mxGetCell(prhs[17],i); int msg_i_nd = mxGetNumberOfDimensions(initMsg_i); const int* msg_i_dim = mxGetDimensions(initMsg_i); if ((msg_i_nd != 2) || !mxIsCell(initMsg_i)) { mexErrMsgTxt("each cell {i} in initMsg for GBP should be a cell array in length of number of neighbour-regions to region i\n"); } int Ni = msg_i_dim[0] * msg_i_dim[1]; initMsg[i] = new double*[Ni]; for (int n=0; n<Ni; n++) { mxArray* initMsg_ij = mxGetCell(initMsg_i,n); const int* msg_ij_dim = mxGetDimensions(initMsg_ij); int numStates = msg_ij_dim[0] * msg_ij_dim[1]; initMsg[i][n] = new double[numStates]; fillDouble(initMsg_ij,initMsg[i][n],numStates); } } } // get potentials for the big regions, if given int regPot_nd = mxGetNumberOfDimensions(prhs[18]); const int* regPot_dim = mxGetDimensions(prhs[18]); if ((regPot_nd == 2) && mxIsCell(prhs[18])) { num_regs = regPot_dim[0] * regPot_dim[1]; bigRegsPot = new Potentials[num_regs]; for (int i=0; i<num_regs; i++) { mxArray* regPot_i = mxGetCell(prhs[18],i); int regPot_i_nd = mxGetNumberOfDimensions(regPot_i); const int* regPot_i_dim = mxGetDimensions(regPot_i); if (regPot_i_nd != 2) { mexErrMsgTxt("each cell {i} in big-regions' potentials for GBP should be a vector in length of number of possible states for the region i\n"); } int Vi = regPot_i_dim[0] * regPot_i_dim[1]; bigRegsPot[i] = new Potential[Vi]; fillDouble(regPot_i,bigRegsPot[i],Vi); } } // if true - get the region beliefs (instead of the single beliefs) regBeliefs = ((int)(mxGetScalar(prhs[19]))) > 0; } } // get tepmerature double temperature = mxGetScalar(prhs[4]); mrf->setTemperature(temperature); // ************************************************************************** // create the algorithm // ************************************************************************** InferenceAlgorithm* algorithm = 0; switch (algo_type) { case AT_LOOPY: if (saveTime) { if (logspace) { algorithm = new LogLoopySTime(mrf,sumOrMax,strategy,maxIter,rho,initMsg,logBels,threshold); } else { algorithm = new LoopySTime(mrf,sumOrMax,strategy,maxIter,rho,initMsg,threshold); } } else { if (logspace) { if (countingNode != 0) { algorithm = new LogPairsGBP(mrf,sumOrMax,strategy,maxIter,countingNode,initMsg,logBels,threshold); } else { algorithm = new LogLoopy(mrf,sumOrMax,strategy,maxIter,rho,initMsg,logBels,threshold); } } else { if (countingNode != 0) { algorithm = new PairsGBP(mrf,sumOrMax,strategy,maxIter,countingNode,initMsg,threshold); } else { algorithm = new Loopy(mrf,sumOrMax,strategy,maxIter,rho,initMsg,threshold); } } } break; case AT_GBP: if (allLevels) { processor = new GBPPreProcessor(allRegions, mrf, trw, full, countingNode, bigRegsPot); } else { processor = new GBPPreProcessor(*regions, mrf, trw, full, countingNode, bigRegsPot); regions->clear(); delete regions; regions = 0; } reg_mrf = processor->getRegionMRF(); assignInd = processor->getAssignTable(); bethe = processor->getBethe(); if (logspace) { algorithm = new LogGBP(reg_mrf,assignInd,bethe,sumOrMax,gbp_alpha,maxIter,initMsg,logBels,threshold); } else { algorithm = new GBP(reg_mrf,assignInd,bethe,sumOrMax,gbp_alpha,maxIter,initMsg,threshold); } break; case AT_GIBBS: algorithm = new Gibbs(mrf,startX,burningTime,samplingInterval,num_samples); delete[] startX; startX = 0; break; case AT_WOLFF: algorithm = new Wolff((PottsMRF*)mrf,startX,burningTime,samplingInterval,num_samples); delete[] startX; startX = 0; break; case AT_SWENDSEN_WANG: algorithm = new SwendsenWang((PottsMRF*)mrf,startX,burningTime,samplingInterval,num_samples); delete[] startX; startX = 0; break; case AT_METROPOLIS: algorithm = new Metropolis(mrf,startX,burningTime,samplingInterval,num_samples); delete[] startX; startX = 0; break; case AT_MEAN_FIELD: if (logspace) { algorithm = new LogMeanField(mrf,maxIter,logBels,threshold); } else { algorithm = new MeanField(mrf,maxIter,threshold); } break; default: mexErrMsgTxt("invalid algorithm type. possible values are: 0-loopy, 1-gbp, 2-gibbs, 3-wolff, 4-swendswen-wang, 5-metropolis, 6-mean-field"); break; } // ************************************************************************** // make inference // ************************************************************************** int converged; double** beliefs = algorithm->inference(&converged); double** singleBeliefs = 0; double**** pairBeliefs = 0; switch (algo_type) { case AT_LOOPY: if (nlhs > 2) { if (countingNode != 0) { pairBeliefs = ((PairsGBP*)algorithm)->calcPairBeliefs(); } else { pairBeliefs = ((Loopy*)algorithm)->calcPairBeliefs(); } } break; case AT_GBP: bool marg; if (sumOrMax==SUM) { marg = ((GBP*)algorithm)->isSumMarg(.0001); } else { marg = ((GBP*)algorithm)->isMaxMarg(.0001); } if (!marg) { converged = -2; mexWarnMsgTxt("resulted beliefs are not marginalizable\n"); } if (!regBeliefs || nlhs > 4) { singleBeliefs = new double*[num_nodes]; for (int i=0; i<num_nodes; i++) { singleBeliefs[i] = new double[mrf->V[i]]; } processor->extractSingle(beliefs,singleBeliefs,sumOrMax); if ((!regBeliefs && nlhs > 2) || (regBeliefs && nlhs > 5)) { pairBeliefs = new double***[num_nodes]; for (int i=0; i<num_nodes; i++) { pairBeliefs[i] = new double**[mrf->neighbNum(i)]; for (int n=0; n<mrf->neighbNum(i); n++) { pairBeliefs[i][n] = 0; int j = mrf->adjMat[i][n]; if (i<j) { pairBeliefs[i][n] = new double*[mrf->V[i]]; for (int xi=0; xi<mrf->V[i]; xi++) { pairBeliefs[i][n][xi] = new double[mrf->V[j]]; } } } } processor->extractPairs(beliefs,pairBeliefs,sumOrMax); } if (!regBeliefs) { beliefs = singleBeliefs; } } break; default: break; } // ************************************************************************** // assign results to output argument (if given) // ************************************************************************** if (regBeliefs) { int num_regs = reg_mrf->N; int regs_dims[2] = {1,num_regs}; Region** all_regions = processor->getAllRegions(); // assign: 1. regions 2. regions' adj-matrix 3. region beliefs 4. convergence flag plhs[0] = mxCreateCellArray(2,regs_dims); plhs[1] = mxCreateCellArray(2,regs_dims); plhs[2] = mxCreateCellArray(2,regs_dims); plhs[3] = mxCreateDoubleScalar(converged); for (int i=0; i<num_regs; i++) { // regions Region* region = all_regions[i]; int reg_i_size = (int)(region->size()); int reg_i_dims[2] = {1,reg_i_size}; mxArray* reg_i = mxCreateNumericArray(2,reg_i_dims,mxDOUBLE_CLASS, mxREAL); double* reg_i_ptr = mxGetPr(reg_i); for (int n=0; n<reg_i_size; n++) { reg_i_ptr[n] = (double)((*region)[n] + 1); } mxSetCell(plhs[0],i,reg_i); // adj-matrix int adj_dims[2] = {1,reg_mrf->neighbNum(i)}; mxArray* adj_i = mxCreateNumericArray(2,adj_dims,mxDOUBLE_CLASS, mxREAL); double* adj_i_ptr = mxGetPr(adj_i); for (int n=0; n<reg_mrf->neighbNum(i); n++) { adj_i_ptr[n] = (double)(reg_mrf->adjMat[i][n] + 1); } mxSetCell(plhs[1],i,adj_i); // region beliefs int val_dims[2] = {reg_mrf->V[i],1}; mxArray* bel_i = mxCreateNumericArray(2,val_dims,mxDOUBLE_CLASS, mxREAL); double* resBelPtr = mxGetPr(bel_i); for (int xi=0; xi<reg_mrf->V[i]; xi++) { resBelPtr[xi] = beliefs[i][xi]; } mxSetCell(plhs[2],i,bel_i); } if (nlhs > 4) { int bel_dims[2] = {1,num_nodes}; // assign: 5. single beliefs 6. pairwise beliefs (if required) plhs[4] = mxCreateCellArray(2,bel_dims); if (nlhs > 5) { plhs[5] = mxCreateCellArray(2,bel_dims); } for (int i=0; i<num_nodes; i++) { // single beliefs int val_dims[2] = {mrf->V[i],1}; mxArray* bel_i = mxCreateNumericArray(2,val_dims,mxDOUBLE_CLASS, mxREAL); double* resBelPtr = mxGetPr(bel_i); for (int xi=0; xi<mrf->V[i]; xi++) { resBelPtr[xi] = singleBeliefs[i][xi]; } mxSetCell(plhs[4],i,bel_i); // pairwise beliefs if (nlhs > 5) { int pair_i_dims[2] = {1, mrf->neighbNum(i)}; mxArray* pbel_i = mxCreateCellArray(2,pair_i_dims); for (int n=0; n<mrf->neighbNum(i); n++) { int j = mrf->adjMat[i][n]; if (i<j) { int pval_dims[2] = {mrf->V[i], mrf->V[j]}; mxArray* pbel_ij = mxCreateNumericArray(2,pval_dims,mxDOUBLE_CLASS,mxREAL); double* resPBelPtr = mxGetPr(pbel_ij); for (int xi=0; xi<mrf->V[i]; xi++) { for (int xj=0; xj<mrf->V[j]; xj++) { resPBelPtr[xi + xj*mrf->V[i]] = pairBeliefs[i][n][xi][xj]; } } mxSetCell(pbel_i, n, pbel_ij); } } mxSetCell(plhs[5], i, pbel_i); } } } } else { if (nlhs > 0) { int bel_dims[2] = {1,num_nodes}; plhs[0] = mxCreateCellArray(2,bel_dims); for (int i=0; i<num_nodes; i++) { int val_dims[2] = {mrf->V[i],1}; mxArray* bel_i = mxCreateNumericArray(2,val_dims,mxDOUBLE_CLASS, mxREAL); double* resBelPtr = mxGetPr(bel_i); for (int xi=0; xi<mrf->V[i]; xi++) { resBelPtr[xi] = beliefs[i][xi]; } mxSetCell(plhs[0],i,bel_i); } if (nlhs > 1) { plhs[1] = mxCreateDoubleScalar(converged); // For matlab6.5 //plhs[1] = mxCreateScalarDouble(converged); if (nlhs > 2) { int pair_dims[2] = {1,num_nodes}; plhs[2] = mxCreateCellArray(2,pair_dims); for (int i=0; i<num_nodes; i++) { int pair_i_dims[2] = {1, mrf->neighbNum(i)}; mxArray* bel_i = mxCreateCellArray(2,pair_i_dims); for (int n=0; n<mrf->neighbNum(i); n++) { int j = mrf->adjMat[i][n]; if (i<j) { int pval_dims[2] = {mrf->V[i], mrf->V[j]}; mxArray* bel_ij = mxCreateNumericArray(2,pval_dims,mxDOUBLE_CLASS,mxREAL); double* resBelPtr = mxGetPr(bel_ij); for (int xi=0; xi<mrf->V[i]; xi++) { for (int xj=0; xj<mrf->V[j]; xj++) { resBelPtr[xi + xj*mrf->V[i]] = pairBeliefs[i][n][xi][xj]; } } mxSetCell(bel_i, n, bel_ij); } } mxSetCell(plhs[2], i, bel_i); } if (nlhs > 3) { double*** msg = 0; int msg_dims[2]; switch (algo_type) { case AT_LOOPY: if (countingNode != 0) { msg = ((PairsGBP*)algorithm)->getMessages(); } else { msg = ((Loopy*)algorithm)->getMessages(); } msg_dims[0] = 1; msg_dims[1] = num_nodes; plhs[3] = mxCreateCellArray(2,msg_dims); for (int i=0; i<num_nodes; i++) { int Ni = mrf->neighbNum(i); int msg_i_dims[2]; msg_i_dims[0] = 1; msg_i_dims[1] = (saveTime ? num_nodes : Ni); mxArray* msg_i = mxCreateCellArray(2,msg_i_dims); for (int n=0; n<Ni; n++) { int j = mrf->adjMat[i][n]; int nei = (saveTime ? j : n); int msg_ij_dims[2] = {1, mrf->V[j]}; mxArray* msg_ij = mxCreateNumericArray(2,msg_ij_dims,mxDOUBLE_CLASS, mxREAL); double* msg_ij_ptr = mxGetPr(msg_ij); for (int xj=0; xj<mrf->V[j]; xj++) { msg_ij_ptr[xj] = msg[i][nei][xj]; } mxSetCell(msg_i,nei,msg_ij); } mxSetCell(plhs[3],i,msg_i); } break; case AT_GBP: if (!trw) { msg = ((GBP*)algorithm)->getMessages(); msg_dims[0] = 1; msg_dims[1] = reg_mrf->N; plhs[3] = mxCreateCellArray(2,msg_dims); for (int i=0; i<reg_mrf->N; i++) { int Ni = reg_mrf->neighbNum(i); int msg_i_dims[2] = {1,Ni}; mxArray* msg_i = mxCreateCellArray(2,msg_i_dims); for (int n=0; n<Ni; n++) { int j = reg_mrf->adjMat[i][n]; int numStates = reg_mrf->V[max(i,j)]; int msg_ij_dims[2] = {1, numStates}; mxArray* msg_ij = mxCreateNumericArray(2,msg_ij_dims,mxDOUBLE_CLASS, mxREAL); double* msg_ij_ptr = mxGetPr(msg_ij); for (int xs=0; xs<numStates; xs++) { msg_ij_ptr[xs] = msg[i][n][xs]; } mxSetCell(msg_i,n,msg_ij); } mxSetCell(plhs[3],i,msg_i); } } break; default: break; } } } } } } // ************************************************************************** // free memory // ************************************************************************** delete algorithm; algorithm = 0; if (singleBeliefs != 0) { for (int i=0; i<num_nodes; i++) { delete[] singleBeliefs[i]; } delete[] singleBeliefs; singleBeliefs = 0; } if (pairBeliefs != 0 && algo_type == AT_GBP) { for (int i=0; i<num_nodes; i++) { for (int n=0; n<mrf->neighbNum(i); n++) { if (pairBeliefs[i][n] != 0) { for (int xi=0; xi<mrf->V[i]; xi++) { delete[] pairBeliefs[i][n][xi]; } delete[] pairBeliefs[i][n]; } } delete[] pairBeliefs[i]; } delete[] pairBeliefs; pairBeliefs = 0; } if (processor != 0) { delete processor; processor = 0; } if (rho != 0) { for (int i=0; i<num_nodes; i++) { delete[] rho[i]; rho[i] = 0; } delete[] rho; rho = 0; } if (countingNode != 0) { delete[] countingNode; countingNode = 0; } if (bigRegsPot != 0) { for (int i=0; i<num_regs; i++) { delete[] bigRegsPot[i]; } delete[] bigRegsPot; bigRegsPot = 0; } delete mrf; mrf = 0; delete adjMat; adjMat = 0; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) //L2L2OpticalFlow(u1,u2,tol,lambda,ux,uy,ut) { double *u1 = mxGetPr(prhs[0]); double *u2 = mxGetPr(prhs[1]); float tol = (float)mxGetScalar(prhs[2]); float lambda = (float)mxGetScalar(prhs[3]); int maxIterations = (int)mxGetScalar(prhs[4]); const mwSize *sizeImage = mxGetDimensions(prhs[0]); double *inputV = 0; double *inputY = 0; int typeNorm = 1; if (nrhs > 5) { typeNorm = (int)mxGetScalar(prhs[5]); } if (nrhs > 6) { inputV = mxGetPr(prhs[6]); } if (nrhs > 7) { inputY = mxGetPr(prhs[7]); } int nPx = (int)(sizeImage[0] * sizeImage[1]); const mwSize sizeY[2] = {4*nPx,1}; // Output v1 plhs[0] = mxCreateNumericArray(2, sizeImage, mxDOUBLE_CLASS, mxREAL); double *Outv1 = mxGetPr(plhs[0]); // Output v2 plhs[1] = mxCreateNumericArray(2, sizeImage, mxDOUBLE_CLASS, mxREAL); double *Outv2 = mxGetPr(plhs[1]); // Output Y plhs[2] = mxCreateNumericArray(2, sizeY, mxDOUBLE_CLASS, mxREAL); double *YOut = mxGetPr(plhs[2]); float* v1 = new float[nPx]; float* v2 = new float[nPx]; float* ux = new float[nPx]; float* uy = new float[nPx]; float* ut = new float[nPx]; float* uxut = new float[nPx]; float* uyut = new float[nPx]; float* c1 = new float[nPx]; float* c2 = new float[nPx]; float* c3 = new float[nPx]; float* teiler = new float[nPx]; float* y11 = new float[nPx]; float* y12 = new float[nPx]; float* y21 = new float[nPx]; float* y22 = new float[nPx]; float* Kty1 = new float[nPx]; float* Kty2 = new float[nPx]; float* Kx11 = new float[nPx]; float* Kx12 = new float[nPx]; float* Kx21 = new float[nPx]; float* Kx22 = new float[nPx]; float tau = 1.0f / sqrt(8.0f); float sigma = tau; float dTau = 1.0f / tau; float dSigma = 1.0f / sigma; //residuals float p = 0; float d = 0; float err = 1.0; float ssl = 1.0f - sigma / (sigma + lambda); int i, j; #pragma omp parallel for private(i,j) for (j = 0; j < sizeImage[1]; ++j) { for (i = 0; i < sizeImage[0]; ++i) { int tmpIndex = index2DtoLinear(sizeImage, i, j); //Index for gradients ut[tmpIndex] = (float)(u2[tmpIndex] - u1[tmpIndex]); if (i>0 && i < sizeImage[0] - 1) { uy[tmpIndex] = (float)(0.5f * (u1[index2DtoLinear(sizeImage, i + 1, j)] - u1[index2DtoLinear(sizeImage, i - 1, j)])); } else { uy[tmpIndex] = 0.0f; } if (j>0 && j < sizeImage[1] - 1) { ux[tmpIndex] = (float)(0.5f * (u1[index2DtoLinear(sizeImage, i, j + 1)] - u1[index2DtoLinear(sizeImage, i, j - 1)])); } else { ux[tmpIndex] = 0.0f; } uxut[tmpIndex] = ux[tmpIndex] * ut[tmpIndex]; uyut[tmpIndex] = uy[tmpIndex] * ut[tmpIndex]; c1[tmpIndex] = 1.0f + tau * ux[tmpIndex] * ux[tmpIndex]; c2[tmpIndex] = tau * ux[tmpIndex] * uy[tmpIndex]; c3[tmpIndex] = 1.0f + tau * uy[tmpIndex] * uy[tmpIndex]; teiler[tmpIndex] = 1.0f / (c1[tmpIndex] * c3[tmpIndex] - c2[tmpIndex] * c2[tmpIndex]); if (nrhs > 6) { v1[tmpIndex] = (float)inputV[tmpIndex]; v2[tmpIndex] = (float)inputV[nPx + tmpIndex]; } else { v1[tmpIndex] = 0.0f; v2[tmpIndex] = 0.0f; } Kty1[tmpIndex] = 0.0f; Kty2[tmpIndex] = 0.0f; if (nrhs > 7) { y11[tmpIndex] = (float)inputY[tmpIndex]; y12[tmpIndex] = (float)inputY[nPx + tmpIndex]; y21[tmpIndex] = (float)inputY[2 * nPx + tmpIndex]; y22[tmpIndex] = (float)inputY[3 * nPx + tmpIndex]; } else { y11[tmpIndex] = 0.0f; y12[tmpIndex] = 0.0f; y21[tmpIndex] = 0.0f; y22[tmpIndex] = 0.0f; } Kx11[tmpIndex] = 0.0f; Kx12[tmpIndex] = 0.0f; Kx21[tmpIndex] = 0.0f; Kx22[tmpIndex] = 0.0f; } } int iterations = 0; while (err > tol && iterations <= maxIterations) { ++iterations; if (iterations % 50 == 0) { p = 0.0f; d = 0.0f; } //primal step #pragma omp parallel for reduction(+:p) private(i,j) for (j = 0; j < sizeImage[1]; ++j) { for (i = 0; i < sizeImage[0]; ++i) { int tmpIndex = index2DtoLinear(sizeImage, i, j); float Kty1Old = Kty1[tmpIndex]; float Kty2Old = Kty2[tmpIndex]; //transpose equals -div Kty1[tmpIndex] = -(dxm(y11, sizeImage, i, j) + dym(y12, sizeImage, i, j)); Kty2[tmpIndex] = -(dxm(y21, sizeImage, i, j) + dym(y22, sizeImage, i, j)); float b1 = v1[tmpIndex] - tau*(Kty1[tmpIndex] + uxut[tmpIndex]); float b2 = v2[tmpIndex] - tau*(Kty2[tmpIndex] + uyut[tmpIndex]); float v1Old = v1[tmpIndex]; float v2Old = v2[tmpIndex]; v1[tmpIndex] = (b1 * c3[tmpIndex] - c2[tmpIndex] * b2) * teiler[tmpIndex]; v2[tmpIndex] = (b2 * c1[tmpIndex] - c2[tmpIndex] * b1) * teiler[tmpIndex]; if (iterations % 50 == 0) { //residuals p += myAbs((v1Old - v1[tmpIndex]) * dTau - Kty1Old + Kty1[tmpIndex]) + myAbs((v2Old - v2[tmpIndex]) * dTau - Kty2Old + Kty2[tmpIndex]); } } } //dual step #pragma omp parallel for reduction(+:d) private(i,j) for (j = 0; j < sizeImage[1]; ++j) { for (i = 0; i < sizeImage[0]; ++i) { int tmpIndex = index2DtoLinear(sizeImage, i, j); float Kx11Old = Kx11[tmpIndex]; float Kx12Old = Kx12[tmpIndex]; float Kx21Old = Kx21[tmpIndex]; float Kx22Old = Kx22[tmpIndex]; Kx11[tmpIndex] = dxp(v1, sizeImage, i, j); Kx12[tmpIndex] = dyp(v1, sizeImage, i, j); Kx21[tmpIndex] = dxp(v2, sizeImage, i, j); Kx22[tmpIndex] = dyp(v2, sizeImage, i, j); float y11Old = y11[tmpIndex]; float y12Old = y12[tmpIndex]; float y21Old = y21[tmpIndex]; float y22Old = y22[tmpIndex]; y11[tmpIndex] = ssl * (y11[tmpIndex] + sigma*(2 * Kx11[tmpIndex] - Kx11Old)); y12[tmpIndex] = ssl * (y12[tmpIndex] + sigma*(2 * Kx12[tmpIndex] - Kx12Old)); y21[tmpIndex] = ssl * (y21[tmpIndex] + sigma*(2 * Kx21[tmpIndex] - Kx21Old)); y22[tmpIndex] = ssl * (y22[tmpIndex] + sigma*(2 * Kx22[tmpIndex] - Kx22Old)); if (iterations % 50 == 0) { d += myAbs((y11Old - y11[tmpIndex]) * dSigma - Kx11Old + Kx11[tmpIndex]) + myAbs((y12Old - y12[tmpIndex]) * dSigma - Kx12Old + Kx12[tmpIndex]) + myAbs((y21Old - y21[tmpIndex]) * dSigma - Kx21Old + Kx21[tmpIndex]) + myAbs((y22Old - y22[tmpIndex]) * dSigma - Kx22Old + Kx22[tmpIndex]); } } } if (iterations % 50 == 0) { err = (d*d + p*p) / nPx; } if (iterations % 1000 == 0) { mexPrintf("Iteration %d,Residual %e\n", iterations, err); mexEvalString("drawnow;"); } } //write output #pragma omp parallel for private(i,j) for (j = 0; j < sizeImage[1]; ++j) { for (i = 0; i < sizeImage[0]; ++i) { int tmpIndex = index2DtoLinear(sizeImage, i, j); YOut[tmpIndex] = (double)y11[tmpIndex]; YOut[tmpIndex + nPx] = (double)y12[tmpIndex]; YOut[tmpIndex + 2 * nPx] = (double)y21[tmpIndex]; YOut[tmpIndex + 3 * nPx] = (double)y22[tmpIndex]; Outv1[tmpIndex] = (double)v1[tmpIndex]; Outv2[tmpIndex] = (double)v2[tmpIndex]; } } delete[] v1; delete[] v2; delete[] ux; delete[] uy; delete[] ut; delete[] uxut; delete[] uyut; delete[] c1; delete[] c2; delete[] c3; delete[] teiler; delete[] y11; delete[] y12; delete[] y21; delete[] y22; delete[] Kty1; delete[] Kty2; delete[] Kx11; delete[] Kx12; delete[] Kx21; delete[] Kx22; }
/** * Creates a wrapper around a Matlab image (i.e., mxArray) to allow OpenVis3D to easily access it. * @param im a pointer to an Matlab mxArray object */ MatlabImageAdapter::MatlabImageAdapter(mxArray*im) : OvImageAdapter(), mMatlabImage(im), mImageDataPtr(0) { int tmpNumDims; const int *tmpDimSizes; mxClassID imageDataType; if(mMatlabImage != 0) { tmpNumDims = mxGetNumberOfDimensions(mMatlabImage); tmpDimSizes = mxGetDimensions(mMatlabImage); mHeight = tmpDimSizes[0]; mWidth = tmpDimSizes[1]; if(tmpNumDims>2) mChannels = tmpDimSizes[2]; else mChannels = 1; imageDataType = mxGetClassID(mMatlabImage); mImageDataPtr = mxGetData(mMatlabImage); switch(imageDataType) { case mxUINT8_CLASS: mDataType = OV_DATA_UINT8; getPixelfptr = &MatlabImageAdapter::getPixelT<unsigned char>; setPixelfptr = &MatlabImageAdapter::setPixelT<unsigned char>; break; case mxUINT16_CLASS: mDataType = OV_DATA_UINT16; getPixelfptr = &MatlabImageAdapter::getPixelT<unsigned short>; setPixelfptr = &MatlabImageAdapter::setPixelT<unsigned short>; break; case mxUINT32_CLASS: mDataType = OV_DATA_UINT32; getPixelfptr = &MatlabImageAdapter::getPixelT<unsigned int>; setPixelfptr = &MatlabImageAdapter::setPixelT<unsigned int>; break; case mxUINT64_CLASS: mDataType = OV_DATA_UINT64; getPixelfptr = &MatlabImageAdapter::getPixelT<unsigned long long>; setPixelfptr = &MatlabImageAdapter::setPixelT<unsigned long long>; break; case mxINT8_CLASS: mDataType = OV_DATA_INT8; getPixelfptr = &MatlabImageAdapter::getPixelT<char>; setPixelfptr = &MatlabImageAdapter::setPixelT<char>; break; case mxINT16_CLASS: mDataType = OV_DATA_INT16; getPixelfptr = &MatlabImageAdapter::getPixelT<short>; setPixelfptr = &MatlabImageAdapter::setPixelT<short>; break; case mxINT32_CLASS: mDataType = OV_DATA_INT32; getPixelfptr = &MatlabImageAdapter::getPixelT<int>; setPixelfptr = &MatlabImageAdapter::setPixelT<int>; break; case mxINT64_CLASS: mDataType = OV_DATA_INT64; getPixelfptr = &MatlabImageAdapter::getPixelT<long long>; setPixelfptr = &MatlabImageAdapter::setPixelT<long long>; break; case mxSINGLE_CLASS: mDataType = OV_DATA_FLOAT32; getPixelfptr = &MatlabImageAdapter::getPixelT<float>; setPixelfptr = &MatlabImageAdapter::setPixelT<float>; break; case mxDOUBLE_CLASS : mDataType = OV_DATA_DOUBLE64; getPixelfptr = &MatlabImageAdapter::getPixelT<double>; setPixelfptr = &MatlabImageAdapter::setPixelT<double>; break; default: mDataType = OV_DATA_UNKNOWN; getPixelfptr = &MatlabImageAdapter::getPixeldoNothing; setPixelfptr = &MatlabImageAdapter::setPixeldoNothing; break; } } else { mDataType = OV_DATA_UNKNOWN; mHeight = 0; mWidth = 0; mChannels = 0; getPixelfptr = &MatlabImageAdapter::getPixeldoNothing; setPixelfptr = &MatlabImageAdapter::setPixeldoNothing; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { char usageStr[] = "Usage: idxImg = SLIC_mex(image(3-Channel uint8 image), spNum(double scalar), compactness(double scalar))\n"; //Check input const mxArray *pmxImg = prhs[0]; if (nrhs != 3 || !mxIsUint8(pmxImg) || !mxIsDouble(prhs[1]) || !mxIsDouble(prhs[2])) mexErrMsgTxt(usageStr); mwSize chn = mxGetNumberOfDimensions(pmxImg); if (3 != chn) mexErrMsgTxt(usageStr); const mwSize *sz = mxGetDimensions(pmxImg); mwSize height = sz[0], width = sz[1], num_pix = height * width; unsigned int iPatchNum = unsigned int( mxGetScalar(prhs[1]) ); float compactness = float( mxGetScalar(prhs[2]) ); //Transfer matlab matrix ImageSimpleUChar img_r, img_g, img_b; img_r.Create(width, height); img_g.Create(width, height); img_b.Create(width, height); unsigned char *pImgData = (unsigned char*)mxGetData(pmxImg); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { img_r.Pixel(x,y) = pImgData[y]; img_g.Pixel(x,y) = pImgData[y + num_pix]; img_b.Pixel(x,y) = pImgData[y + num_pix * 2]; } pImgData += height; } //Rgb --> Lab ImageSimpleFloat img_L, img_A, img_B; Rgb2Lab(img_r, img_g, img_b, img_L, img_A, img_B); //Do SLIC ImageSimpleUInt idxImg; idxImg.Create(width, height); int iSuperPixelNum = Run_SLIC_GivenPatchNum(img_L, img_A, img_B, iPatchNum, compactness, idxImg); //Transfer back to matlab plhs[0] = mxCreateDoubleMatrix(height, width, mxREAL); double *pdIdxImg = mxGetPr(plhs[0]); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { unsigned int id = idxImg.Pixel(x, y); pdIdxImg[y] = double(id) + 1; } pdIdxImg += height; } plhs[1] = mxCreateDoubleMatrix(1, 1, mxREAL); *mxGetPr(plhs[1]) = double(iSuperPixelNum); return; }
static void Segment(const mxArray *mx_in, const mxArray *mx_interface, const mxArray *mx_mask, T l1, T l2, T c1, T c2, T conv, Gc::Size max_iter, const char *str_nb, bool log, mxArray *plhs[]) { // Turn on logging Gc::Examples::Matlab::LogTarget mlt; Gc::System::Log::SetTarget(&mlt); Gc::System::Time::StopWatch::EnableOutput(log); // Get image from matlab Gc::Data::Image<N,T,T> img; Gc::Examples::Matlab::GetImage<N,T,T>(mx_in, img); // Set image resolution - unknown img.SetSpacing(Gc::Math::Algebra::Vector<N,T>(1)); // Get initial interface from matlab Gc::System::Collection::Array<N,LAB> iface; Gc::Examples::Matlab::GetImage<N,LAB,LAB>(mx_interface, iface); if (iface.Dimensions() != img.Dimensions()) { mexErrMsgTxt("Initial interface and image must have the same dimensions."); } // Get mask from matlab Gc::System::Collection::Array<N,Gc::Uint8> mask; if (mx_mask != NULL) { Gc::Examples::Matlab::GetImage<N,Gc::Uint8,Gc::Uint8>(mx_mask, mask); if (mask.Dimensions() != img.Dimensions()) { mexErrMsgTxt("Mask and image must have the same dimensions."); } } // Create neighbourhood object Gc::Energy::Neighbourhood<N,Gc::Int32> nb((Gc::Size)atoi(str_nb + 1), false); // Segment Gc::System::Collection::Array<N,bool> seg; Gc::System::Collection::Array<N,LAB> labels; T energy; // Topology preserving max-flow if (mx_mask == NULL) { Gc::Flow::Grid::DanekLabels<N,T,T,T,LAB,false> mf; mf.SetInitialLabelingRef(iface); energy = Gc::Algo::Segmentation::ChanVese::Compute(img, l1, l2, c1, c2, conv, max_iter, nb, mf, seg); // Get final labels seg.Dispose(); labels.Resize(img.Dimensions()); for (Gc::Size i = 0; i < labels.Elements(); i++) { labels[i] = mf.NodeLabel(i); } } else { Gc::Flow::Grid::DanekLabels<N,T,T,T,LAB,true> mf; mf.SetInitialLabelingRef(iface); energy = Gc::Algo::Segmentation::ChanVese::ComputeMasked(img, mask, l1, l2, c1, c2, conv, max_iter, nb, mf, seg); // Get final labels seg.Dispose(); labels.Resize(img.Dimensions()); Gc::Size j = 0; for (Gc::Size i = 0; i < labels.Elements(); i++) { if (mask[i] == Gc::Algo::Segmentation::MaskUnknown) { labels[i] = mf.NodeLabel(j); j++; } else { labels[i] = iface[i]; } } } // Save result to matlab plhs[0] = mxCreateNumericArray(N, mxGetDimensions(mx_in), mxUINT8_CLASS, mxREAL); Gc::Examples::Matlab::SetImage<N,LAB,LAB>(labels, plhs[0]); plhs[1] = mxCreateDoubleScalar((double)energy); plhs[2] = mxCreateDoubleScalar((double)max_iter); plhs[3] = mxCreateDoubleScalar((double)c1); plhs[4] = mxCreateDoubleScalar((double)c2); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { /* Check for proper number of arguments. */ if (nrhs != 3) { mexErrMsgTxt("Three inputs required."); } //the first argument is the array of vectors used to build the tree /* int nelements=mxGetNumberOfFields(prhs[0]); if(nelements!=1) { mexErrMsgTxt("Input should have one element."); } */ //the second argument is the struct returned by covertree int nfields = mxGetNumberOfFields(prhs[1]); if(nfields!=8) { mexErrMsgTxt("Second input should have 8 fields."); } //the third argument is the struct whose first member is the array of //vectors being studied; //whose second member is the distance; //whose third member is the depth nfields = mxGetNumberOfFields(prhs[2]); if(nfields!=3) { mexErrMsgTxt("Third input should have three fields."); } const mxArray* tmp=0; //Check for proper number of return arguments; [D] or [D E] or [D E F] //Return argument one is a cell array D //D{i}=indices of A.vectors within distance of A.vectors(:,i) at right level //E{i} is corresponding distances //F is diagnostics bool dist_flag=false; bool diag_flag=false; if(nlhs==3) { dist_flag=true; diag_flag=true; } else if (nlhs=3) { dist_flag=true; } else { if(nlhs!=1) { mexErrMsgTxt("One, two or three return arguments required\n"); } } //Extract appropriate members from first input; //this is what what was passed to covertree tmp=prhs[0]; mwSize ndims_in=mxGetNumberOfDimensions(tmp); const mwSize* dims_in=mxGetDimensions(tmp); int N=dims_in[ndims_in-1]; int n=1; for(int i=0;i<ndims_in-1;i++) { n*=dims_in[i]; } mexPrintf("n=%d N=%d\n",n,N); double* X=(double*)mxGetData(tmp); Vectors vectors(n,N,X); // Extract appropriate members from second input; //this is what was returned from covertree tmp=mxGetField(prhs[1],0,cover_in[0]); double* ptheta=(double*)mxGetData(tmp); double theta=*ptheta; tmp=mxGetField(prhs[1],0,cover_in[1]); int* params=(int*)mxGetData(tmp); tmp=mxGetField(prhs[1],0,cover_in[2]); int* lp=(int*)mxGetData(tmp); tmp=mxGetField(prhs[1],0,cover_in[3]); int* pchildren=(int*)mxGetData(tmp); DisjointLists children(N,pchildren,false); int* pdescend_list=(int*)mxMalloc(2*N*sizeof(int)); int* pdist_flags=(int*)mxMalloc(N*sizeof(int)); int* pindices_to_dist_flags=(int*)mxMalloc(N*sizeof(int)); double* pdistances=(double*)mxMalloc(N*sizeof(double)); int* pcurrent_child_flags=(int*)mxMalloc(N*sizeof(int)); int* pindices_to_current_child_flags=(int*)mxMalloc(N*sizeof(int)); int* pcurrent_children=(int*)mxMalloc(N*sizeof(int)); //Get third input //tmp=prhs[2]; tmp=mxGetField(prhs[2],0,within_in[0]); ndims_in=mxGetNumberOfDimensions(tmp); dims_in=mxGetDimensions(tmp); int N2=dims_in[ndims_in-1]; int n2=1; for(int i=0;i<ndims_in-1;i++) { n2*=dims_in[i]; } mexPrintf("N2=%d\n",N2); if(n2!=n) { mexPrintf("n2=%d must equal n=%d\n",n2,n); } double* Y=(double*)mxGetData(tmp); tmp=mxGetField(prhs[2],0,within_in[1]); double* pdwithin=(double*)mxGetData(tmp); double dwithin=*pdwithin; tmp=mxGetField(prhs[2],0,within_in[2]); int* pdepth=(int*)mxGetData(tmp); int depth=*pdepth; mexPrintf("point=%g dwithin=%g depth=%d\n",*Y,dwithin,depth); Cover cover(theta, params, &vectors, lp,children, pdescend_list, pdist_flags,pindices_to_dist_flags, pdistances, pcurrent_child_flags,pindices_to_current_child_flags, pcurrent_children); ndims=2; dims[0]=1; dims[1]=N2; mxArray* pointer0=mxCreateCellArray(ndims,dims); mxArray* pointer1=0; Cover::DescendList* pdescendlist=0; if(dist_flag) { pointer1= mxCreateCellArray(ndims,dims); pdescendlist=(Cover::DescendList*)&cover.getDescendList(); } for(int i=0;i<N2;i++) { //mexPrintf("loop i=%d\n",i); Vector v(n,Y+i*n); cover.findWithin(&v,dwithin,depth); int count=cover.getDescendList().getCount(); dims[1]=count; mxArray* fout=mxCreateNumericArray(ndims,dims,mxINT32_CLASS,mxREAL); int* arr=(int*)mxGetData(fout); cover.fillArrFromDescendList(arr); /* bool test=cover.checkFindWithin(&v,dwithin,depth); if(test) { mexPrintf("checkFindWithin passed\n"); } else { mexPrintf("checkFindWithin failed\n"); } */ mxSetCell(pointer0,i,fout); if(dist_flag) { fout=mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL); double* dist=(double*)mxGetData(fout); for(int i=0;i<count;i++) { dist[i]=pdescendlist->getDist(&v,arr[i]); } } mxSetCell(pointer1,i,fout); cover.clearDescendList(); } plhs[0]=pointer0; if(dist_flag) { plhs[1]=pointer1; } if(diag_flag) { double* p=0; plhs[2]= mxCreateStructMatrix(1, 1, 4, fnames_out_2); ndims=2; dims[0]=1; dims[1]=1; mxArray* fout=0; fout = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL); p=(double*)mxGetData(fout); mxSetField(plhs[2],0,fnames_out_2[0],fout); p[0]=cover.getDistNCallsToGet(); fout = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL); p=(double*)mxGetData(fout); mxSetField(plhs[2],0,fnames_out_2[1],fout); p[0]=cover.getDistNCallsToSet(); fout = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL); p=(double*)mxGetData(fout); mxSetField(plhs[2],0,fnames_out_2[2],fout); p[0]=cover.getChildrenNCallsToGet(); fout = mxCreateNumericArray(ndims,dims,mxDOUBLE_CLASS,mxREAL); p=(double*)mxGetData(fout); mxSetField(plhs[2],0,fnames_out_2[3],fout); p[0]=cover.getChildrenNCallsToSet(); } mxFree(pdescend_list); mxFree(pdist_flags); mxFree(pindices_to_dist_flags); mxFree(pdistances); mxFree(pcurrent_child_flags); mxFree(pindices_to_current_child_flags); mxFree(pcurrent_children); }
/* The matlab mex function */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* I1 and I2 are the input images */ /* hist12 joint histogram */ /* hist1 and histogram of I1 and hist2 of I2 */ double *I1, *I2, *Imin, *Imax, *nbins, *hist12, *hist1, *hist2; /* Size of input image */ const mwSize *idims; /* Size of output */ int odims2[2]={0,0}; int odims1[1]={0}; /* Dimensions */ int nsubs; int npixels=1; double npixelsi=1; /* intensity location*/ int sizex, sizexd; double xd, xm, xp, xmd, xpd; double yd, ym, yp, ymd, ypd; int xmi, xpi, ymi, ypi; /* loop vars*/ int i; /* vars*/ double minv; double scav; /* Check for proper number of arguments. */ if(nrhs!=5) { mexErrMsgTxt("five inputs are required."); } else if(nlhs!=3) { mexErrMsgTxt("Three outputs are required"); } /* Get the number of dimensions */ nsubs = mxGetNumberOfDimensions(prhs[0]); /* Get the sizes of the grid */ idims = mxGetDimensions(prhs[0]); for (i=0; i<nsubs; i++) { npixels=npixels*idims[i]; } npixelsi=1/((double)npixels); /* Assign pointers to each input. */ I1=(double *)mxGetData(prhs[0]); I2=(double *)mxGetData(prhs[1]); Imin=(double *)mxGetData(prhs[2]); Imax=(double *)mxGetData(prhs[3]); nbins=(double *)mxGetData(prhs[4]); /* Create image matrix for the return arguments*/ odims2[0]=(int) nbins[0]; odims2[1]=(int)nbins[0]; plhs[0] = mxCreateNumericArray(2, odims2, mxDOUBLE_CLASS, mxREAL); odims1[0]=(int) nbins[0]; plhs[1] = mxCreateNumericArray(1, odims1, mxDOUBLE_CLASS, mxREAL); plhs[2] = mxCreateNumericArray(1, odims1, mxDOUBLE_CLASS, mxREAL); /* Assign pointers to each output. */ hist12=(double *)mxGetData(plhs[0]); hist1=(double *)mxGetData(plhs[1]); hist2=(double *)mxGetData(plhs[2]); /* min value */ minv=Imin[0]; /* scale value */ scav=nbins[0]/(Imax[0]-Imin[0]); sizex=(int) nbins[0]; sizexd=sizex-1; for (i=0; i<npixels; i++) { xd=(double)scav*(I1[i]-minv); xm=(double)floor(xd); xp=xm+1; xmd=xp-xd; xpd=xd-xm; yd=(double)scav*(I2[i]-minv); ym=(double)floor(yd); yp=ym+1; ymd=yp-yd; ypd=yd-ym; xmi=(int)xm; xpi=(int)xp; ymi=(int)ym; ypi=(int)yp; /* Make sum of all values in histogram 1 and histrogram 2 equal to 1*/ xmd*=npixelsi; ymd*=npixelsi; xpd*=npixelsi; ypd*=npixelsi; if(xmi<0){ xmi=0; } else if(xmi>sizexd) { xmi=sizexd; } if(xpi<0){ xpi=0; } else if(xpi>sizexd) { xpi=sizexd; } if(ymi<0){ ymi=0; } else if(ymi>sizexd) { ymi=sizexd; } if(ypi<0){ ypi=0; } else if(ypi>sizexd) { ypi=sizexd; } hist12[xmi+ymi*sizex]+=xmd*ymd; hist12[xpi+ymi*sizex]+=xpd*ymd; hist12[xmi+ypi*sizex]+=xmd*ypd; hist12[xpi+ypi*sizex]+=xpd*ypd; hist1[xmi]=hist1[xmi]+xmd; hist1[xpi]=hist1[xpi]+xpd; hist2[ymi]=hist2[ymi]+ymd; hist2[ypi]=hist2[ypi]+ypd; } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //printf("1\n"); //declare variables mxArray *D, *PairW, *tU, *kIn, *alpha; const mwSize *dimsPairW, *dimsD; double *alphaPtr, *DPtr, *PairWPtr, *tUPtr, *kInPtr; int dimxPairW, dimyPairW, dimzPairW, dimxD, dimyD; int i,j; //associate inputs //printf("2\n"); D = mxDuplicateArray(prhs[0]); PairW = mxDuplicateArray(prhs[1]); //tU = mxDuplicateArray(prhs[2]); //kIn = mxDuplicateArray(prhs[3]); //figure out dimensions //printf("3\n"); dimsPairW = mxGetDimensions(prhs[1]); dimyPairW = (int)dimsPairW[0]; dimxPairW = (int)dimsPairW[1]; dimzPairW = (int)dimsPairW[2]; dimsD = mxGetDimensions(prhs[0]); dimyD = (int)dimsD[0]; dimxD = (int)dimsD[1]; //printf("4\n"); //associate outputs alpha = plhs[0] = mxCreateDoubleMatrix(1,dimxPairW,mxREAL); //printf("5\n"); //associate pointers alphaPtr = mxGetPr(alpha); DPtr = mxGetPr(D); PairWPtr = mxGetPr(PairW); //tUPtr = mxGetPr(tU); //kInPtr = mxGetPr(kIn); //printf("6\n"); typedef Graph<double,double,double> GraphType; int numNodes=dimxPairW; GraphType *g = new GraphType(/*estimated # of nodes*/ numNodes, /*estimated # of edges*/ numNodes*6); g->add_node(numNodes); // loop through pixels /* for(i=0;i<dimxPairW;i++) { //mexPrintf("D[0][%d] = %f\n",i,DPtr[i*2]); //mexPrintf("D[1][%d] = %f\n",i,DPtr[i*2+1]); for(j=0;j<dimyPairW;j++) { int xy = j+i*dimyPairW; int matSize = dimxPairW*dimyPairW; //mexPrintf("V[%d][%d][0] = %f\n",j,i,PairWPtr[xy]); mexPrintf("V[%d][%d][1] = %f\n",j,i,PairWPtr[matSize + xy - 1]); } } */ for (i=0;i<dimxPairW;i++) { //if (i % 10000 == 0) //printf("7: %d/%d\n", i, dimxPairW); //if (((int)tUPtr[i])==1) { //printf("7: %d/%d\n", i, dimxPairW); g->add_tweights(i,DPtr[2*i+1],DPtr[2*i]); //} /*else { //printf("7: %d/%d\n", i, dimxPairW); g->add_tweights(i,0,kInPtr[0]); }*/ for (j=0;j<dimyPairW;j++) { int xy = j+i*dimyPairW; int matSize = dimxPairW*dimyPairW; // printf("8: %d/%d\n", j, dimyPairW); if ((int)PairWPtr[matSize + xy]-1<=0) { //printf("8-2\n"); continue; } else { // printf("8-3: i=%d, j=%d, dimyPairW=%d, dimxPairW=%d, dimzPairW=%d, dimxD=%d, dimyD=%d, matSize=%d, xy=%d ---- ", i, j, dimyPairW, dimxPairW, dimzPairW, dimxD, dimyD, matSize, xy); // printf("8-3-2: PairWPtr1=%d, PairWPtr2=%f\n", (int)PairWPtr[matSize + xy]-1, PairWPtr[xy]); g->add_edge(i,(int)PairWPtr[matSize + xy]-1,PairWPtr[xy],PairWPtr[xy]); } } } double flow = g->maxflow(); printf("Flow = %f\n", flow); //printf("9\n"); for (i=0;i<dimxPairW;i++) { //printf("10: %d/%d\n", i, dimxPairW); if (g->what_segment(i) == GraphType::SOURCE) alphaPtr[i]=1; else alphaPtr[i]=0; } delete g; return; }
static void get_map_dat(int i, const mxArray *ptr, MAPTYPE *maps) { mxArray *tmp; double *pr; int num_dims, j, t, dtype = 0; const int *dims; unsigned char *dptr; tmp=mxGetField(ptr,i,"dat"); if (tmp == (mxArray *)0) { free_maps(maps,i); mexErrMsgTxt("Cant find dat."); } if (mxIsDouble(tmp)) dtype = SPM_DOUBLE; else if (mxIsSingle(tmp)) dtype = SPM_FLOAT; else if (mxIsInt32 (tmp)) dtype = SPM_SIGNED_INT; else if (mxIsUint32(tmp)) dtype = SPM_UNSIGNED_INT; else if (mxIsInt16 (tmp)) dtype = SPM_SIGNED_SHORT; else if (mxIsUint16(tmp)) dtype = SPM_UNSIGNED_SHORT; else if (mxIsInt8 (tmp)) dtype = SPM_SIGNED_CHAR; else if (mxIsUint8 (tmp)) dtype = SPM_UNSIGNED_CHAR; else { free_maps(maps,i); mexErrMsgTxt("Unknown volume datatype."); } dptr = (unsigned char *)mxGetPr(tmp); num_dims = mxGetNumberOfDimensions(tmp); if (num_dims > 3) { free_maps(maps,i); mexErrMsgTxt("Too many dimensions."); } dims = mxGetDimensions(tmp); for(j=0; j<num_dims; j++) maps[i].dim[j]=dims[j]; for(j=num_dims; j<3; j++) maps[i].dim[j]=1; tmp=mxGetField(ptr,i,"dim"); if (tmp != (mxArray *)0) { if (mxGetM(tmp)*mxGetN(tmp) != 3) { free_maps(maps,i); mexErrMsgTxt("Wrong sized dim."); } pr = mxGetPr(tmp); if (maps[i].dim[0] != (int)fabs(pr[0]) || maps[i].dim[1] != (int)fabs(pr[1]) || maps[i].dim[2] != (int)fabs(pr[2])) { free_maps(maps,i); mexErrMsgTxt("Incompatible volume dimensions in dim."); } } tmp=mxGetField(ptr,i,"dt"); if (tmp != (mxArray *)0) { if (mxGetM(tmp)*mxGetN(tmp) != 1 && mxGetM(tmp)*mxGetN(tmp) != 2) { free_maps(maps,i); mexErrMsgTxt("Wrong sized dt."); } pr = mxGetPr(tmp); if (dtype != (int)fabs(pr[0])) { free_maps(maps,i); mexErrMsgTxt("Incompatible datatype in dt."); } } maps[i].addr = 0; maps[i].len = 0; maps[i].dtype = dtype; maps[i].data = (void **)mxCalloc(maps[i].dim[2],sizeof(void *)); maps[i].scale = (double *)mxCalloc(maps[i].dim[2],sizeof(double)); maps[i].offset = (double *)mxCalloc(maps[i].dim[2],sizeof(double)); t = maps[i].dim[0]*maps[i].dim[1]*get_datasize(maps[i].dtype)/8; tmp = mxGetField(ptr,i,"pinfo"); if (tmp != (mxArray *)0) { if ((mxGetM(tmp) != 2 && mxGetM(tmp) != 3) || (mxGetN(tmp) != 1 && mxGetN(tmp) != maps[i].dim[2])) { free_maps(maps,i+1); mexErrMsgTxt("Wrong sized pinfo."); } if (mxGetM(tmp) == 3 && mxGetPr(tmp)[2] != 0) { free_maps(maps,i+1); mexErrMsgTxt("pinfo(3) must equal 0 to read dat field."); } pr = mxGetPr(tmp); if (mxGetN(tmp) == 1) for(j=0; j<maps[i].dim[2]; j++) { maps[i].scale[j] = pr[0]; maps[i].offset[j] = pr[1]; maps[i].data[j] = &(dptr[j*t]); } else for(j=0; j<maps[i].dim[2]; j++) { maps[i].scale[j] = pr[0+j*2]; maps[i].offset[j] = pr[1+j*2]; maps[i].data[j] = &(dptr[j*t]); } } else for(j=0; j<maps[i].dim[2]; j++) { maps[i].scale[j] = 1.0; maps[i].offset[j] = 0.0; maps[i].data[j] = &(dptr[j*t]); } tmp=mxGetField(ptr,i,"mat"); if (tmp != (mxArray *)0) { if (mxGetM(tmp) != 4 || mxGetN(tmp) != 4) { free_maps(maps,i+1); mexErrMsgTxt("Wrong sized mat."); } pr = mxGetPr(tmp); for(j=0; j<16; j++) maps[i].mat[j] = pr[j]; } else { for(j=0; j<16; j++) maps[i].mat[j] = 0.0; for(j=0; j<4; j++) maps[i].mat[j + j*4] = 1.0; } }
/* driver */ void mexFunction(int nout, mxArray *out[], int nin, const mxArray *in[]) { enum {IN_I=0, IN_ER} ; enum {OUT_MEMBERS} ; idx_t i ; int k, nel, ndims ; mwSize const * dims ; val_t const * I_pt ; int last = 0 ; int last_expanded = 0 ; val_t value = 0 ; double const * er_pt ; int* subs_pt ; /* N-dimensional subscript */ int* nsubs_pt ; /* diff-subscript to point to neigh. */ idx_t* strides_pt ; /* strides to move in image array */ val_t* visited_pt ; /* flag */ idx_t* members_pt ; /* region members */ bool invert = VL_FALSE ; /** ----------------------------------------------------------------- ** Check the arguments ** -------------------------------------------------------------- */ if (nin != 2) { mexErrMsgTxt("Two arguments required.") ; } else if (nout > 4) { mexErrMsgTxt("Too many output arguments."); } if(mxGetClassID(in[IN_I]) != mxUINT8_CLASS) { mexErrMsgTxt("I must be of class UINT8.") ; } if(!vlmxIsPlainScalar(in[IN_ER])) { mexErrMsgTxt("ER must be a DOUBLE scalar.") ; } /* get dimensions */ nel = mxGetNumberOfElements(in[IN_I]) ; ndims = mxGetNumberOfDimensions(in[IN_I]) ; dims = mxGetDimensions(in[IN_I]) ; I_pt = mxGetData(in[IN_I]) ; /* allocate stuff */ subs_pt = mxMalloc( sizeof(int) * ndims ) ; nsubs_pt = mxMalloc( sizeof(int) * ndims ) ; strides_pt = mxMalloc( sizeof(idx_t) * ndims ) ; visited_pt = mxMalloc( sizeof(val_t) * nel ) ; members_pt = mxMalloc( sizeof(idx_t) * nel ) ; er_pt = mxGetPr(in[IN_ER]) ; /* compute strides to move into the N-dimensional image array */ strides_pt [0] = 1 ; for(k = 1 ; k < ndims ; ++k) { strides_pt [k] = strides_pt [k-1] * dims [k-1] ; } /* load first pixel */ memset(visited_pt, 0, sizeof(val_t) * nel) ; { idx_t idx = (idx_t) *er_pt ; if (idx < 0) { idx = -idx; invert = VL_TRUE ; } if( idx < 1 || idx > nel ) { char buff[80] ; snprintf(buff,80,"ER=%d out of range [1,%d]",idx,nel) ; mexErrMsgTxt(buff) ; } members_pt [last++] = idx - 1 ; } value = I_pt[ members_pt[0] ] ; /* ----------------------------------------------------------------- * Fill region * -------------------------------------------------------------- */ while(last_expanded < last) { /* pop next node xi */ idx_t index = members_pt[last_expanded++] ; /* convert index into a subscript sub; also initialize nsubs to (-1,-1,...,-1) */ { idx_t temp = index ; for(k = ndims-1 ; k >=0 ; --k) { nsubs_pt [k] = -1 ; subs_pt [k] = temp / strides_pt [k] ; temp = temp % strides_pt [k] ; } } /* process neighbors of xi */ while(VL_TRUE) { int good = VL_TRUE ; idx_t nindex = 0 ; /* compute NSUBS+SUB, the correspoinding neighbor index NINDEX and check that the pixel is within image boundaries. */ for(k = 0 ; k < ndims && good ; ++k) { int temp = nsubs_pt [k] + subs_pt [k] ; good &= 0 <= temp && temp < (signed) dims[k] ; nindex += temp * strides_pt [k] ; } /* process neighbor 1 - the pixel is within image boundaries; 2 - the pixel is indeed different from the current node (this happens when nsub=(0,0,...,0)); 3 - the pixel has value not greather than val is a pixel older than xi 4 - the pixel has not been visited yet */ if(good && nindex != index && ((!invert && I_pt [nindex] <= value) || ( invert && I_pt [nindex] >= value)) && ! visited_pt [nindex] ) { /* mark as visited */ visited_pt [nindex] = 1 ; /* add to list */ members_pt [last++] = nindex ; } /* move to next neighbor */ k = 0 ; while(++ nsubs_pt [k] > 1) { nsubs_pt [k++] = -1 ; if(k == ndims) goto done_all_neighbors ; } } /* next neighbor */ done_all_neighbors : ; } /* goto pop next member */ /* * Save results */ { mwSize dims[2] ; int unsigned * pt ; dims[0] = last ; out[OUT_MEMBERS] = mxCreateNumericArray(1,dims,mxUINT32_CLASS,mxREAL); pt = mxGetData(out[OUT_MEMBERS]) ; for (i = 0 ; i < last ; ++i) { *pt++ = members_pt[i] + 1 ; } } /* free stuff */ mxFree( members_pt ) ; mxFree( visited_pt ) ; mxFree( strides_pt ) ; mxFree( nsubs_pt ) ; mxFree( subs_pt ) ; }
void mexFunction ( /* === Parameters ======================================================= */ int nlhs, /* number of left-hand sides */ mxArray *plhs [], /* left-hand side matrices */ int nrhs, /* number of right--hand sides */ const mxArray *prhs [] /* right-hand side matrices */ ) { Zmat A; ZAMGlevelmat *PRE; ZILUPACKparam *param; integer n; const char **fnames; const mwSize *dims; mxClassID *classIDflags; mxArray *tmp, *fout, *A_input , *b_input, *x0_input, *options_input, *PRE_input, *options_output, *x_output; char *pdata, *input_buf, *output_buf; mwSize mrows, ncols, buflen, ndim,nnz; int ifield, status, nfields, ierr,i,j,k,l,m; size_t sizebuf; double dbuf, *A_valuesR, *A_valuesI, *convert, *sr, *pr, *pi; doublecomplex *sol, *rhs; mwIndex *irs, *jcs, *A_ja, /* row indices of input matrix A */ *A_ia; /* column pointers of input matrix A */ if (nrhs != 5) mexErrMsgTxt("five input arguments required."); else if (nlhs !=2) mexErrMsgTxt("Too many output arguments."); else if (!mxIsStruct(prhs[2])) mexErrMsgTxt("Third input must be a structure."); else if (!mxIsNumeric(prhs[0])) mexErrMsgTxt("First input must be a matrix."); /* The first input must be a square matrix.*/ A_input = (mxArray *) prhs [0] ; /* get size of input matrix A */ mrows = mxGetM (A_input) ; ncols = mxGetN (A_input) ; nnz = mxGetNzmax(A_input); if (mrows!=ncols) { mexErrMsgTxt("First input must be a square matrix."); } if (!mxIsSparse (A_input)) { mexErrMsgTxt ("ILUPACK: input matrix must be in sparse format.") ; } /* copy input matrix to sparse row format */ A.nc=A.nr=mrows; A.ia=(integer *) MAlloc((size_t)(A.nc+1)*sizeof(integer),"ZGNLSYMilupacksolver"); A.ja=(integer *) MAlloc((size_t)nnz *sizeof(integer),"ZGNLSYMilupacksolver"); A. a=(doublecomplex *) MAlloc((size_t)nnz *sizeof(doublecomplex), "ZGNLSYMilupacksolver"); A_ja = (mwIndex *) mxGetIr (A_input) ; A_ia = (mwIndex *) mxGetJc (A_input) ; A_valuesR = (double *) mxGetPr(A_input); if (mxIsComplex(A_input)) A_valuesI = (double *) mxGetPi(A_input); /* -------------------------------------------------------------------- */ /* .. Convert matrix from 0-based C-notation to Fortran 1-based */ /* notation. */ /* -------------------------------------------------------------------- */ /* for (i = 0 ; i < ncols ; i++) for (j = A_ia[i] ; j < A_ia[i+1] ; j++) printf("i=%d j=%d A.real=%e\n", i+1, A_ja[j]+1, A_valuesR[j]); */ for (i=0; i<=A.nr; i++) A.ia[i]=0; /* remember that MATLAB uses storage by columns and NOT by rows! */ for (i=0; i<A.nr; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { k=A_ja[j]; A.ia[k+1]++; } } /* now we know how many entries are located in every row */ /* switch to pointer structure */ for (i=0; i<A.nr; i++) A.ia[i+1]+=A.ia[i]; if (mxIsComplex(A_input)) { for (i=0; i<ncols; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { /* row index l in C-notation */ l=A_ja[j]; /* where does row l currently start */ k=A.ia[l]; /* column index will be i in FORTRAN notation */ A.ja[k]=i+1; A.a [k].r =A_valuesR[j]; A.a [k++].i=A_valuesI[j]; A.ia[l]=k; } } } else { for (i=0; i<ncols; i++) { for (j=A_ia[i]; j<A_ia[i+1]; j++) { /* row index l in C-notation */ l=A_ja[j]; /* where does row l currently start */ k=A.ia[l]; /* column index will be i in FORTRAN notation */ A.ja[k]=i+1; A.a [k].r =A_valuesR[j]; A.a [k++].i=0; A.ia[l]=k; } } } /* switch to FORTRAN style */ for (i=A.nr; i>0; i--) A.ia[i]=A.ia[i-1]+1; A.ia[0]=1; /* for (i = 0 ; i < A.nr ; i++) for (j = A.ia[i]-1 ; j < A.ia[i+1]-1 ; j++) printf("i=%d j=%d A.real=%e A.imag=%e\n", i+1, A.ja[j], A.a[j].r, A.a[j].i); */ /* import pointer to the preconditioner */ PRE_input = (mxArray*) prhs [1] ; /* get number of levels of input preconditioner structure `PREC' */ /* nlev=mxGetN(PRE_input); */ nfields = mxGetNumberOfFields(PRE_input); /* allocate memory for storing pointers */ fnames = mxCalloc((size_t)nfields, (size_t)sizeof(*fnames)); for (ifield = 0; ifield < nfields; ifield++) { fnames[ifield] = mxGetFieldNameByNumber(PRE_input,ifield); /* check whether `PREC.ptr' exists */ if (!strcmp("ptr",fnames[ifield])) { /* field `ptr' */ tmp = mxGetFieldByNumber(PRE_input,0,ifield); pdata = mxGetData(tmp); memcpy(&PRE, pdata, (size_t)sizeof(size_t)); } else if (!strcmp("param",fnames[ifield])) { /* field `param' */ tmp = mxGetFieldByNumber(PRE_input,0,ifield); pdata = mxGetData(tmp); memcpy(¶m, pdata, (size_t)sizeof(size_t)); } } mxFree(fnames); /* rescale input matrix */ /* obsolete for (i=0; i <A.nr; i++) { for (j=A.ia[i]-1; j<A.ia[i+1]-1; j++) { A.a[j].r*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r; A.a[j].i*=PRE->rowscal[i].r*PRE->colscal[A.ja[j]-1].r; } } */ /* Get third input argument `options' */ options_input=(mxArray*)prhs[2]; nfields = mxGetNumberOfFields(options_input); /* Allocate memory for storing classIDflags */ classIDflags = (mxClassID *) mxCalloc((size_t)nfields+1, (size_t)sizeof(mxClassID)); /* allocate memory for storing pointers */ fnames = mxCalloc((size_t)nfields+1, (size_t)sizeof(*fnames)); /* Get field name pointers */ j=-1; for (ifield = 0; ifield < nfields; ifield++) { fnames[ifield] = mxGetFieldNameByNumber(options_input,ifield); /* check whether `options.niter' already exists */ if (!strcmp("niter",fnames[ifield])) j=ifield; } if (j==-1) fnames[nfields]="niter"; /* mexPrintf("search for niter completed\n"); fflush(stdout); */ /* import data */ for (ifield = 0; ifield < nfields; ifield++) { /* mexPrintf("%2d\n",ifield+1); fflush(stdout); */ tmp = mxGetFieldByNumber(options_input,0,ifield); classIDflags[ifield] = mxGetClassID(tmp); ndim = mxGetNumberOfDimensions(tmp); dims = mxGetDimensions(tmp); /* Create string/numeric array */ if (classIDflags[ifield] == mxCHAR_CLASS) { /* Get the length of the input string. */ buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1; /* Allocate memory for input and output strings. */ input_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); /* Copy the string data from tmp into a C string input_buf. */ status = mxGetString(tmp, input_buf, buflen); if (!strcmp("amg",fnames[ifield])) { if (strcmp(param->amg,input_buf)) { param->amg=(char *)MAlloc((size_t)buflen*sizeof(char),"ilupacksolver"); strcpy(param->amg,input_buf); } } else if (!strcmp("presmoother",fnames[ifield])) { if (strcmp(param->presmoother,input_buf)) { param->presmoother=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->presmoother,input_buf); } } else if (!strcmp("postsmoother",fnames[ifield])) { if (strcmp(param->postsmoother,input_buf)) { param->postsmoother=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->postsmoother,input_buf); } } else if (!strcmp("typecoarse",fnames[ifield])) { if (strcmp(param->typecoarse,input_buf)) { param->typecoarse=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->typecoarse,input_buf); } } else if (!strcmp("typetv",fnames[ifield])) { if (strcmp(param->typetv,input_buf)) { param->typetv=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->typetv,input_buf); } } else if (!strcmp("FCpart",fnames[ifield])) { if (strcmp(param->FCpart,input_buf)) { param->FCpart=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->FCpart,input_buf); } } else if (!strcmp("solver",fnames[ifield])) { if (strcmp(param->solver,input_buf)) { param->solver=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->solver,input_buf); } } else if (!strcmp("ordering",fnames[ifield])) { if (strcmp(param->ordering,input_buf)) { param->ordering=(char *)MAlloc((size_t)buflen*sizeof(char), "ilupacksolver"); strcpy(param->ordering,input_buf); } } else { /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */ } } else { if (!strcmp("elbow",fnames[ifield])) { param->elbow=*mxGetPr(tmp); } else if (!strcmp("lfilS",fnames[ifield])) { param->lfilS=*mxGetPr(tmp); } else if (!strcmp("lfil",fnames[ifield])) { param->lfil=*mxGetPr(tmp); } else if (!strcmp("maxit",fnames[ifield])) { param->maxit=*mxGetPr(tmp); } else if (!strcmp("droptolS",fnames[ifield])) { param->droptolS=*mxGetPr(tmp); } else if (!strcmp("droptol",fnames[ifield])) { param->droptol=*mxGetPr(tmp); } else if (!strcmp("condest",fnames[ifield])) { param->condest=*mxGetPr(tmp); } else if (!strcmp("restol",fnames[ifield])) { param->restol=*mxGetPr(tmp); } else if (!strcmp("npresmoothing",fnames[ifield])) { param->npresmoothing=*mxGetPr(tmp); } else if (!strcmp("npostmoothing",fnames[ifield])) { param->npostsmoothing=*mxGetPr(tmp); } else if (!strcmp("ncoarse",fnames[ifield])) { param->ncoarse=*mxGetPr(tmp); } else if (!strcmp("matching",fnames[ifield])) { param->matching=*mxGetPr(tmp); } else if (!strcmp("nrestart",fnames[ifield])) { param->nrestart=*mxGetPr(tmp); } else if (!strcmp("damping",fnames[ifield])) { param->damping.r=*mxGetPr(tmp); if (mxIsComplex(tmp)) param->damping.i=*mxGetPi(tmp); else param->damping.i=0; } else if (!strcmp("mixedprecision",fnames[ifield])) { param->mixedprecision=*mxGetPr(tmp); } else { /* mexPrintf("%s ignored\n",fnames[ifield]);fflush(stdout); */ } } } /* copy right hand side `b' */ b_input = (mxArray *) prhs [3] ; /* get size of input matrix A */ rhs=(doublecomplex*) MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLSYMilupacksolver:rhs"); pr=mxGetPr(b_input); if (!mxIsComplex(b_input)) { for (i=0; i<A.nr; i++) { rhs[i].r=pr[i]; rhs[i].i=0; } } else { pi=mxGetPi(b_input); for (i=0; i<A.nr; i++) { rhs[i].r=pr[i]; rhs[i].i=pi[i]; } } /* copy initial solution `x0' */ x0_input = (mxArray *) prhs [4] ; /* numerical solution */ sol=(doublecomplex *)MAlloc((size_t)A.nr*sizeof(doublecomplex),"ZGNLSYMilupacksolver:sol"); pr=mxGetPr(x0_input); if (!mxIsComplex(x0_input)) { for (i=0; i<A.nr; i++) { sol[i].r=pr[i]; sol[i].i=0; } } else { pi=mxGetPi(x0_input); for (i=0; i<A.nr; i++) { sol[i].r=pr[i]; sol[i].i=pi[i]; } } ierr=ZGNLSYMAMGsolver(&A, PRE, param, rhs, sol); /* Create a struct matrices for output */ nlhs=2; if (j==-1) plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, (mwSize)nfields+1, fnames); else plhs[1] = mxCreateStructMatrix((mwSize)1, (mwSize)1, (mwSize)nfields, fnames); if (plhs[1]==NULL) mexErrMsgTxt("Could not create structure mxArray\n"); options_output=plhs[1]; /* export data */ for (ifield = 0; ifield<nfields; ifield++) { tmp = mxGetFieldByNumber(options_input,0,ifield); classIDflags[ifield] = mxGetClassID(tmp); ndim = mxGetNumberOfDimensions(tmp); dims = mxGetDimensions(tmp); /* Create string/numeric array */ if (classIDflags[ifield] == mxCHAR_CLASS) { if (!strcmp("amg",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->amg)+1, (size_t)sizeof(char)); strcpy(output_buf,param->amg); fout = mxCreateString(output_buf); } else if (!strcmp("presmoother",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->presmoother)+1, (size_t)sizeof(char)); strcpy(output_buf,param->presmoother); fout = mxCreateString(output_buf); } else if (!strcmp("postsmoother",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->postsmoother)+1, (size_t)sizeof(char)); strcpy(output_buf,param->postsmoother); fout = mxCreateString(output_buf); } else if (!strcmp("typecoarse",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->typecoarse)+1, (size_t)sizeof(char)); strcpy(output_buf,param->typecoarse); fout = mxCreateString(output_buf); } else if (!strcmp("typetv",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->typetv)+1, (size_t)sizeof(char)); strcpy(output_buf,param->typetv); fout = mxCreateString(output_buf); } else if (!strcmp("FCpart",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->FCpart)+1, (size_t)sizeof(char)); strcpy(output_buf,param->FCpart); fout = mxCreateString(output_buf); } else if (!strcmp("solver",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->solver)+1, (size_t)sizeof(char)); strcpy(output_buf, param->solver); fout = mxCreateString(output_buf); } else if (!strcmp("ordering",fnames[ifield])) { output_buf = (char *) mxCalloc((size_t)strlen(param->ordering)+1, (size_t)sizeof(char)); strcpy(output_buf, param->ordering); fout = mxCreateString(output_buf); } else { /* Get the length of the input string. */ buflen = (mxGetM(tmp) * mxGetN(tmp)) + 1; /* Allocate memory for input and output strings. */ input_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); output_buf = (char *) mxCalloc((size_t)buflen, (size_t)sizeof(char)); /* Copy the string data from tmp into a C string input_buf. */ status = mxGetString(tmp, input_buf, buflen); sizebuf = (size_t)buflen*sizeof(char); memcpy(output_buf, input_buf, sizebuf); fout = mxCreateString(output_buf); } } else { /* real case */ if (mxGetPi(tmp)==NULL && strcmp("damping",fnames[ifield])) fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxREAL); else { /* complex case */ fout = mxCreateNumericArray(ndim, dims, classIDflags[ifield], mxCOMPLEX); } pdata = mxGetData(fout); sizebuf = mxGetElementSize(tmp); if (!strcmp("elbow",fnames[ifield])) { dbuf=param->elbow; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("lfilS",fnames[ifield])) { dbuf=param->lfilS; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("lfil",fnames[ifield])) { dbuf=param->lfil; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("maxit",fnames[ifield])) { dbuf=param->maxit; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("droptolS",fnames[ifield])) { dbuf=param->droptolS; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("droptol",fnames[ifield])) { dbuf=param->droptol; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("condest",fnames[ifield])) { dbuf=param->condest; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("restol",fnames[ifield])) { dbuf=param->restol; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("npresmoothing",fnames[ifield])) { dbuf=param->npresmoothing; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("npostmoothing",fnames[ifield])) { dbuf=param->npostsmoothing; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("ncoarse",fnames[ifield])) { dbuf=param->ncoarse; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("matching",fnames[ifield])) { dbuf=param->matching; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("nrestart",fnames[ifield])) { dbuf=param->nrestart; memcpy(pdata, &dbuf, sizebuf); } else if (!strcmp("damping",fnames[ifield])) { pr=mxGetPr(fout); pi=mxGetPi(fout); *pr=param->damping.r; *pi=param->damping.i; } else if (!strcmp("mixedprecision",fnames[ifield])) { dbuf=param->mixedprecision; memcpy(pdata, &dbuf, sizebuf); } else { memcpy(pdata, mxGetData(tmp), sizebuf); } } /* Set each field in output structure */ mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout); } /* store number of iteration steps */ if (j==-1) ifield=nfields; else ifield=j; fout=mxCreateDoubleMatrix((mwSize)1,(mwSize)1, mxREAL); pr=mxGetPr(fout); *pr=param->ipar[26]; /* set each field in output structure */ mxSetFieldByNumber(options_output, (mwIndex)0, ifield, fout); mxFree(fnames); mxFree(classIDflags); /* mexPrintf("options exported\n"); fflush(stdout); */ /* export approximate solution */ plhs[0] = mxCreateDoubleMatrix((mwSize)A.nr, (mwSize)1, mxCOMPLEX); x_output=plhs[0]; pr=mxGetPr(x_output); pi=mxGetPi(x_output); for (i=0; i<A.nr; i++) { pr[i]=sol[i].r; pi[i]=sol[i].i; } /* release right hand side */ free(rhs); /* release solution */ free(sol); /* release input matrix */ free(A.ia); free(A.ja); free(A.a); switch (ierr) { case 0: /* perfect! */ break; case -1: /* too many iteration steps */ mexPrintf("!!! ILUPACK Warning !!!\n"); mexPrintf("number of iteration steps exceeded its limit.\nEither increase `options.maxit'\n or recompute ILUPACK preconditioner using a smaller `options.droptol'"); break; case -2: /* weird, should not occur */ mexErrMsgTxt("not enough workspace provided."); plhs[0]=NULL; break; case -3: /* breakdown */ mexErrMsgTxt("iterative solver breaks down.\nMost likely you need to recompute ILUPACK preconditioner using a smaller `options.droptol'"); plhs[0]=NULL; break; default: /* zero pivot encountered at step number ierr */ mexPrintf("iterative solver exited with error code %d",ierr); mexErrMsgTxt("."); plhs[0]=NULL; break; } /* end switch */ return; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //----------------------- // Input pointers double *h_fMRI_Volumes_double, *h_X_GLM_double, *h_xtxxt_GLM_double, *h_Contrasts_double, *h_ctxtxc_GLM_double, *h_Whitened_Models_double; float *h_fMRI_Volumes, *h_X_GLM, *h_xtxxt_GLM, *h_Contrasts, *h_ctxtxc_GLM, *h_Whitened_Models; double *h_EPI_Mask_double, *h_Smoothed_EPI_Mask_double; float *h_EPI_Mask, *h_Smoothed_EPI_Mask; unsigned short int *h_Permutation_Matrix; float EPI_SMOOTHING_AMOUNT, AR_SMOOTHING_AMOUNT; float EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z; float CLUSTER_DEFINING_THRESHOLD; int INFERENCE_MODE, NUMBER_OF_PERMUTATIONS, OPENCL_PLATFORM, OPENCL_DEVICE; //----------------------- // Output pointers double *h_Permutation_Distribution_double; double *h_Beta_Volumes_double, *h_Residuals_double, *h_Residual_Variances_double, *h_Statistical_Maps_double; double *h_AR1_Estimates_double, *h_AR2_Estimates_double, *h_AR3_Estimates_double, *h_AR4_Estimates_double; double *h_Detrended_fMRI_Volumes_double; double *h_Whitened_fMRI_Volumes_double; double *h_Permuted_fMRI_Volumes_double; int *h_Cluster_Indices, *h_Cluster_Indices_Out; float *h_Permutation_Distribution; float *h_Beta_Volumes, *h_Residuals, *h_Residual_Variances, *h_Statistical_Maps; float *h_AR1_Estimates, *h_AR2_Estimates, *h_AR3_Estimates, *h_AR4_Estimates; float *h_Detrended_fMRI_Volumes; float *h_Whitened_fMRI_Volumes; float *h_Permuted_fMRI_Volumes; //--------------------- /* Check the number of input and output arguments. */ if(nrhs<18) { mexErrMsgTxt("Too few input arguments."); } if(nrhs>18) { mexErrMsgTxt("Too many input arguments."); } if(nlhs<13) { mexErrMsgTxt("Too few output arguments."); } if(nlhs>13) { mexErrMsgTxt("Too many output arguments."); } /* Input arguments */ // The data h_fMRI_Volumes_double = (double*)mxGetData(prhs[0]); h_EPI_Mask_double = (double*)mxGetData(prhs[1]); h_Smoothed_EPI_Mask_double = (double*)mxGetData(prhs[2]); h_X_GLM_double = (double*)mxGetData(prhs[3]); h_xtxxt_GLM_double = (double*)mxGetData(prhs[4]); h_Contrasts_double = (double*)mxGetData(prhs[5]); h_ctxtxc_GLM_double = (double*)mxGetData(prhs[6]); EPI_SMOOTHING_AMOUNT = (float)mxGetScalar(prhs[7]); AR_SMOOTHING_AMOUNT = (float)mxGetScalar(prhs[8]); EPI_VOXEL_SIZE_X = (float)mxGetScalar(prhs[9]); EPI_VOXEL_SIZE_Y = (float)mxGetScalar(prhs[10]); EPI_VOXEL_SIZE_Z = (float)mxGetScalar(prhs[11]); h_Permutation_Matrix = (unsigned short int*)mxGetData(prhs[12]); NUMBER_OF_PERMUTATIONS = (int)mxGetScalar(prhs[13]); INFERENCE_MODE = (int)mxGetScalar(prhs[14]); CLUSTER_DEFINING_THRESHOLD = (float)mxGetScalar(prhs[15]); OPENCL_PLATFORM = (int)mxGetScalar(prhs[16]); OPENCL_DEVICE = (int)mxGetScalar(prhs[17]); int NUMBER_OF_DIMENSIONS = mxGetNumberOfDimensions(prhs[0]); const int *ARRAY_DIMENSIONS_DATA = mxGetDimensions(prhs[0]); const int *ARRAY_DIMENSIONS_GLM = mxGetDimensions(prhs[3]); const int *ARRAY_DIMENSIONS_CONTRAST = mxGetDimensions(prhs[6]); int DATA_H, DATA_W, DATA_D, DATA_T, NUMBER_OF_REGRESSORS, NUMBER_OF_TOTAL_GLM_REGRESSORS, NUMBER_OF_CONTRASTS; DATA_H = ARRAY_DIMENSIONS_DATA[0]; DATA_W = ARRAY_DIMENSIONS_DATA[1]; DATA_D = ARRAY_DIMENSIONS_DATA[2]; DATA_T = ARRAY_DIMENSIONS_DATA[3]; NUMBER_OF_REGRESSORS = ARRAY_DIMENSIONS_GLM[1]; NUMBER_OF_TOTAL_GLM_REGRESSORS = NUMBER_OF_REGRESSORS; NUMBER_OF_CONTRASTS = ARRAY_DIMENSIONS_CONTRAST[1]; int DATA_SIZE = DATA_W * DATA_H * DATA_D * DATA_T * sizeof(float); int VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float); int VOLUME_SIZE_INT = DATA_W * DATA_H * DATA_D * sizeof(int); int GLM_SIZE = DATA_T * NUMBER_OF_REGRESSORS * sizeof(float); int CONTRAST_SIZE = NUMBER_OF_REGRESSORS * NUMBER_OF_CONTRASTS * sizeof(float); int CONTRAST_MATRIX_SIZE = NUMBER_OF_CONTRASTS * NUMBER_OF_CONTRASTS * sizeof(float); int BETA_SIZE = DATA_W * DATA_H * DATA_D * NUMBER_OF_TOTAL_GLM_REGRESSORS * sizeof(float); int STATISTICAL_MAPS_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float); int DESIGN_MATRIX_SIZE = NUMBER_OF_TOTAL_GLM_REGRESSORS * DATA_T * sizeof(float); int NULL_DISTRIBUTION_SIZE = NUMBER_OF_PERMUTATIONS * sizeof(float); mexPrintf("Data size : %i x %i x %i x %i \n", DATA_W, DATA_H, DATA_D, DATA_T); mexPrintf("Number of regressors : %i \n", NUMBER_OF_REGRESSORS); mexPrintf("Number of contrasts : %i \n", NUMBER_OF_CONTRASTS); mexPrintf("Number of permutations : %i \n", NUMBER_OF_PERMUTATIONS); //------------------------------------------------- // Output to Matlab // Create pointer for volumes to Matlab NUMBER_OF_DIMENSIONS = 4; int ARRAY_DIMENSIONS_OUT_BETA[4]; ARRAY_DIMENSIONS_OUT_BETA[0] = DATA_H; ARRAY_DIMENSIONS_OUT_BETA[1] = DATA_W; ARRAY_DIMENSIONS_OUT_BETA[2] = DATA_D; ARRAY_DIMENSIONS_OUT_BETA[3] = NUMBER_OF_TOTAL_GLM_REGRESSORS; plhs[0] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_BETA,mxDOUBLE_CLASS, mxREAL); h_Beta_Volumes_double = mxGetPr(plhs[0]); NUMBER_OF_DIMENSIONS = 4; int ARRAY_DIMENSIONS_OUT_RESIDUALS[4]; ARRAY_DIMENSIONS_OUT_RESIDUALS[0] = DATA_H; ARRAY_DIMENSIONS_OUT_RESIDUALS[1] = DATA_W; ARRAY_DIMENSIONS_OUT_RESIDUALS[2] = DATA_D; ARRAY_DIMENSIONS_OUT_RESIDUALS[3] = DATA_T; plhs[1] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_RESIDUALS,mxDOUBLE_CLASS, mxREAL); h_Residuals_double = mxGetPr(plhs[1]); NUMBER_OF_DIMENSIONS = 3; int ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES[3]; ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES[0] = DATA_H; ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES[1] = DATA_W; ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES[2] = DATA_D; plhs[2] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_RESIDUAL_VARIANCES,mxDOUBLE_CLASS, mxREAL); h_Residual_Variances_double = mxGetPr(plhs[2]); NUMBER_OF_DIMENSIONS = 3; int ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS[3]; ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS[0] = DATA_H; ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS[1] = DATA_W; ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS[2] = DATA_D; plhs[3] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_STATISTICAL_MAPS,mxDOUBLE_CLASS, mxREAL); h_Statistical_Maps_double = mxGetPr(plhs[3]); NUMBER_OF_DIMENSIONS = 3; int ARRAY_DIMENSIONS_OUT_AR_ESTIMATES[3]; ARRAY_DIMENSIONS_OUT_AR_ESTIMATES[0] = DATA_H; ARRAY_DIMENSIONS_OUT_AR_ESTIMATES[1] = DATA_W; ARRAY_DIMENSIONS_OUT_AR_ESTIMATES[2] = DATA_D; plhs[4] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_AR_ESTIMATES,mxDOUBLE_CLASS, mxREAL); h_AR1_Estimates_double = mxGetPr(plhs[4]); plhs[5] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_AR_ESTIMATES,mxDOUBLE_CLASS, mxREAL); h_AR2_Estimates_double = mxGetPr(plhs[5]); plhs[6] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_AR_ESTIMATES,mxDOUBLE_CLASS, mxREAL); h_AR3_Estimates_double = mxGetPr(plhs[6]); plhs[7] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_AR_ESTIMATES,mxDOUBLE_CLASS, mxREAL); h_AR4_Estimates_double = mxGetPr(plhs[7]); NUMBER_OF_DIMENSIONS = 3; int ARRAY_DIMENSIONS_OUT_CLUSTER_INDICES[3]; ARRAY_DIMENSIONS_OUT_CLUSTER_INDICES[0] = DATA_H; ARRAY_DIMENSIONS_OUT_CLUSTER_INDICES[1] = DATA_W; ARRAY_DIMENSIONS_OUT_CLUSTER_INDICES[2] = DATA_D; plhs[8] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_CLUSTER_INDICES,mxINT32_CLASS, mxREAL); h_Cluster_Indices_Out = (int*)mxGetData(plhs[8]); NUMBER_OF_DIMENSIONS = 4; int ARRAY_DIMENSIONS_OUT_DETRENDED_VOLUMES[3]; ARRAY_DIMENSIONS_OUT_DETRENDED_VOLUMES[0] = DATA_H; ARRAY_DIMENSIONS_OUT_DETRENDED_VOLUMES[1] = DATA_W; ARRAY_DIMENSIONS_OUT_DETRENDED_VOLUMES[2] = DATA_D; ARRAY_DIMENSIONS_OUT_DETRENDED_VOLUMES[3] = DATA_T; plhs[9] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_DETRENDED_VOLUMES,mxDOUBLE_CLASS, mxREAL); h_Detrended_fMRI_Volumes_double = mxGetPr(plhs[9]); NUMBER_OF_DIMENSIONS = 4; int ARRAY_DIMENSIONS_OUT_WHITENED_VOLUMES[3]; ARRAY_DIMENSIONS_OUT_WHITENED_VOLUMES[0] = DATA_H; ARRAY_DIMENSIONS_OUT_WHITENED_VOLUMES[1] = DATA_W; ARRAY_DIMENSIONS_OUT_WHITENED_VOLUMES[2] = DATA_D; ARRAY_DIMENSIONS_OUT_WHITENED_VOLUMES[3] = DATA_T; plhs[10] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_WHITENED_VOLUMES,mxDOUBLE_CLASS, mxREAL); h_Whitened_fMRI_Volumes_double = mxGetPr(plhs[10]); NUMBER_OF_DIMENSIONS = 4; int ARRAY_DIMENSIONS_OUT_PERMUTED_VOLUMES[3]; ARRAY_DIMENSIONS_OUT_PERMUTED_VOLUMES[0] = DATA_H; ARRAY_DIMENSIONS_OUT_PERMUTED_VOLUMES[1] = DATA_W; ARRAY_DIMENSIONS_OUT_PERMUTED_VOLUMES[2] = DATA_D; ARRAY_DIMENSIONS_OUT_PERMUTED_VOLUMES[3] = DATA_T; plhs[11] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_PERMUTED_VOLUMES,mxDOUBLE_CLASS, mxREAL); h_Permuted_fMRI_Volumes_double = mxGetPr(plhs[11]); NUMBER_OF_DIMENSIONS = 2; int ARRAY_DIMENSIONS_OUT_DISTRIBUTION[2]; ARRAY_DIMENSIONS_OUT_DISTRIBUTION[0] = NUMBER_OF_PERMUTATIONS; ARRAY_DIMENSIONS_OUT_DISTRIBUTION[1] = 1; plhs[12] = mxCreateNumericArray(NUMBER_OF_DIMENSIONS,ARRAY_DIMENSIONS_OUT_DISTRIBUTION,mxDOUBLE_CLASS, mxREAL); h_Permutation_Distribution_double = mxGetPr(plhs[12]); // ------------------------------------------------ // Allocate memory on the host h_fMRI_Volumes = (float *)mxMalloc(DATA_SIZE); h_EPI_Mask = (float *)mxMalloc(VOLUME_SIZE); h_Smoothed_EPI_Mask = (float *)mxMalloc(VOLUME_SIZE); h_X_GLM = (float *)mxMalloc(GLM_SIZE); h_xtxxt_GLM = (float *)mxMalloc(GLM_SIZE); h_Contrasts = (float *)mxMalloc(CONTRAST_SIZE); h_ctxtxc_GLM = (float *)mxMalloc(CONTRAST_MATRIX_SIZE); h_Beta_Volumes = (float *)mxMalloc(BETA_SIZE); h_Residuals = (float *)mxMalloc(DATA_SIZE); h_Residual_Variances = (float *)mxMalloc(VOLUME_SIZE); h_Statistical_Maps = (float *)mxMalloc(STATISTICAL_MAPS_SIZE); h_AR1_Estimates = (float *)mxMalloc(VOLUME_SIZE); h_AR2_Estimates = (float *)mxMalloc(VOLUME_SIZE); h_AR3_Estimates = (float *)mxMalloc(VOLUME_SIZE); h_AR4_Estimates = (float *)mxMalloc(VOLUME_SIZE); h_Cluster_Indices = (int *)mxMalloc(VOLUME_SIZE_INT); h_Permutation_Distribution = (float *)mxMalloc(NULL_DISTRIBUTION_SIZE); h_Detrended_fMRI_Volumes = (float *)mxMalloc(DATA_SIZE); h_Whitened_fMRI_Volumes = (float *)mxMalloc(DATA_SIZE); h_Permuted_fMRI_Volumes = (float *)mxMalloc(DATA_SIZE); // Reorder and cast data pack_double2float_volumes(h_fMRI_Volumes, h_fMRI_Volumes_double, DATA_W, DATA_H, DATA_D, DATA_T); pack_double2float_volume(h_EPI_Mask, h_EPI_Mask_double, DATA_W, DATA_H, DATA_D); pack_double2float_volume(h_Smoothed_EPI_Mask, h_Smoothed_EPI_Mask_double, DATA_W, DATA_H, DATA_D); pack_double2float(h_X_GLM, h_X_GLM_double, NUMBER_OF_REGRESSORS * DATA_T); pack_double2float(h_xtxxt_GLM, h_xtxxt_GLM_double, NUMBER_OF_REGRESSORS * DATA_T); //pack_double2float(h_Contrasts, h_Contrasts_double, NUMBER_OF_REGRESSORS * NUMBER_OF_CONTRASTS); pack_double2float_image(h_Contrasts, h_Contrasts_double, NUMBER_OF_REGRESSORS, NUMBER_OF_CONTRASTS); pack_double2float(h_ctxtxc_GLM, h_ctxtxc_GLM_double, NUMBER_OF_CONTRASTS * NUMBER_OF_CONTRASTS); //------------------------ BROCCOLI_LIB BROCCOLI(OPENCL_PLATFORM,OPENCL_DEVICE); // Something went wrong... if (BROCCOLI.GetOpenCLInitiated() == 0) { int getPlatformIDsError = BROCCOLI.GetOpenCLPlatformIDsError(); int getDeviceIDsError = BROCCOLI.GetOpenCLDeviceIDsError(); int createContextError = BROCCOLI.GetOpenCLCreateContextError(); int getContextInfoError = BROCCOLI.GetOpenCLContextInfoError(); int createCommandQueueError = BROCCOLI.GetOpenCLCreateCommandQueueError(); int createProgramError = BROCCOLI.GetOpenCLCreateProgramError(); int buildProgramError = BROCCOLI.GetOpenCLBuildProgramError(); int getProgramBuildInfoError = BROCCOLI.GetOpenCLProgramBuildInfoError(); mexPrintf("Get platform IDs error is %d \n",getPlatformIDsError); mexPrintf("Get device IDs error is %d \n",getDeviceIDsError); mexPrintf("Create context error is %d \n",createContextError); mexPrintf("Get create context info error is %d \n",getContextInfoError); mexPrintf("Create command queue error is %d \n",createCommandQueueError); mexPrintf("Create program error is %d \n",createProgramError); mexPrintf("Build program error is %d \n",buildProgramError); mexPrintf("Get program build info error is %d \n",getProgramBuildInfoError); // Print create kernel errors int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (createKernelErrors[i] != 0) { mexPrintf("Create kernel error %i is %d \n",i,createKernelErrors[i]); } } mexPrintf("OPENCL initialization failed, aborting \n"); } else if (BROCCOLI.GetOpenCLInitiated() == 1) { BROCCOLI.SetInputfMRIVolumes(h_fMRI_Volumes); BROCCOLI.SetEPIWidth(DATA_W); BROCCOLI.SetEPIHeight(DATA_H); BROCCOLI.SetEPIDepth(DATA_D); BROCCOLI.SetEPITimepoints(DATA_T); BROCCOLI.SetEPIVoxelSizeX(EPI_VOXEL_SIZE_X); BROCCOLI.SetEPIVoxelSizeY(EPI_VOXEL_SIZE_Y); BROCCOLI.SetEPIVoxelSizeZ(EPI_VOXEL_SIZE_Z); BROCCOLI.SetEPISmoothingAmount(EPI_SMOOTHING_AMOUNT); BROCCOLI.SetARSmoothingAmount(AR_SMOOTHING_AMOUNT); BROCCOLI.SetEPIMask(h_EPI_Mask); BROCCOLI.SetSmoothedEPIMask(h_Smoothed_EPI_Mask); BROCCOLI.SetNumberOfGLMRegressors(NUMBER_OF_REGRESSORS); BROCCOLI.SetNumberOfContrasts(NUMBER_OF_CONTRASTS); BROCCOLI.SetDesignMatrix(h_X_GLM, h_xtxxt_GLM); BROCCOLI.SetContrasts(h_Contrasts); BROCCOLI.SetGLMScalars(h_ctxtxc_GLM); BROCCOLI.SetStatisticalTest(1); // F-test BROCCOLI.SetInferenceMode(INFERENCE_MODE); BROCCOLI.SetClusterDefiningThreshold(CLUSTER_DEFINING_THRESHOLD); BROCCOLI.SetNumberOfPermutations(NUMBER_OF_PERMUTATIONS); BROCCOLI.SetPermutationMatrix(h_Permutation_Matrix); BROCCOLI.SetOutputBetaVolumes(h_Beta_Volumes); BROCCOLI.SetOutputResiduals(h_Residuals); BROCCOLI.SetOutputResidualVariances(h_Residual_Variances); BROCCOLI.SetOutputStatisticalMaps(h_Statistical_Maps); BROCCOLI.SetOutputAREstimates(h_AR1_Estimates, h_AR2_Estimates, h_AR3_Estimates, h_AR4_Estimates); BROCCOLI.SetOutputClusterIndices(h_Cluster_Indices); BROCCOLI.SetOutputPermutationDistribution(h_Permutation_Distribution); BROCCOLI.SetOutputDetrendedfMRIVolumes(h_Detrended_fMRI_Volumes); BROCCOLI.SetOutputWhitenedfMRIVolumes(h_Whitened_fMRI_Volumes); BROCCOLI.SetOutputPermutedfMRIVolumes(h_Permuted_fMRI_Volumes); BROCCOLI.PerformGLMFTestFirstLevelPermutationWrapper(); // Print create buffer errors int* createBufferErrors = BROCCOLI.GetOpenCLCreateBufferErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (createBufferErrors[i] != 0) { mexPrintf("Create buffer error %i is %d \n",i,createBufferErrors[i]); } } // Print run kernel errors int* runKernelErrors = BROCCOLI.GetOpenCLRunKernelErrors(); for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++) { if (runKernelErrors[i] != 0) { mexPrintf("Run kernel error %i is %d \n",i,runKernelErrors[i]); } } } mexPrintf("Build info \n \n %s \n", BROCCOLI.GetOpenCLBuildInfoChar()); unpack_float2double_volumes(h_Beta_Volumes_double, h_Beta_Volumes, DATA_W, DATA_H, DATA_D, NUMBER_OF_TOTAL_GLM_REGRESSORS); unpack_float2double_volumes(h_Residuals_double, h_Residuals, DATA_W, DATA_H, DATA_D, DATA_T); unpack_float2double_volume(h_Residual_Variances_double, h_Residual_Variances, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_Statistical_Maps_double, h_Statistical_Maps, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_AR1_Estimates_double, h_AR1_Estimates, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_AR2_Estimates_double, h_AR2_Estimates, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_AR3_Estimates_double, h_AR3_Estimates, DATA_W, DATA_H, DATA_D); unpack_float2double_volume(h_AR4_Estimates_double, h_AR4_Estimates, DATA_W, DATA_H, DATA_D); unpack_int2int_volume(h_Cluster_Indices_Out, h_Cluster_Indices, DATA_W, DATA_H, DATA_D); unpack_float2double(h_Permutation_Distribution_double, h_Permutation_Distribution, NUMBER_OF_PERMUTATIONS); unpack_float2double_volumes(h_Detrended_fMRI_Volumes_double, h_Detrended_fMRI_Volumes, DATA_W, DATA_H, DATA_D, DATA_T); unpack_float2double_volumes(h_Whitened_fMRI_Volumes_double, h_Whitened_fMRI_Volumes, DATA_W, DATA_H, DATA_D, DATA_T); unpack_float2double_volumes(h_Permuted_fMRI_Volumes_double, h_Permuted_fMRI_Volumes, DATA_W, DATA_H, DATA_D, DATA_T); // Free all the allocated memory on the host mxFree(h_fMRI_Volumes); mxFree(h_EPI_Mask); mxFree(h_Smoothed_EPI_Mask); mxFree(h_X_GLM); mxFree(h_xtxxt_GLM); mxFree(h_Contrasts); mxFree(h_ctxtxc_GLM); mxFree(h_Beta_Volumes); mxFree(h_Residuals); mxFree(h_Residual_Variances); mxFree(h_Statistical_Maps); mxFree(h_AR1_Estimates); mxFree(h_AR2_Estimates); mxFree(h_AR3_Estimates); mxFree(h_AR4_Estimates); mxFree(h_Cluster_Indices); mxFree(h_Permutation_Distribution); mxFree(h_Detrended_fMRI_Volumes); mxFree(h_Whitened_fMRI_Volumes); mxFree(h_Permuted_fMRI_Volumes); return; }
shared_ptr<RvmClassifier> RvmClassifier::loadFromMatlab(const string& classifierFilename, const string& thresholdsFilename) { Logger logger = Loggers->getLogger("classification"); #ifdef WITH_MATLAB_CLASSIFIER logger.info("Loading RVM classifier from Matlab file: " + classifierFilename); MATFile *pmatfile; mxArray *pmxarray; // =mat double *matdata; pmatfile = matOpen(classifierFilename.c_str(), "r"); if (pmatfile == NULL) { throw invalid_argument("RvmClassifier: Could not open the provided classifier filename: " + classifierFilename); } pmxarray = matGetVariable(pmatfile, "num_hk"); if (pmxarray == 0) { throw runtime_error("RvmClassifier: There is a no num_hk in the classifier file."); // TODO (concerns the whole class): I think we leak memory here (all the MATFile and double pointers etc.)? } matdata = mxGetPr(pmxarray); int numFilter = (int)matdata[0]; mxDestroyArray(pmxarray); logger.debug("Found " + lexical_cast<string>(numFilter)+" reduced set vectors (RSVs)."); float nonlinThreshold; int nonLinType; float basisParam; int polyPower; float divisor; pmxarray = matGetVariable(pmatfile, "param_nonlin1_rvm"); if (pmxarray != 0) { matdata = mxGetPr(pmxarray); nonlinThreshold = (float)matdata[0]; nonLinType = (int)matdata[1]; basisParam = (float)(matdata[2] / 65025.0); // because the training images gray level values were divided by 255 polyPower = (int)matdata[3]; divisor = (float)matdata[4]; mxDestroyArray(pmxarray); } else { pmxarray = matGetVariable(pmatfile, "param_nonlin1"); if (pmxarray != 0) { matdata = mxGetPr(pmxarray); nonlinThreshold = (float)matdata[0]; nonLinType = (int)matdata[1]; basisParam = (float)(matdata[2] / 65025.0); // because the training images gray level values were divided by 255 polyPower = (int)matdata[3]; divisor = (float)matdata[4]; mxDestroyArray(pmxarray); } else { throw runtime_error("RvmClassifier: Could not find kernel parameters and bias."); // TODO tidying up?! } } shared_ptr<Kernel> kernel; if (nonLinType == 1) { // polynomial kernel kernel.reset(new PolynomialKernel(1 / divisor, basisParam / divisor, polyPower)); } else if (nonLinType == 2) { // RBF kernel kernel.reset(new RbfKernel(basisParam)); } else { throw runtime_error("RvmClassifier: Unsupported kernel type. Currently, only polynomial and RBF kernels are supported."); // TODO We should also throw/print the unsupported nonLinType value to the user } // TODO: logger.debug("Loaded kernel with params... "); shared_ptr<RvmClassifier> rvm = make_shared<RvmClassifier>(kernel); rvm->bias = nonlinThreshold; logger.debug("Reading the " + lexical_cast<string>(numFilter)+" non-linear filters support_hk* and weight_hk* ..."); char str[100]; sprintf(str, "support_hk%d", 1); pmxarray = matGetVariable(pmatfile, str); if (pmxarray == 0) { throw runtime_error("RvmClassifier: Unable to find the matrix 'support_hk1' in the classifier file."); } if (mxGetNumberOfDimensions(pmxarray) != 2) { throw runtime_error("RvmClassifier: The matrix 'support_hk1' in the classifier file should have 2 dimensions."); } const mwSize *dim = mxGetDimensions(pmxarray); int filterSizeY = (int)dim[0]; // height int filterSizeX = (int)dim[1]; // width TODO check if this is right with eg 24x16 mxDestroyArray(pmxarray); // Alloc space for SV's and alphas (weights) rvm->supportVectors.reserve(numFilter); rvm->coefficients.reserve(numFilter); // Read the reduced vectors and coefficients (weights): for (int i = 0; i < numFilter; ++i) { sprintf(str, "support_hk%d", i + 1); pmxarray = matGetVariable(pmatfile, str); if (pmxarray == 0) { throw runtime_error("RvmClassifier: Unable to find the matrix 'support_hk" + lexical_cast<string>(i + 1) + "' in the classifier file."); } if (mxGetNumberOfDimensions(pmxarray) != 2) { throw runtime_error("RvmClassifier: The matrix 'support_hk" + lexical_cast<string>(i + 1) + "' in the classifier file should have 2 dimensions."); } // Read the reduced-vector: matdata = mxGetPr(pmxarray); int k = 0; Mat supportVector(filterSizeY, filterSizeX, CV_32F); float* values = supportVector.ptr<float>(0); for (int x = 0; x < filterSizeX; ++x) // column-major order (ML-convention) for (int y = 0; y < filterSizeY; ++y) values[y * filterSizeX + x] = static_cast<float>(matdata[k++]); // because the training images gray level values were divided by 255 rvm->supportVectors.push_back(supportVector); mxDestroyArray(pmxarray); sprintf(str, "weight_hk%d", i + 1); pmxarray = matGetVariable(pmatfile, str); if (pmxarray != 0) { const mwSize *dim = mxGetDimensions(pmxarray); if ((dim[1] != i + 1) && (dim[0] != i + 1)) { throw runtime_error("RvmClassifier: The matrix " + lexical_cast<string>(str)+" in the classifier file should have a dimensions 1x" + lexical_cast<string>(i + 1) + " or " + lexical_cast<string>(i + 1) + "x1"); } vector<float> coefficientsForFilter; matdata = mxGetPr(pmxarray); for (int j = 0; j <= i; ++j) { coefficientsForFilter.push_back(static_cast<float>(matdata[j])); } rvm->coefficients.push_back(coefficientsForFilter); mxDestroyArray(pmxarray); } } // end for over numHKs logger.debug("Vectors and weights successfully read."); if (matClose(pmatfile) != 0) { logger.warn("RvmClassifier: Could not close file " + classifierFilename); // TODO What is this? An error? Info? Throw an exception? } logger.info("RVM successfully read."); //MATFile *mxtFile = matOpen(args->threshold, "r"); logger.info("Loading RVM thresholds from Matlab file: " + thresholdsFilename); pmatfile = matOpen(thresholdsFilename.c_str(), "r"); if (pmatfile == 0) { throw runtime_error("RvmClassifier: Unable to open the thresholds file (wrong format?):" + thresholdsFilename); } else { pmxarray = matGetVariable(pmatfile, "hierar_thresh"); if (pmxarray == 0) { throw runtime_error("RvmClassifier: Unable to find the matrix hierar_thresh in the thresholds file."); } else { double* matdata = mxGetPr(pmxarray); const mwSize *dim = mxGetDimensions(pmxarray); for (int o = 0; o < (int)dim[1]; ++o) { rvm->hierarchicalThresholds.push_back(static_cast<float>(matdata[o])); } mxDestroyArray(pmxarray); } matClose(pmatfile); } if (rvm->hierarchicalThresholds.size() != rvm->coefficients.size()) { throw runtime_error("RvmClassifier: Something seems to be wrong, hierarchicalThresholds.size() != coefficients.size(): " + lexical_cast<string>(rvm->hierarchicalThresholds.size()) + "!=" + lexical_cast<string>(rvm->coefficients.size())); } logger.info("RVM thresholds successfully read."); rvm->setNumFiltersToUse(numFilter); return rvm; #else string errorMessage("RvmClassifier: Cannot load a Matlab classifier, library compiled without support for Matlab. Please re-run CMake with WITH_MATLAB_CLASSIFIER enabled."); logger.error(errorMessage); throw std::runtime_error(errorMessage); #endif }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { struct mxArray_Tag *mx; mwSize inbytes, outbytes, i, k, idim, ndim; mwSize *dims_old, *dims_new; char *outstring; mxClassID outclass; int out_numeric; /* Check input arguments */ if( nrhs > 2 ) { mexErrMsgTxt("Too many input arguments."); } if( nrhs < 2 ) { mexErrMsgTxt("Not enough input arguments."); } if( nlhs > 1 ) { mexErrMsgTxt("Too many output arguments."); } if( mxIsSparse(prhs[0]) || (!mxIsNumeric(prhs[0]) && !mxIsChar(prhs[0]) && !mxIsLogical(prhs[0])) ) { mexErrMsgTxt("The first input argument must be a full numeric value, or char, or logical."); } if( !mxIsChar(prhs[1]) ) { mexErrMsgTxt("The second input argument must be a character array."); } /* Get input argument byte length */ inbytes = mxGetElementSize(prhs[0]); /* Check second input argument for desired output type */ outstring = mxArrayToString(prhs[1]); out_numeric = 1; if( strcmp(outstring,"int8") == 0 ) { outclass = mxINT8_CLASS; outbytes = 1; } else if( strcmp(outstring,"uint8") == 0 ) { outclass = mxUINT8_CLASS; outbytes = 1; } else if( strcmp(outstring,"int16") == 0 ) { outclass = mxINT16_CLASS; outbytes = 2; } else if( strcmp(outstring,"uint16") == 0 ) { outclass = mxUINT16_CLASS; outbytes = 2; } else if( strcmp(outstring,"int32") == 0 ) { outclass = mxINT32_CLASS; outbytes = 4; } else if( strcmp(outstring,"uint32") == 0 ) { outclass = mxUINT32_CLASS; outbytes = 4; } else if( strcmp(outstring,"int64") == 0 ) { outclass = mxINT64_CLASS; outbytes = 8; } else if( strcmp(outstring,"uint64") == 0 ) { outclass = mxUINT64_CLASS; outbytes = 8; } else if( strcmp(outstring,"double") == 0 ) { outclass = mxDOUBLE_CLASS; outbytes = 8; } else if( strcmp(outstring,"single") == 0 ) { outclass = mxSINGLE_CLASS; outbytes = 4; } else if( strcmp(outstring,"char") == 0 ) { outclass = mxCHAR_CLASS; outbytes = 2; out_numeric = 0; } else if( strcmp(outstring,"logical") == 0 ) { outclass = mxLOGICAL_CLASS; outbytes = 1; out_numeric = 0; } else { mxFree(outstring); mexErrMsgTxt("Unsupported class.\n"); } mxFree(outstring); /* Check for complex coversion to non-numeric */ if( mxIsComplex(prhs[0]) && !out_numeric ) { mexErrMsgTxt("Cannot typecast a complex input to a non-numeric class.\n"); } /* Check for empty input. No data to share, so simply create a new empty variable */ if( mxIsEmpty(prhs[0]) ) { if( out_numeric ) { plhs[0] = mxCreateNumericArray(mxGetNumberOfDimensions(prhs[0]), mxGetDimensions(prhs[0]), outclass, mxREAL); } else if( outclass == mxCHAR_CLASS ) { plhs[0] = mxCreateCharArray(mxGetNumberOfDimensions(prhs[0]), mxGetDimensions(prhs[0])); } else { plhs[0] = mxCreateLogicalArray(mxGetNumberOfDimensions(prhs[0]), mxGetDimensions(prhs[0])); } return; } /* Check the old & new sizes for compatibility */ ndim = mxGetNumberOfDimensions(prhs[0]); dims_old = mxGetDimensions(prhs[0]); for( i=0; i<ndim; i++ ) { if( dims_old[i] != 1 || i == ndim-1 ) { k = (dims_old[i] * inbytes) / outbytes; if( k * outbytes != dims_old[i] * inbytes ) { mexErrMsgTxt("Too few input values to make output type.\n"); } idim = i; break; } } dims_new = mxMalloc(ndim * sizeof(*dims_new)); for( i=0; i<ndim; i++ ) { dims_new[i] = dims_old[i]; } dims_new[idim] = k; /* Create the output array as a shared data copy, then manually set the class * and size parameters by accessing the structure fields directly. Note that * this is using undocumented MATLAB API functions and hacking of the * mxArray_tag structure, so this may not work in future versions of MATLAB. */ // mx = (struct mxArray_Tag *) prhs[0]; // printf("old flags: %#6x\n", mx->flags); plhs[0] = mxCreateSharedDataCopy(prhs[0]); mx = (struct mxArray_Tag *) plhs[0]; mx->ClassID = outclass; mx->VariableType = VariableType_Temporary; mxSetDimensions(plhs[0],dims_new,ndim); mxFree(dims_new); //mexPrintf("post shared data copy\n"); // printf("new flags: %#6x\n", mx->flags); return; // this breaks in R2018a, @djoshea removing /* Also need to fix up the flags */ if( outclass == mxDOUBLE_CLASS ) { if( mxGetNumberOfElements(plhs[0]) == 1 ) { mx->flags = 0x0211; /* Set numeric, temporary, and full double scalar bits */ } else { mx->flags = 0x0210; /* Set numeric and temporary bits */ } } else if( out_numeric ) { mx->flags = 0x0210; /* Set numeric and temporary bits */ } else { mx->flags = 0x0010; /* Set the temporary bit */ } }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { //declare variables mxArray *image_in_m, *c_out_m; const mwSize *dims; double *image, *c, beta; int MXS, MYS, numdims; int x,y; /* Check for proper number of input and output arguments */ if (nrhs != 2) { mexErrMsgIdAndTxt( "MATLAB: markov_network_multilable:invalidNumInputs", "Wrong number of arguments\n\n\t Data usage : labelfield = demo2(image,mask,sigma)."); } /* Check data type of input argument */ if (!(mxIsDouble(prhs[0])) || !(mxIsDouble(prhs[1]))){ mexErrMsgIdAndTxt( "MATLAB: markov_network_multilable:inputNotDouble", " Input arguments must be of type double."); } //associate inputs image_in_m = mxDuplicateArray(prhs[0]); //d_in_m = mxDuplicateArray(prhs[2]); //figure out dimensions dims = mxGetDimensions(prhs[0]); numdims = mxGetNumberOfDimensions(prhs[0]); MYS = (int)dims[0]; MXS = (int)dims[1]; //associate outputs c_out_m = plhs[0] = mxCreateDoubleMatrix(MYS,MXS,mxREAL); //associate pointers and scalars image = mxGetPr(image_in_m); beta = mxGetScalar(prhs[1]); c = mxGetPr(c_out_m); ///*do something*/ int nbLabels = 256; GCoptimizationGridGraph gc(MXS,MYS,nbLabels); /* */ for(y=0;y<MYS;y++) { for(x=0;x<MXS;x++) { int pixelIndex = y*MXS+x; for(int label=0;label<256;label++){ gc.setDataCost(pixelIndex,label,(int)pow(label*255.0/nbLabels- image[pixelIndex],2)); } } } /* Specifier le terme a priori */ for ( int l1 = 0; l1 < nbLabels; l1++ ) for (int l2 = 0; l2 < nbLabels; l2++ ){ float cost = beta*abs(l1-l2); gc.setSmoothCost(l1,l2,(int)cost); } /* On lance l'algorithme de graph cut */ gc.expansion(2); /* save results */ int i=0; for( int y=0;y<MYS;y++){ for( int x=0;x<MXS;x++,i++){ c[i]=gc.whatLabel(i); } } }
/* * main enterance point */ void mexFunction( int nlhs, /* number of expected outputs */ mxArray *plhs[], /* mxArray output pointer array */ int nrhs, /* number of inputs */ const mxArray *prhs[] /* mxArray input pointer array */ ) { if ( nrhs != 3 ) mexErrMsgIdAndTxt("edison_wraper:main","Must have three inputs"); if ( mxGetClassID(prhs[0]) != mxSINGLE_CLASS ) mexErrMsgIdAndTxt("edison_wraper:main","fim must be of type single"); if ( mxGetClassID(prhs[1]) != mxUINT8_CLASS ) mexErrMsgIdAndTxt("edison_wraper:main","rgbim must be of type uint8"); if ( mxGetClassID(prhs[2]) != mxSTRUCT_CLASS ) mexErrMsgIdAndTxt("edison_wraper:main","parameters argument must be a structure"); /* first argument - the image in whatever feature space it is given in */ float * fimage = (float*)mxGetData(prhs[0]); const int* image_dims = mxGetDimensions(prhs[0]); int image_ndim = mxGetNumberOfDimensions(prhs[0]); unsigned int w = image_dims[1]; unsigned int h = image_dims[2]; unsigned int N = image_dims[0]; int ii; unsigned char * rgbim = (unsigned char*)mxGetData(prhs[1]); const int * rgb_dims = mxGetDimensions(prhs[1]); if ( rgb_dims[1] != w || rgb_dims[2] != h ) mexErrMsgIdAndTxt("edison_wraper:main","size of fim and rgbim do not match"); /* second input - parameters structure */ // 'steps' - What steps the algorithm should perform: // 1 - only mean shift filtering // 2 - filtering and region fusion // 3 - full segmentation process [default] int steps; GetScalar(mxGetField(prhs[2], 0, "steps"), steps); // 'synergistic' - perform synergistic segmentation [true]|false bool syn; GetScalar(mxGetField(prhs[2], 0, "synergistic"), syn); // 'SpatialBandWidth' - segmentation spatial radius (integer) [7] unsigned int spBW; GetScalar(mxGetField(prhs[2], 0, "SpatialBandWidth"), spBW); // 'RangeBandWidth' - segmentation feature space radius (float) [6.5] float fsBW; GetScalar(mxGetField(prhs[2], 0, "RangeBandWidth"), fsBW); // 'MinimumRegionArea'- minimum segment area (integer) [20] unsigned int minArea; GetScalar(mxGetField(prhs[2], 0, "MinimumRegionArea"), minArea); // 'SpeedUp' - algorithm speed up {0,1,2} [1] int SpeedUp; enum SpeedUpLevel sul; GetScalar(mxGetField(prhs[2], 0, "SpeedUp"), SpeedUp); switch (SpeedUp) { case 1: sul = NO_SPEEDUP; break; case 2: sul = MED_SPEEDUP; break; case 3: sul = HIGH_SPEEDUP; break; default: mexErrMsgIdAndTxt("edison_wraper:main","wrong speedup value"); } // 'GradientWindowRadius' - synergistic parameters (integer) [2] unsigned int grWin; GetScalar(mxGetField(prhs[2], 0, "GradientWindowRadius"), grWin); // 'MixtureParameter' - synergistic parameter (float 0,1) [.3] float aij; GetScalar(mxGetField(prhs[2], 0, "MixtureParameter"), aij); // 'EdgeStrengthThreshold'- synergistic parameter (float 0,1) [.3] float edgeThr; GetScalar(mxGetField(prhs[2], 0, "EdgeStrengthThreshold"), edgeThr); msImageProcessor ms; ms.DefineLInput(fimage, h, w, N); // image array should be after permute if (ms.ErrorStatus) mexErrMsgIdAndTxt("edison_wraper:edison","Mean shift define latice input: %s", ms.ErrorMessage); kernelType k[2] = {DefualtKernelType, DefualtKernelType}; int P[2] = {DefualtSpatialDimensionality, N}; float tempH[2] = {1.0, 1.0}; ms.DefineKernel(k, tempH, P, 2); if (ms.ErrorStatus) mexErrMsgIdAndTxt("edison_wraper:edison","Mean shift define kernel: %s", ms.ErrorMessage); mxArray * mxconf = NULL; float * conf = NULL; mxArray * mxgrad = NULL; float * grad = NULL; mxArray * mxwght = NULL; float * wght = NULL; if (syn) { /* perform synergistic segmentation */ int maps_dim[2] = {w*h, 1}; /* allcate memory for confidence and gradient maps */ mxconf = mxCreateNumericArray(2, maps_dim, mxSINGLE_CLASS, mxREAL); conf = (float*)mxGetData(mxconf); mxgrad = mxCreateNumericArray(2, maps_dim, mxSINGLE_CLASS, mxREAL); grad = (float*)mxGetData(mxgrad); BgImage rgbIm; rgbIm.SetImage(rgbim, w, h, rgb_dims[0] == 3); BgEdgeDetect edgeDetector(grWin); edgeDetector.ComputeEdgeInfo(&rgbIm, conf, grad); mxwght = mxCreateNumericArray(2, maps_dim, mxSINGLE_CLASS, mxREAL); wght = (float*)mxGetData(mxgrad); for ( ii = 0 ; ii < w*h; ii++ ) { wght[ii] = (grad[ii] > .002) ? aij*grad[ii]+(1-aij)*conf[ii] : 0; } ms.SetWeightMap(wght, edgeThr); if (ms.ErrorStatus) mexErrMsgIdAndTxt("edison_wraper:edison","Mean shift set weights: %s", ms.ErrorMessage); } ms.Filter(spBW, fsBW, sul); if (ms.ErrorStatus) mexErrMsgIdAndTxt("edison_wraper:edison","Mean shift filter: %s", ms.ErrorMessage); if (steps == 2) { ms.FuseRegions(fsBW, minArea); if (ms.ErrorStatus) mexErrMsgIdAndTxt("edison_wraper:edison","Mean shift fuse: %s", ms.ErrorMessage); } if ( nlhs >= 1 ) { // first output - the feture space raw image plhs[0] = mxCreateNumericArray(image_ndim, image_dims, mxSINGLE_CLASS, mxREAL); fimage = (float*)mxGetData(plhs[0]); ms.GetRawData(fimage); } int* labels; float* modes; int* count; int RegionCount = ms.GetRegions(&labels, &modes, &count); if ( nlhs >= 2 ) { // second output - labeled image plhs[1] = mxCreateNumericArray(2, image_dims+1, mxINT32_CLASS, mxREAL); int* plabels = (int*)mxGetData(plhs[1]); for (ii=0; ii< w*h; ii++) plabels[ii] = labels[ii]; } delete [] labels; int arr_dims[2]; if ( nlhs >= 3 ) { // third output - the modes arr_dims[0] = N; arr_dims[1] = RegionCount; plhs[2] = mxCreateNumericArray(2, arr_dims, mxSINGLE_CLASS, mxREAL); fimage = (float*)mxGetData(plhs[2]); for (ii=0;ii<N*RegionCount; ii++) fimage[ii] = modes[ii]; } delete [] modes; if ( nlhs >= 4 ) { // fourth output - region sizes (# of pixels) arr_dims[0] = 1; arr_dims[1] = RegionCount; plhs[3] = mxCreateNumericArray(2, arr_dims, mxINT32_CLASS, mxREAL); int * pc = (int*)mxGetData(plhs[3]); for (ii=0;ii<RegionCount; ii++) pc[ii] = count[ii]; } delete [] count; if ( !syn ) return; if ( nlhs >= 5) // fifth output - gradient map plhs[4] = mxgrad; else mxDestroyArray(mxgrad); if ( nlhs >= 6) plhs[5] = mxconf; else mxDestroyArray(mxconf); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int dim, m, n, l, ntot, dims[3]; float *data1, *data2, *wx, *wy, *wz; double spline, nx, ny, nz, offx, offy, offz, mx, my, mz; size_t sizebuf; if (nrhs == 6) { spline = mxGetScalar(prhs[5]); } else if (nrhs == 5) { spline = 3; } else { mexPrintf("VAL = BsplCo2GdZZero(COEFF, [nx ny nz], [offx offy" " offz], [mx my mz], {wx wy wz}, deg);\n"); mexPrintf("[in]\n"); mexPrintf("\tCOEFF : bspline coefficients -" " single type\n"); mexPrintf("\t[nx ny nz] : output dimension\n"); mexPrintf("\t[offx offy offz] : offset of the origin\n"); mexPrintf("\t[mx my mz] : magnification factor for" " each direction\n"); mexPrintf("\t{wx wy wz} : deformed value vectors\n"); mexPrintf("\tdeg : (opt) spline basis degree" " {default: 3}\n"); mexPrintf("[out]\n"); mexPrintf("\tVAL : interpolated grad z" " values\n"); return; } if (mxIsSingle(prhs[0]) != 1) { mexErrMsgTxt("First argument must be of single type\n"); return; } /* Retrieve the input data */ data1 = mxGetData(prhs[0]); if (mxGetNumberOfDimensions(prhs[0]) == 3) { m = mxGetDimensions(prhs[0])[0]; n = mxGetDimensions(prhs[0])[1]; l = mxGetDimensions(prhs[0])[2]; } else { mexErrMsgTxt("First argument must be 3D\n"); return; } ntot = mxGetNumberOfElements(prhs[1]); dim = ntot; sizebuf = mxGetElementSize(prhs[1]); if (ntot == 3) { nx = *((double*)mxGetData(prhs[1])); ny = *((double*)(mxGetData(prhs[1]) + sizebuf)); nz = *((double*)(mxGetData(prhs[1]) + 2*sizebuf)); dims[0] = (int)nx; dims[1] = (int)ny; dims[2] = (int)nz; } else { mexErrMsgTxt("Second argument should be [nx ny nz]\n"); return; } ntot = mxGetNumberOfElements(prhs[2]); sizebuf = mxGetElementSize(prhs[2]); if (ntot == 3) { offx = *((double*)mxGetData(prhs[2])); offy = *((double*)(mxGetData(prhs[2]) + sizebuf)); offz = *((double*)(mxGetData(prhs[2]) + 2*sizebuf)); } else { mexErrMsgTxt("Third argument should be [offx offy offz]\n"); return; } ntot = mxGetNumberOfElements(prhs[3]); sizebuf = mxGetElementSize(prhs[3]); if (ntot == 3) { mx = *((double*)mxGetData(prhs[3])); my = *((double*)(mxGetData(prhs[3]) + sizebuf)); mz = *((double*)(mxGetData(prhs[3]) + 2*sizebuf)); } else { mexErrMsgTxt("Fourth argument should be [mx my mz]\n"); return; } ntot = mxGetNumberOfElements(prhs[4]); if (ntot == 0) { } else if (ntot == 3) { wx = (float*)mxGetData(mxGetCell(prhs[4], 0)); wy = (float*)mxGetData(mxGetCell(prhs[4], 1)); wz = (float*)mxGetData(mxGetCell(prhs[4], 2)); } else { mexErrMsgTxt("Fifth argument should be either {} or" " {wx wy wz}\n"); return; } /* Create an mxArray for the output data */ plhs[0] = mxCreateNumericArray(mxGetNumberOfElements(prhs[1]), dims, mxSINGLE_CLASS, mxREAL); /* Retrieve the output data */ data2 = mxGetData(plhs[0]); if (ntot == 0) { BatchInterpolatedGradZ3DZero(data2, data1, m, n, l, nx, offx, mx, ny, offy, my, nz, offz, mz, (long)spline); } else { BatchInterpolatedGradZ3DZeroWarp(data2, data1, m, n, l, nx, offx, mx, wx, ny, offy, my, wy, nz, offz, mz, wz, (long)spline); } }
void mexFunction(int nlhs, /* No. of output arguments */ mxArray *plhs[], /* Output arguments. */ int nrhs, /* No. of input arguments. */ const mxArray *prhs[]) /* Input arguments. */ { int ndim, pm_ndim; int n, i; const int *cdim = NULL, *pm_cdim = NULL; unsigned int dim[3]; unsigned int nnz = 0; double *rima = NULL; double *pm = NULL; double *ii = NULL, *jj = NULL; double *nn = NULL, *pp = NULL; double *tmp = NULL; if (nrhs == 0) mexErrMsgTxt("usage: [i,j,n,p]=pm_create_connectogram_dtj(rima,pm)"); if (nrhs != 2) mexErrMsgTxt("pm_create_connectogram_dtj: 2 input arguments required"); if (nlhs != 4) mexErrMsgTxt("pm_create_connectogram_dtj: 4 output argument required"); /* Get connected components map. */ if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0]) || mxIsSparse(prhs[0]) || !mxIsDouble(prhs[0])) { mexErrMsgTxt("pm_bwlabel_dtj: rima must be numeric, real, full and double"); } ndim = mxGetNumberOfDimensions(prhs[0]); if ((ndim < 2) | (ndim > 3)) { mexErrMsgTxt("pm_bwlabel_dtj: rima must be 2 or 3-dimensional"); } cdim = mxGetDimensions(prhs[0]); rima = mxGetPr(prhs[0]); /* Get phase-map. */ if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || mxIsSparse(prhs[1]) || !mxIsDouble(prhs[1])) { mexErrMsgTxt("pm_bwlabel_dtj: pm must be numeric, real, full and double"); } pm_ndim = mxGetNumberOfDimensions(prhs[1]); if (pm_ndim != ndim) { mexErrMsgTxt("pm_bwlabel_dtj: rima and pm must have same dimensionality"); } pm_cdim = mxGetDimensions(prhs[1]); for (i=0; i<ndim; i++) { if (cdim[i] != pm_cdim[i]) { mexErrMsgTxt("pm_bwlabel_dtj: rima and pm must have same size"); } } pm = mxGetPr(prhs[1]); /* Fix dimensions to allow for 2D and 3D data. */ dim[0]=cdim[0]; dim[1]=cdim[1]; if (ndim==2) {dim[2]=1; ndim=3;} else {dim[2]=cdim[2];} for (i=0, n=1; i<ndim; i++) { n *= dim[i]; } /* Create ii, jj, and nn and pp vectors for subsequent use by the matlab sparse function such that N = sparse(ii,jj,nn,nnz) generates a matrix where each non-zero entry signifies the no. of voxels along the border of the corresponding regions. */ nnz = make_vectors(rima,pm,dim,&ii,&jj,&nn,&pp); /* Allocate memory for output. */ plhs[0] = mxCreateDoubleMatrix(nnz,1,mxREAL); tmp = mxGetPr(plhs[0]); memcpy(tmp,ii,nnz*sizeof(double)); plhs[1] = mxCreateDoubleMatrix(nnz,1,mxREAL); tmp = mxGetPr(plhs[1]); memcpy(tmp,jj,nnz*sizeof(double)); plhs[2] = mxCreateDoubleMatrix(nnz,1,mxREAL); tmp = mxGetPr(plhs[2]); memcpy(tmp,nn,nnz*sizeof(double)); plhs[3] = mxCreateDoubleMatrix(nnz,1,mxREAL); tmp = mxGetPr(plhs[3]); memcpy(tmp,pp,nnz*sizeof(double)); /* Clean up a bit. */ mxFree(ii); mxFree(jj); mxFree(nn); mxFree(pp); return; }