コード例 #1
0
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;
}
コード例 #2
0
// 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;
}
コード例 #3
0
ファイル: bbmean.c プロジェクト: AlphaJi/pmtksupport
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;
}     
コード例 #4
0
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)]);
            }
        }
    }
    
    
}
コード例 #5
0
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);
}
コード例 #7
0
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);
}
コード例 #9
0
ファイル: tao_distance_3.cpp プロジェクト: qyouurcs/ncut
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;
}
コード例 #10
0
ファイル: siftrefinemx.c プロジェクト: BIANZiyang/3PRE
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) ;
  }

}
コード例 #11
0
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);



}
コード例 #12
0
//  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;
}
コード例 #13
0
ファイル: c_inference.cpp プロジェクト: Jadecity/SoftSeg
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;
  
}
コード例 #14
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;
}
コード例 #15
0
/**
* 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;
  }
}
コード例 #16
0
ファイル: SLIC_mex.cpp プロジェクト: AAAyag/SalBenchmark
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;
}
コード例 #17
0
ファイル: GcChanVeseLab.cpp プロジェクト: KorriZokta/ESIR3_IN
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);
}
コード例 #18
0
ファイル: findwithin.C プロジェクト: aweinstein/dw
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;
    }
}
コード例 #20
0
ファイル: segment_full.cpp プロジェクト: itsmeknt/cs231p2
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;
}
コード例 #21
0
ファイル: spm_mapping.c プロジェクト: rusjan/spm8
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;
    }
}
コード例 #22
0
ファイル: vl_erfill.c プロジェクト: 19test/sandbox
/* 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    ) ;
}
コード例 #23
0
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(&param, 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;
}
コード例 #24
0
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;
}
コード例 #25
0
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
}
コード例 #26
0
ファイル: typecastx.c プロジェクト: djoshea/matlab-utils
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 */
   }
}
コード例 #27
0
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);
        }
    }
        
}
コード例 #28
0
/*
 * 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);
   
}
コード例 #29
0
ファイル: BsplCo2GdZZero.c プロジェクト: Ole1/irt-clone
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); 
	}
}
コード例 #30
0
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;
}