Exemplo n.º 1
0
Arquivo: rk4.c Projeto: Ajaxels/MIB
__inline void interpgrad2d(double *Ireturn, double *I, int *Isize, double *point) {
    /*  Linear interpolation variables */
    int xBas0, xBas1, yBas0, yBas1;
    double perc[4]={0, 0, 0, 0};
    double xCom, yCom, xComi, yComi;
    double fTlocalx, fTlocaly;
    int f;
    int index[4];
    
    fTlocalx = floor(point[0]); fTlocaly = floor(point[1]);
    xBas0=(int) fTlocalx; yBas0=(int) fTlocaly;
    xBas1=xBas0+1; yBas1=yBas0+1;
    
    /* Linear interpolation constants (percentages) */
    xCom=point[0]-fTlocalx; yCom=point[1]-fTlocaly;
    xComi=(1-xCom); yComi=(1-yCom);
    perc[0]=xComi * yComi;
    perc[1]=xComi * yCom;
    perc[2]=xCom * yComi;
    perc[3]=xCom * yCom;
    
    /* Stick to boundary */
    if(xBas0<0) { xBas0=0; if(xBas1<0) { xBas1=0; }}
    if(yBas0<0) { yBas0=0; if(yBas1<0) { yBas1=0; }}
    if(xBas1>(Isize[0]-1)) { xBas1=Isize[0]-1; if(xBas0>(Isize[0]-1)) { xBas0=Isize[0]-1; }}
    if(yBas1>(Isize[1]-1)) { yBas1=Isize[1]-1; if(yBas0>(Isize[1]-1)) { yBas0=Isize[1]-1; }}
    
    /* Get the neighbour intensities */
    index[0]=mindex2(xBas0, yBas0, Isize[0]);
    index[1]=mindex2(xBas0, yBas1, Isize[0]);
    index[2]=mindex2(xBas1, yBas0, Isize[0]);
    index[3]=mindex2(xBas1, yBas1, Isize[0]);
    f=Isize[0]*Isize[1];
    
    /* the interpolated color */
    Ireturn[0]=I[index[0]]*perc[0]+I[index[1]]*perc[1]+I[index[2]]*perc[2]+I[index[3]]*perc[3];
    Ireturn[1]=I[index[0]+f]*perc[0]+I[index[1]+f]*perc[1]+I[index[2]+f]*perc[2]+I[index[3]+f]*perc[3];
}
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
    /* Ox and Oy are the grid points */
    /* Zo is the input image */
    /* Zi is the transformed image */

    /* nx and ny are the number of grid points (inside the image) */
    double *Ox,*Oy,*Oz,*dxa, *dya,*dza,*Iout;
    mxArray *matlabCallOut[1]={0};
    mxArray *matlabCallIn[1]={0};
    double *Nthreadsd;
    int Nthreads;
	/* double pointer array to store all needed function variables) */
    double ***ThreadArgs;
    double **ThreadArgs1;
    /* Handles to the worker threads */
		ThreadHANDLE *ThreadList;

    /* ID of Threads */
    double **ThreadID;              
    double *ThreadID1;
    
    double nlhs_d[1]={0};
    
    /* Size of input image */
	double *Isize_d;
    mwSize dims[3];


    /* Size of grid */
    mwSize  Osizex, Osizey, Osizez;
    double Osize_d[3]={0,0,0};
    const mwSize *dimso;
  
    /* B-spline variablesl */
    double u,v,w;
    int u_index=0; 
    int v_index=0;
    int w_index=0;
    
    double *Bu, *Bv, *Bw;
    double *Bdu, *Bdv, *Bdw;
	
	/* Loop variable  */
	int i;
	/* Grid distance */
    int dx,dy,dz; 
    /* X,Y,Z coordinates of current pixel */
    int x,y,z;
        
  /* Check for proper number of arguments. */
  if(nrhs!=7) {
    mexErrMsgTxt("Seven inputs are required.");
  }
 

  /* Get the sizes of the grid */
  dimso = mxGetDimensions(prhs[0]);   
  Osizex = dimso[0]; 
  Osizey = dimso[1];
  Osizez = dimso[2];
    
  /* Assign pointers to each input. */
  Ox=(double *)mxGetData(prhs[0]);
  Oy=(double *)mxGetData(prhs[1]);
  Oz=(double *)mxGetData(prhs[2]);
  Isize_d=(double *)mxGetData(prhs[3]);
  dxa=(double *)mxGetData(prhs[4]);
  dya=(double *)mxGetData(prhs[5]);
  dza=(double *)mxGetData(prhs[6]);
   
   
  /* Create image matrix for the return arguments with the size of input image  */  
  dims[0]=(mwSize)Isize_d[0];
  dims[1]=(mwSize)Isize_d[1];
  dims[2]=(mwSize)Isize_d[2];
  
  plhs[0] = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL); 
  
  
  /* Get the spacing of the uniform b-spline grid */
  dx=(int)dxa[0]; dy=(int)dya[0]; dz=(int)dza[0]; 
  
  /* Get number of allowed threads */
  mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads");
  Nthreadsd=mxGetPr(matlabCallOut[0]);
  Nthreads=(int)Nthreadsd[0];
  
    /* Reserve room for handles of threads in ThreadList  */
		ThreadList = (ThreadHANDLE*)malloc(Nthreads* sizeof( ThreadHANDLE ));
	
  ThreadID = (double **)malloc( Nthreads* sizeof(double *) );
  ThreadArgs = (double ***)malloc( Nthreads* sizeof(double **) );
  

  /* Assign pointer to output. */
  Iout = (double *)mxGetData(plhs[0]);
 
   /*  Make polynomial look up tables   */
  Bu=malloc(dx*4*sizeof(double));
  Bv=malloc(dy*4*sizeof(double));
  Bw=malloc(dz*4*sizeof(double));
  Bdu=malloc(dx*4*sizeof(double));
  Bdv=malloc(dy*4*sizeof(double));
  Bdw=malloc(dz*4*sizeof(double));
  
  for (x=0; x<dx; x++)
  {
    u=((double)x/(double)dx)-floor((double)x/(double)dx);
    Bu[mindex2(0,x,4)] = BsplineCoefficient(u,0);
    Bu[mindex2(1,x,4)] = BsplineCoefficient(u,1);
    Bu[mindex2(2,x,4)] = BsplineCoefficient(u,2);
    Bu[mindex2(3,x,4)] = BsplineCoefficient(u,3);
    Bdu[mindex2(0,x,4)] = BsplineCoefficientDerivative(u,0)/dxa[0];
    Bdu[mindex2(1,x,4)] = BsplineCoefficientDerivative(u,1)/dxa[0];
    Bdu[mindex2(2,x,4)] = BsplineCoefficientDerivative(u,2)/dxa[0];
    Bdu[mindex2(3,x,4)] = BsplineCoefficientDerivative(u,3)/dxa[0];
  }
  
  for (y=0; y<dy; y++)
  {
    v=((double)y/(double)dy)-floor((double)y/(double)dy);
    Bv[mindex2(0,y,4)] = BsplineCoefficient(v,0);
    Bv[mindex2(1,y,4)] = BsplineCoefficient(v,1);
    Bv[mindex2(2,y,4)] = BsplineCoefficient(v,2);
    Bv[mindex2(3,y,4)] = BsplineCoefficient(v,3);
    Bdv[mindex2(0,y,4)] = BsplineCoefficientDerivative(v,0)/dya[0];
    Bdv[mindex2(1,y,4)] = BsplineCoefficientDerivative(v,1)/dya[0];
    Bdv[mindex2(2,y,4)] = BsplineCoefficientDerivative(v,2)/dya[0];
    Bdv[mindex2(3,y,4)] = BsplineCoefficientDerivative(v,3)/dya[0];
  }
  
  for (z=0; z<dz; z++)
  {
    w=((double)z/(double)dz)-floor((double)z/(double)dz);
    Bw[mindex2(0,z,4)] = BsplineCoefficient(w,0);
    Bw[mindex2(1,z,4)] = BsplineCoefficient(w,1);
    Bw[mindex2(2,z,4)] = BsplineCoefficient(w,2);
    Bw[mindex2(3,z,4)] = BsplineCoefficient(w,3);
    Bdw[mindex2(0,z,4)] = BsplineCoefficientDerivative(w,0)/dza[0];
    Bdw[mindex2(1,z,4)] = BsplineCoefficientDerivative(w,1)/dza[0];
    Bdw[mindex2(2,z,4)] = BsplineCoefficientDerivative(w,2)/dza[0];
    Bdw[mindex2(3,z,4)] = BsplineCoefficientDerivative(w,3)/dza[0];
	
  }
  

  Osize_d[0]=(double)Osizex;  Osize_d[1]=(double)Osizey; Osize_d[2]=(double)Osizez;
  
  nlhs_d[0]=(double)nlhs;
  
 /* Reserve room for 16 function variables(arrays)   */
  for (i=0; i<Nthreads; i++)
  {
    /*  Make Thread ID  */
    ThreadID1= (double *)malloc( 1* sizeof(double) );
    ThreadID1[0]=(double)i;
    ThreadID[i]=ThreadID1;  
	
    /*  Make Thread Structure  */
    ThreadArgs1 = (double **)malloc( 17* sizeof( double * ) );  
	ThreadArgs1[0]=Bu;
	ThreadArgs1[1]=Bv;
	ThreadArgs1[2]=Bw;
	ThreadArgs1[3]=Isize_d;
	ThreadArgs1[4]=Osize_d;
	ThreadArgs1[5]=Iout;
	ThreadArgs1[6]=dxa;
	ThreadArgs1[7]=dya;
	ThreadArgs1[8]=dza;
	ThreadArgs1[9]=ThreadID[i];
	ThreadArgs1[10]=Ox;
	ThreadArgs1[11]=Oy;
	ThreadArgs1[12]=Oz;
	ThreadArgs1[13]=Nthreadsd;
    ThreadArgs1[14]=Bdu;
    ThreadArgs1[15]=Bdv;
	ThreadArgs1[16]=Bdw;
	
    ThreadArgs[i]=ThreadArgs1;

	StartThread(ThreadList[i], &transformvolume_jacobiandet, ThreadArgs[i])
  }

     for (i=0; i<Nthreads; i++) { WaitForThreadFinish(ThreadList[i]); }


  for (i=0; i<Nthreads; i++) 
  { 
    free(ThreadArgs[i]);
    free(ThreadID[i]);
  }

  free(ThreadArgs);
  free(ThreadID );
  free(ThreadList);  
  

  free(Bu);
  free(Bv);
  free(Bw);
  free(Bdu);
  free(Bdv);
  free(Bdw);
  
}
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[],
        int nrhs, const mxArray *prhs[] ) {
    /* Ox and Oy are the grid points */
    /* Zo is the input image */
    /* Zi is the transformed image */
    /* dx and dy are the spacing of the b-spline knots */
    double *Ox, *Oy, *dxa, *dya, *E, *Egradient;
    double *ThreadErrorOut, *ThreadGradientOutX, *ThreadGradientOutY;
    mxArray *matlabCallOut[1]={0};
    mxArray *matlabCallIn[1]={0};
    double *Nthreadsd;
    int Nthreads;
    /* Finite difference step size */
	double step=0.001;
    /* index offsets */
    int offset1;
    /* double pointer array to store all needed function variables) */
    double ***ThreadArgs;
    double **ThreadArgs1;
    /* Handles to the worker threads */
    ThreadHANDLE *ThreadList;
    /* ID of Threads */
    double **ThreadID;
    double *ThreadID1;
    /* Dims outputs */
    const int dims_error[2]={1, 1};
    int dims_error_gradient[3]={1, 1, 2};
    /* Size of input image */
    double *Isize_d;
    /* Size of grid */
    mwSize  Osizex, Osizey;
    int Onumel;
    double Inumel;
    double Osize_d[2]={0, 0};
    /* B-spline variablesl */
    double u, v;
    int u_index=0;
    int v_index=0;
    double *Bu, *Bv, *Bdu, *Bdv;
    /* Loop variables  */
    int i, j;
    /* X,Y coordinates of current pixel */
    int x, y;
    /* Grid distance */
    int dx, dy;
    
    /* Check for proper number of arguments. */
    if(nrhs!=5) {
        mexErrMsgTxt("Five nputs are required.");
    }
    
    /* Get the sizes of the grid */
    Osizex = (mwSize)mxGetM(prhs[0]);
    Osizey = (mwSize)mxGetN(prhs[0]);
    
    /* Assign pointers to each input. */
    Ox=mxGetPr(prhs[0]);
    Oy=mxGetPr(prhs[1]);
    Isize_d=mxGetPr(prhs[2]);
    dxa=mxGetPr(prhs[3]);
    dya=mxGetPr(prhs[4]);
    
    Onumel= Osizex*Osizey;
    Inumel = Isize_d[0]*Isize_d[1];
    /* Create image matrix for the Error return argument  */
    plhs[0] = mxCreateNumericArray(2, dims_error, mxDOUBLE_CLASS, mxREAL);
    if(nlhs>1) {
        dims_error_gradient[0]=Osizex;
        dims_error_gradient[1]=Osizey;
        /* Error Gradient needed */
        
        plhs[1] = mxCreateNumericArray(3, dims_error_gradient, mxDOUBLE_CLASS, mxREAL);
    }
    
    /* Get the spacing of the uniform b-spline grid */
    dx=(int)dxa[0]; dy=(int)dya[0];
    
    /* Get number of allowed threads */
    mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads");
    Nthreadsd=mxGetPr(matlabCallOut[0]);
    Nthreads=(int)Nthreadsd[0];
    /* Reserve room for handles of threads in ThreadList  */
    ThreadList = (ThreadHANDLE*)malloc(Nthreads* sizeof( ThreadHANDLE ));
    
    ThreadID = (double **)malloc( Nthreads* sizeof(double *) );
    ThreadArgs = (double ***)malloc( Nthreads* sizeof(double **) );
    
    ThreadErrorOut= (double *)malloc(Nthreads* sizeof(double) ); 
    if(nlhs==1)
    {	
        ThreadGradientOutX=NULL;
        ThreadGradientOutY=NULL;
    }
    else 
    {   
        ThreadGradientOutX= (double *)malloc(Nthreads*Onumel*sizeof(double));
        ThreadGradientOutY= (double *)malloc(Nthreads*Onumel*sizeof(double));
    }
    
    /* Assign pointer to output. */
    E = mxGetPr(plhs[0]);
    if(nlhs>1) { Egradient = mxGetPr(plhs[1]); }
    
    /*  Make polynomial look up tables   */
    Bu=malloc(dx*4*sizeof(double));
    Bv=malloc(dy*4*sizeof(double));
    Bdu=malloc(dx*4*sizeof(double));
    Bdv=malloc(dy*4*sizeof(double));
    for (x=0; x<dx; x++) {
        u=(x/(double)dx)-floor(x/(double)dx);
        Bu[mindex2(0, x, 4)] = BsplineCoefficient(u, 0);
        Bu[mindex2(1, x, 4)] = BsplineCoefficient(u, 1);
        Bu[mindex2(2, x, 4)] = BsplineCoefficient(u, 2);
        Bu[mindex2(3, x, 4)] = BsplineCoefficient(u, 3);
        Bdu[mindex2(0, x, 4)] = BsplineCoefficientDerivative(u, 0)/dxa[0];
        Bdu[mindex2(1, x, 4)] = BsplineCoefficientDerivative(u, 1)/dxa[0];
        Bdu[mindex2(2, x, 4)] = BsplineCoefficientDerivative(u, 2)/dxa[0];
        Bdu[mindex2(3, x, 4)] = BsplineCoefficientDerivative(u, 3)/dxa[0];
    }
    
    for (y=0; y<dy; y++) {
        v=(y/(double)dy)-floor(y/(double)dy);
        Bv[mindex2(0, y, 4)] = BsplineCoefficient(v, 0);
        Bv[mindex2(1, y, 4)] = BsplineCoefficient(v, 1);
        Bv[mindex2(2, y, 4)] = BsplineCoefficient(v, 2);
        Bv[mindex2(3, y, 4)] = BsplineCoefficient(v, 3);
        Bdv[mindex2(0, y, 4)] = BsplineCoefficientDerivative(v, 0)/dya[0];
        Bdv[mindex2(1, y, 4)] = BsplineCoefficientDerivative(v, 1)/dya[0];
        Bdv[mindex2(2, y, 4)] = BsplineCoefficientDerivative(v, 2)/dya[0];
        Bdv[mindex2(3, y, 4)] = BsplineCoefficientDerivative(v, 3)/dya[0];
    }
    
    Osize_d[0]=Osizex;  Osize_d[1]=Osizey;
        
    /* Reserve room for 14 function variables(arrays)   */
    for (i=0; i<Nthreads; i++) {
        /*  Make Thread ID  */
        ThreadID1= (double *)malloc( 1* sizeof(double) );
        ThreadID1[0]=i;
        ThreadID[i]=ThreadID1;
        /*  Make Thread Structure  */
        ThreadArgs1 = (double **)malloc( 15 * sizeof( double * ) );
        ThreadArgs1[0]=Bu;
        ThreadArgs1[1]=Bv;
        ThreadArgs1[2]=Isize_d;
        ThreadArgs1[3]=Osize_d;
        ThreadArgs1[4]=ThreadErrorOut;
        ThreadArgs1[5]=dxa;
        ThreadArgs1[6]=dya;
        ThreadArgs1[7]=ThreadID[i];
        ThreadArgs1[8]=Ox;
        ThreadArgs1[9]=Oy;
        ThreadArgs1[10]=Nthreadsd;
        ThreadArgs1[11]=Bdu;
        ThreadArgs1[12]=Bdv;
        ThreadArgs1[13]=ThreadGradientOutX;
        ThreadArgs1[14]=ThreadGradientOutY;
    
        ThreadArgs[i]=ThreadArgs1;
        if(nlhs>1) 
        {
            StartThread(ThreadList[i], &jacobian_errorgradient, ThreadArgs[i])
        }
        else
        {
            StartThread(ThreadList[i], &jacobian_error, ThreadArgs[i])
        }
    }

    for (i=0; i<Nthreads; i++) { WaitForThreadFinish(ThreadList[i]); }
    
    /* Add accumlated error of all threads */
    E[0]=0;
    for (i=0; i<Nthreads; i++) 
    {
        E[0]+=ThreadErrorOut[i]; 
    } 
    E[0]/=Inumel;

    if(nlhs>1) {
        for (i=0; i<Nthreads; i++) {
            offset1=i*Onumel;
            for(j=0; j<Onumel; j++) {
                Egradient[j]+=ThreadGradientOutX[j+offset1];
                Egradient[j+Onumel]+=ThreadGradientOutY[j+offset1];
            }
        }
        for(j=0; j<Onumel; j++) {
            Egradient[j]/=Inumel*step;
            Egradient[j+Onumel]/=Inumel*step;
        }
    }
        
    for (i=0; i<Nthreads; i++) {
        free(ThreadArgs[i]);
        free(ThreadID[i]);
    }
    
    free(ThreadErrorOut);
    free(ThreadGradientOutX);
    free(ThreadGradientOutY);
        
    free(ThreadArgs);
    free(ThreadID );
    free(ThreadList);
    free(Bu);
    free(Bdu);
    free(Bv);
    free(Bdv);
    
}
voidthread transformvolume_jacobiandet(double **Args) {
    double *Bu, *Bv, *Bdu, *Bdv, *Iout, *dxa, *dya, *ThreadID, *Ox, *Oy;
    double *Isize_d;
    double *Osize_d;
    int Isize[3]={0,0,0};
    int Osize[2]={0,0};

    double *Nthreadsd;
    int Nthreads;
    /* Multiple threads, one does the odd the other even indexes */
    int ThreadOffset;
    /* Location of pixel which will be come the current pixel */
    double Tlocalx,Tlocaly;
    double Tlocaldxx, Tlocaldxy, Tlocaldyy, Tlocaldyx;
            
    /* Variables to store 1D index */
    int indexO;
    int indexI;
    /* Grid distance */
    int dx,dy; 
    /* X,Y coordinates of current pixel */
    int x,y;
    /* B-spline variablesl */
    int u_index=0; 
    int v_index=0;
    int i, j;
    /* temporary value */
	double valx,valy;

	
	/* Look up tables index */
	int *u_index_array, *i_array;
	int *v_index_array, *j_array;
    /*  B-Spline loop variabels */
    int l,m;


    /* Current voxel/pixel */
	double Ipixel[3]={0,0,0};
    /* Split input into variables */
    Bu=Args[0];
    Bv=Args[1];
    Isize_d=Args[2];
    Osize_d=Args[3];
    Iout=Args[4];
    dxa=Args[5];
    dya=Args[6];
    ThreadID=Args[7];
    Ox=Args[8];
    Oy=Args[9];
    Nthreadsd=Args[10];  Nthreads=(int)Nthreadsd[0];
    Bdu=Args[11];
    Bdv=Args[12];
    Isize[0] = (int)Isize_d[0]; 
    Isize[1] = (int)Isize_d[1]; 
    Osize[0] = (int)Osize_d[0]; 
    Osize[1] = (int)Osize_d[1]; 

    /* Get the spacing of the uniform b-spline grid */
    dx=(int)dxa[0]; dy=(int)dya[0];
    
    ThreadOffset=(int) ThreadID[0];
	/*  Calculate the indexs need to look up the B-spline values. */
	u_index_array= (int*)malloc(Isize[0]* sizeof(int));
	i_array= (int*)malloc(Isize[0]* sizeof(int));
	v_index_array= (int*)malloc(Isize[1]* sizeof(int));
	j_array= (int*)malloc(Isize[1]* sizeof(int));
	for (x=0; x<Isize[0]; x++) {
        u_index_array[x]=(x%dx)*4; /* Already multiplied by 4, because it specifies the y dimension */
        i_array[x]=(int)floor((double)x/dx); /*  (first row outside image against boundary artefacts)  */
	}
	for (y=ThreadOffset; y<Isize[1]; y++) {
	    v_index_array[y]=(y%dy)*4; j_array[y]=(int)floor((double)y/dy);
	}
   
    /*  Loop through all image pixel coordinates */
    for (y=ThreadOffset; y<Isize[1]; y=y+Nthreads)
    {
  		v_index=v_index_array[y]; j=j_array[y];
        for (x=0; x<Isize[0]; x++)
        {
            /* Calculate the index needed to loop up the B-spline values. */
			u_index=u_index_array[x]; i=i_array[x];
            /*  This part calculates the coordinates of the pixel */
            /*  which will be transformed to the current x,y pixel. */
            Tlocalx=0; Tlocaly=0;
            Tlocaldxx=0; Tlocaldxy=0; 
            Tlocaldyy=0; Tlocaldyx=0;
            
            for(l=0; l<4; l++)
            {
				if(((i+l)>=0)&&((i+l)<Osize[0]))
				{
					for(m=0; m<4; m++)
					{    
						 if(((j+m)>=0)&&((j+m)<Osize[1]))
						 {
							  indexO=(i+l)+(j+m)*Osize[0];
                              valx=Bdu[l+u_index]*Bv[m+v_index];
                              valy=Bu[l+u_index]*Bdv[m+v_index];
                              
                              Tlocaldxx+=valx*Ox[indexO]; 
                              Tlocaldyy+=valy*Oy[indexO];
                              Tlocaldxy+=valy*Ox[indexO]; 
                              Tlocaldyx+=valx*Oy[indexO];
						 }
					}
				}
            }            

            /* Set the current pixel value */
            indexI=mindex2(x,y,Isize[0]);
            
            Iout[indexI]=Tlocaldxx*Tlocaldyy-Tlocaldyx*Tlocaldxy;




        }
    }
    
	/* Free memory index look up tables */
	free(u_index_array);
	free(v_index_array);
	free(i_array);
	free(j_array);
	
    /*  explicit end thread, helps to ensure proper recovery of resources allocated for the thread */
	EndThread;
}
Exemplo n.º 5
0
  unsigned __stdcall transformvolume_gray(double **Args) {
#else
  void transformvolume_gray(double **Args) {
#endif
    double *Isize_d, *A, *Iin, *Iout, *ThreadID, *moded, *Jsize_d;
    int Isize[3]={0,0,0};
	int Jsize[3]={0,0,0};
	double Imean[2]={0,0};
	double Jmean[2]={0,0};
    int mode=0;
    int x,y;
	double *Nthreadsd;
    int Nthreads;

    /* Location of pixel which will be come the current pixel */
    double Tlocalx;
    double Tlocaly;
    
    /* X,Y,Z coordinates of current pixel */
    double xd,yd;

	/* Parts of location calculation */
	double compa0, compa1, compb0, compb1;
	
    /* Variables to store 1D index */
    int indexI;
    
    /* Cubic and outside black booleans */
    bool black, cubic;
    
    /* Multiple threads, one does the odd the other even indexes */
    int ThreadOffset;
    /* int start; */
    /* int end;; */
    
    Isize_d=Args[0];
   	Jsize_d=Args[1];
	A=Args[2];
    Iin=Args[3];
    Iout=Args[4];
    ThreadID=Args[5];
    moded=Args[6]; mode=(int) moded[0];
    Nthreadsd=Args[7];  Nthreads=(int)Nthreadsd[0];
  
	/* Center of the image */
	Imean[0]=Isize_d[0]/2;	Imean[1]=Isize_d[1]/2;  
    Jmean[0]=Jsize_d[0]/2;	Jmean[1]=Jsize_d[1]/2; 
                    
    black = true;
    cubic = false;
    if(mode==0||mode==2){ black = false; } else { black = true; }
    if(mode==0||mode==1){ cubic = false; } else { cubic = true; }
    
    
    Isize[0] = (int)Isize_d[0]; 
    Isize[1] = (int)Isize_d[1]; 
    Isize[2] = (int)Isize_d[2]; 
	
	Jsize[0] = (int)Jsize_d[0]; 
    Jsize[1] = (int)Jsize_d[1]; 
    Jsize[2] = (int)Jsize_d[2]; 
	    
    ThreadOffset=(int) ThreadID[0];
	
	compb0= A[2] + Imean[0];
	compb1= A[5] + Imean[1];

    /*  Loop through all image pixel coordinates */
    for (y=ThreadOffset; y<Jsize[1]; y=y+Nthreads)
    {
		yd=(double)y-Jmean[1];
		compa0 = A[1] *yd + compb0;
		compa1 = A[4] *yd + compb1;

        for (x=0; x<Jsize[0]; x++)
        {
            xd=(double)x-Jmean[0];
            Tlocalx =  A[0] * xd + compa0;
            Tlocaly =  A[3] * xd + compa1;

            /* Set the current pixel value */
            indexI=mindex2(x,y,Jsize[0]);
            
            /* interpolate the intensities */
            Iout[indexI]=interpolate_2d_double_gray(Tlocalx, Tlocaly, Isize, Iin,cubic,black); 
        }
    }
   
    /*  explicit end thread, helps to ensure proper recovery of resources allocated for the thread */
    #ifdef _WIN32
	_endthreadex( 0 );
    return 0;
	#else
	pthread_exit(NULL);
	#endif
}
Exemplo n.º 6
0
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    /* Ox and Oy are the grid points */
    /* Zo is the input image */
    /* Zi is the transformed image */
    /* nx and ny are the number of grid points (inside the image) */
    double *Iin, *Iout, *M, *moded;
    mxArray *matlabCallOut[1]={0};
    //mxArray *matlabCallIn[1]={0};     // commented by Ilya Belevich
    mxArray *matlabCallIn[1]={mxCreateString("Numcores")};  // added by Ilya Belevich
    
    double *Nthreadsd;
    int Nthreads;
            
    /* double pointer array to store all needed function variables) */
    double ***ThreadArgs;
    double **ThreadArgs1;
    
	/* Handles to the worker threads */
	#ifdef _WIN32
		HANDLE *ThreadList; 
    #else
		pthread_t *ThreadList;
	#endif
    
    /* ID of Threads */
    double **ThreadID;              
    double *ThreadID1;
    
    /* Transformation matrix */
    double A[9]={0,0,0,0,0,0,0,0,0};

    /* Loop variable  */
    int i;
    
    /* Size of input image */
    double Isize_d[3]={0,0,0};
	double Jsize_d[3]={0,0,0};
    int Jdimsc[3]={0,0,0};
    const mwSize *dims;
	double *Jdims;

  /* Check for proper number of arguments. */
  if(nrhs<3) {
    mexErrMsgTxt("3 or 4 inputs are required.");
  } else if(nlhs!=1) {
    mexErrMsgTxt("One output required");
  }
  
  /* Get the sizes of the image */
  dims = mxGetDimensions(prhs[0]);   
  Isize_d[0] = (double)dims[0]; Isize_d[1] = (double)dims[1]; 
  /* Detect if color image */
  if(mxGetNumberOfDimensions(prhs[0])>2) { Isize_d[2]=(double)3; } else { Isize_d[2]=1; }
  
  /* Get output image size */
  if(nrhs==4)
  {
	Jdims = mxGetPr(prhs[3]);
    Jsize_d[0] = (double)Jdims[0]; 
	Jsize_d[1] = (double)Jdims[1]; 
    if(Isize_d[2]>0) { Jsize_d[2]=Isize_d[2];  }
  }
  else
  {
    Jsize_d[0] = Isize_d[0]; 
	Jsize_d[1] = Isize_d[1]; 
    if(Isize_d[2]>0) { Jsize_d[2]=Isize_d[2];  }
  }   
   
  /* Create output array */
  Jdimsc[0]=(int)Jsize_d[0];
  Jdimsc[1]=(int)Jsize_d[1];
  Jdimsc[2]=(int)Jsize_d[2];
      
  if(Isize_d[2]>1) {
      plhs[0] = mxCreateNumericArray(3, Jdimsc, mxDOUBLE_CLASS, mxREAL);
  }
  else  {
      plhs[0] = mxCreateNumericArray(2, Jdimsc, mxDOUBLE_CLASS, mxREAL);
  }
          
  /* Assign pointers to each input. */
  Iin=mxGetPr(prhs[0]);
  M=mxGetPr(prhs[1]);
  moded=mxGetPr(prhs[2]);
 
  A[0] = M[mindex2(0,0,3)]; A[1] = M[mindex2(0,1,3)]; A[2] = M[mindex2(0,2,3)]; 
  A[3] = M[mindex2(1,0,3)]; A[4] = M[mindex2(1,1,3)]; A[5] = M[mindex2(1,2,3)]; 
  A[6] = M[mindex2(2,0,3)]; A[7] = M[mindex2(2,1,3)]; A[8] = M[mindex2(2,2,3)]; 
  
	//mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads"); // commented by Ilya Belevich
    mexCallMATLAB(1, matlabCallOut, 1, matlabCallIn, "feature"); // feature('Numcores') added by Ilya Belevich
    Nthreadsd=mxGetPr(matlabCallOut[0]);
	Nthreads=(int)Nthreadsd[0];
    
    /* Reserve room for handles of threads in ThreadList  */
	#ifdef _WIN32
		ThreadList = (HANDLE*)malloc(Nthreads* sizeof( HANDLE ));
    #else
		ThreadList = (pthread_t*)malloc(Nthreads* sizeof( pthread_t ));
	#endif
	
	ThreadID = (double **)malloc( Nthreads* sizeof(double *) );
	ThreadArgs = (double ***)malloc( Nthreads* sizeof(double **) );
	
  
  /* Assign pointer to output. */
  Iout = mxGetPr(plhs[0]);
  
  for (i=0; i<Nthreads; i++)
  {
    /*  Make Thread ID  */
    ThreadID1= (double *)malloc( 1* sizeof(double) );
    ThreadID1[0]=i;
    ThreadID[i]=ThreadID1;  
    
	/*  Make Thread Structure  */
    ThreadArgs1 = (double **)malloc( 9* sizeof( double * ) );  
	ThreadArgs1[0]=Isize_d;
	ThreadArgs1[1]=Jsize_d;
    ThreadArgs1[2]=A;
	ThreadArgs1[3]=Iin;
	ThreadArgs1[4]=Iout;
	ThreadArgs1[5]=ThreadID[i];
	ThreadArgs1[6]=moded;
	ThreadArgs1[7]=Nthreadsd;
	
	/* Start a Thread  */
	ThreadArgs[i]=ThreadArgs1;
    if(Isize_d[2]>1) {
		#ifdef _WIN32
			ThreadList[i] = (HANDLE)_beginthreadex( NULL, 0, &transformvolume_color, ThreadArgs[i] , 0, NULL );
		#else
			pthread_create ((pthread_t*)&ThreadList[i], NULL, (void *) &transformvolume_color, ThreadArgs[i]);
		#endif
    }
    else
    {
		#ifdef _WIN32
			ThreadList[i] = (HANDLE)_beginthreadex( NULL, 0, &transformvolume_gray, ThreadArgs[i] , 0, NULL );
		#else
			pthread_create ((pthread_t*)&ThreadList[i], NULL, (void *) &transformvolume_gray, ThreadArgs[i]);
		#endif
    }
  }
   
	#ifdef _WIN32
		for (i=0; i<Nthreads; i++) { WaitForSingleObject(ThreadList[i], INFINITE); }
		for (i=0; i<Nthreads; i++) { CloseHandle( ThreadList[i] ); }
	#else
		for (i=0; i<Nthreads; i++) { pthread_join(ThreadList[i],NULL); }
	#endif


  for (i=0; i<Nthreads; i++) 
  { 
    free(ThreadArgs[i]);
    free(ThreadID[i]);
  }

  free(ThreadArgs);
  free(ThreadID );
  free(ThreadList);

}
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    /* I is the input image, Iout the transformed image  */
    /* Tx and Ty images of the translation of every pixel. */
    double *Iin, *Iout, *Tx, *Ty, *ImageSizeT;
	double *moded;
	mxArray *matlabCallOut[1]={0};
    mxArray *matlabCallIn[1]={0};
    double *Nthreadsd;
    int Nthreads;
    double *Tlocalx, *Tlocaly;
    int x,y;
    int index;
    
    /* double pointer array to store all needed function variables) */
    double ***ThreadArgs;
    double **ThreadArgs1;
    
	/* Handles to the worker threads */
		ThreadHANDLE *ThreadList;

    
    /* ID of Threads */
    double **ThreadID;              
    double *ThreadID1;

    /* Size of input image */
    const mwSize *dims;
    double Isize_d[3]={0,0,0};
    int Isize[3]={1,1,1};
    
    /* Size of output image */
    double ImageSize_d[3]={0,0,0};
    int ImageSize[3]={1,1,1};
	
	/* Loop variable  */
	int i;
	
    /* Check for proper number of arguments. */
    if(nrhs<4) {
      mexErrMsgTxt("Four inputs are required.");
    } else if(nlhs!=1) {
      mexErrMsgTxt("One output required");
    }
 
    /* Get the sizes of the image */
    dims = mxGetDimensions(prhs[0]);   
    Isize_d[0] = (double)dims[0]; Isize_d[1] = (double)dims[1]; 
    /* Detect if color image */
    if(mxGetNumberOfDimensions(prhs[0])>2) { Isize_d[2]=(double)3; } else { Isize_d[2]=1; }
    Isize[0]=(int)Isize_d[0];
    Isize[1]=(int)Isize_d[1];
    Isize[2]=(int)Isize_d[2];
     
   
    /* Assign pointers to each input. */
    Iin=mxGetPr(prhs[0]);
    Tx=mxGetPr(prhs[1]);
    Ty=mxGetPr(prhs[2]);
	moded=mxGetPr(prhs[3]);
    if(nrhs==5)
    {
      ImageSizeT=mxGetPr(prhs[4]);
    }
 
 
	if(nrhs==5)
	{
		ImageSize_d[0]=ImageSizeT[0];
		ImageSize_d[1]=ImageSizeT[1];
		ImageSize_d[2]=Isize_d[2];
	}
	else
	{
		ImageSize_d[0]= Isize_d[0];
		ImageSize_d[1]= Isize_d[1];
		ImageSize_d[2]= Isize_d[2];
	}
	ImageSize[0]=(int)ImageSize_d[0];
	ImageSize[1]=(int)ImageSize_d[1];
	ImageSize[2]=(int)ImageSize_d[2];
  
   /* Create image matrix for the return arguments with the size of input image  */  
    if(Isize_d[2]>1) {
          plhs[0] = mxCreateNumericArray(3, ImageSize, mxDOUBLE_CLASS, mxREAL);
    }
    else  {
        plhs[0] = mxCreateNumericArray(2, ImageSize, mxDOUBLE_CLASS, mxREAL);
    }

	
  
	  
    /* Assign pointer to output. */
    Iout = mxGetPr(plhs[0]);
        
    if(moded[0]==4)
    {
        Tlocalx=(double*)malloc(Isize[0]*Isize[1]*sizeof(double));
        Tlocaly=(double*)malloc(Isize[0]*Isize[1]*sizeof(double));
        for (y=0; y<Isize[1]; y++)
        {
            for (x=0; x<Isize[0]; x++)
            {
                index=mindex2(x,y,Isize[0]);
                Tlocalx[index]=((double)x)+Tx[index];
                Tlocaly[index]=((double)y)+Ty[index];
            }
        }
    
        interpolate_forward_2d_double(Iin, Tlocalx, Tlocaly, Isize, ImageSize, Iout);
        
        free(Tlocalx);
        free(Tlocaly);
    
    }
    else
    {   
        mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads");
        Nthreadsd=mxGetPr(matlabCallOut[0]);
        Nthreads=(int)Nthreadsd[0];
        /* Reserve room for handles of threads in ThreadList  */
            ThreadList = (ThreadHANDLE*)malloc(Nthreads* sizeof( ThreadHANDLE ));

        ThreadID = (double **)malloc( Nthreads* sizeof(double *) );
        ThreadArgs = (double ***)malloc( Nthreads* sizeof(double **) );


      for (i=0; i<Nthreads; i++)
      {
        /*  Make Thread ID  */
        ThreadID1= (double *)malloc( 1* sizeof(double) );
        ThreadID1[0]=i;
        ThreadID[i]=ThreadID1;  

        /*  Make Thread Structure  */
        ThreadArgs1 = (double **)malloc( 9* sizeof( double * ) );  
        ThreadArgs1[0]=Iin;
        ThreadArgs1[1]=Iout;
        ThreadArgs1[2]=Tx;
        ThreadArgs1[3]=Ty;
        ThreadArgs1[4]=Isize_d;
        ThreadArgs1[5]=ThreadID[i];
        ThreadArgs1[6]=moded;
        ThreadArgs1[7]=Nthreadsd;
		ThreadArgs1[8]=ImageSize_d;
		

        ThreadArgs[i]=ThreadArgs1;
        if(Isize_d[2]>1) {
            StartThread(ThreadList[i], &transformvolume_color, ThreadArgs[i])
        }
        else
        {
            StartThread(ThreadList[i], &transformvolume_gray, ThreadArgs[i])
        }
      }

        for (i=0; i<Nthreads; i++) { WaitForThreadFinish(ThreadList[i]); }


      for (i=0; i<Nthreads; i++) 
      { 
        free(ThreadArgs[i]);
        free(ThreadID[i]);
      }

      free(ThreadArgs);
      free(ThreadID );
      free(ThreadList);
    }
}
voidthread transformvolume_color(double **Args) {

    /* I is the input image, Iout the transformed image  */
    /* Tx and Ty images of the translation of every pixel. */
    double *Iin, *Iout, *Tx, *Ty;
    double *Nthreadsd;
    int Nthreads;
	/*  if one outside pixels are set to zero. */
	double  *moded;
	int mode=0;
	
	/* Output image size */
    double *ImageSize_d;
    int ImageSize[3];
	
    /* 2D index storage */
    int indexI;
    
    /* Size of input image */
    int Isize[3]={0,0,0};
    double *Isize_d;
    
    /* Location of translated pixel */
    double Tlocalx;
    double Tlocaly;
    
    /* Cubic and outside black booleans */
    bool black, cubic;

    /* loop throught the colors r,g,b */
    int rgb=0;
    
    /* Current voxel/pixel */
    double Ipixel[3]={0,0,0};
    
    /* offset */
    int offset=0;
    
    /* The thread ID number/name */
    double *ThreadID;
    
    /* X,Y coordinates of current pixel */
    int x,y;
    
    Iin=Args[0];
    Iout=Args[1];
    Tx=Args[2];
    Ty=Args[3];
    Isize_d=Args[4];
    ThreadID=Args[5];
	moded=Args[6]; mode=(int) moded[0];
    Nthreadsd=Args[7];  Nthreads=(int)Nthreadsd[0];
	ImageSize_d=Args[8];
		
    if(mode==0||mode==2){ black = false; } else { black = true; }
    if(mode==0||mode==1){ cubic = false; } else { cubic = true; }
    
    Isize[0]=(int)Isize_d[0];
    Isize[1]=(int)Isize_d[1];
    Isize[2]=(int)Isize_d[2];
        
	ImageSize[0] = (int)ImageSize_d[0]; 
    ImageSize[1] = (int)ImageSize_d[1]; 
    ImageSize[2] = (int)ImageSize_d[2]; 
	
    offset=(int) ThreadID[0];
	
    /*  Loop through all image pixel coordinates */
    for (y=offset; y<ImageSize[1]; y=y+Nthreads)
    {
        for (x=0; x<ImageSize[0]; x++)
        {
		    indexI=mindex2(x,y,ImageSize[0]);
            Tlocalx=((double)x)+Tx[indexI];
            Tlocaly=((double)y)+Ty[indexI];
            
            /* interpolate the intensities */
            interpolate_2d_double_color(Ipixel,Tlocalx, Tlocaly, Isize, Iin,cubic,black);
         
            /* Set the current pixel value */
   
            for (rgb=0; rgb<3; rgb++)
            {
                Iout[indexI+rgb*ImageSize[0]*ImageSize[1]]=Ipixel[rgb];
            }
        }
    }

    /*  explicit end thread, helps to ensure proper recovery of resources allocated for the thread */
	EndThread;
}
unsigned __stdcall  transformvolume(double **Args)
{
    double *Isize_d, *mean_in, *A, *Iin, *Iout, *ThreadID;
	double *ImageSize_d, *check_bil_intp;
	double mean_out[2]={0,0};
	int bilintp=0;
    int Isize[2]={0,0};
	int ImageSize[2]={0,0};
	
    int x,y;
	double *Nthreadsd;
    int Nthreads;

    // Location of pixel which will be come the current pixel
    double Tlocalx;
    double Tlocaly;
    
    // Linear interpolation variables
    int xBas[4], yBas[4];
    double perc[4]={0,0,0,0};
    double xCom, yCom;
    double color[4]={0,0,0,0};
    
    // Color offsets;
    int offset_out[3]={0,0,0};
    int offset_in[3]={0,0,0};
    
    // X,Y,Z coordinates of current pixel
    double xd,yd;

    // Variables to store 1D index
    int indexI;
    int indexI1, indexI2, indexI3, indexI4;
    
    // Multiple threads, one does the odd the other even indexes
    int offset;
    //int start;
    //int end;
    
    // Loop through all colors r,g,b or only gray
    int c;
    
    
    Isize_d=Args[0];
    mean_in=Args[1];
    A=Args[2];
    Iin=Args[3];
    Iout=Args[4];
    ThreadID=Args[5];
	ImageSize_d=Args[6];
	check_bil_intp=Args[7]; bilintp=(int)check_bil_intp[0];
	Nthreadsd=Args[8];  Nthreads=(int)Nthreadsd[0];
   
      /* Center of the output image */
	mean_out[0]=ImageSize_d[0]/2;  mean_out[1]=ImageSize_d[1]/2;  
  
    ImageSize[0] = (int)ImageSize_d[0]; 
    ImageSize[1] = (int)ImageSize_d[1]; 
    
	Isize[0] = (int)Isize_d[0]; 
    Isize[1] = (int)Isize_d[1]; 
    Isize[2] = (int)Isize_d[2]; 
    
    offset=(int) ThreadID[0];
	
    offset_out[0]=0;
    offset_in[0]=0;
    offset_out[1]=ImageSize[0]*ImageSize[1];
    offset_in[1]=Isize[0]*Isize[1];
    offset_out[2]=2*ImageSize[0]*ImageSize[1];
    offset_in[2]=2*Isize[0]*Isize[1];
             
    // Loop through all image pixel coordinates
    for (y=offset; y<ImageSize[1]; y=y+Nthreads)
    {
        for (x=0; x<ImageSize[0]; x++)
        {
            xd=(double)x-mean_out[0]; yd=(double)y-mean_out[1];

            Tlocalx = mean_in[0] + A[0] * xd + A[1] *yd + A[2] * 1;
            Tlocaly = mean_in[1] + A[3] * xd + A[4] *yd + A[5] * 1;

			if(bilintp>0)
			{
				// Determine the coordinates of the pixel(s) which will be come the current pixel
				// (using linear interpolation)  
				xBas[0]=(int) floor(Tlocalx); yBas[0]=(int) floor(Tlocaly);
				xBas[1]=xBas[0]+0;      yBas[1]=yBas[0]+1;
				xBas[2]=xBas[0]+1;      yBas[2]=yBas[0]+0;
				xBas[3]=xBas[0]+1;      yBas[3]=yBas[0]+1;

				
                // Linear interpolation constants (percentages)
				xCom=Tlocalx-floor(Tlocalx); yCom=Tlocaly-floor(Tlocaly);
				perc[0]=(1-xCom) * (1-yCom);
				perc[1]=(1-xCom) * yCom;
				perc[2]=xCom * (1-yCom);
				perc[3]=xCom * yCom;

                indexI1=mindex2c(xBas[0],yBas[0],Isize[0],Isize[1],perc,0);
                indexI2=mindex2c(xBas[1],yBas[1],Isize[0],Isize[1],perc,1);
                indexI3=mindex2c(xBas[2],yBas[2],Isize[0],Isize[1],perc,2);
                indexI4=mindex2c(xBas[3],yBas[3],Isize[0],Isize[1],perc,3);
    
                // Get index current pixel value
				indexI=mindex2(x,y,ImageSize[0],ImageSize[1]);

                for(c=0; c<Isize[2]; c++)
                {
                    color[0]=Iin[indexI1+offset_in[c]]; 
                    color[1]=Iin[indexI2+offset_in[c]];
                    color[2]=Iin[indexI3+offset_in[c]];
                    color[3]=Iin[indexI4+offset_in[c]];
                    Iout[indexI+offset_out[c]]=color[0]*perc[0]+color[1]*perc[1]+color[2]*perc[2]+color[3]*perc[3];
                }
			}
			else
            {  
                // Get index current pixel value
				indexI=mindex2(x,y,ImageSize[0],ImageSize[1]);
                perc[0]=1;
                indexI1=mindex2c((int) floor(Tlocalx+0.5),(int) floor(Tlocaly+0.5),Isize[0],Isize[1],perc,0);
                for(c=0; c<Isize[2]; c++)
                {
                    Iout[indexI+offset_out[c]]=Iin[indexI1+offset_in[c]]*perc[0];
                }
			}
        }
    }
   
    // explicit end thread, helps to ensure proper recovery of resources allocated for the thread
    _endthreadex( 0 );
    return 0;
    
}
Exemplo n.º 10
0
// The matlab mex function
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    // Ox and Oy are the grid points
    // Zo is the input image
    // Zi is the transformed image
    // nx and ny are the number of grid points (inside the image)
    double *Iin, *Iout, *M, *ImageSize, *check_bil_intp;
    mxArray *matlabCallOut[1]={0};
    mxArray *matlabCallIn[1]={0};
    double *Nthreadsd;
    int Nthreads;
	
    // double pointer array to store all needed function variables
    double ***ThreadArgs;
    double **ThreadArgs1;
    
    HANDLE *ThreadList; // Handles to the worker threads
    
    // ID of Threads
    double **ThreadID;              
    double *ThreadID1;
    
    // Transformation matrix
    double A[9]={0,0,0,0,0,0,0,0,0};

    // Loop variable
    int i;
    
    // Size of input image
    double Isize_d[3]={0,0,0};
    const mwSize *dims;
	mwSize dims_out3[3]={0,0,0};
    
    mwSize dimnum;
    
    double mean_in[2]={0,0};

  /* Check for proper number of arguments. */
  if(nrhs!=4) {
    mexErrMsgTxt("Four inputs are required.");
  } else if(nlhs!=1) {
    mexErrMsgTxt("One output required");
  }
  // nsubs=mxGetNumberOfDimensions(prhs[0]);
     
  // Get the sizes of the image
  dimnum=mxGetNumberOfDimensions(prhs[0]);
    
  dims = mxGetDimensions(prhs[0]);   
  Isize_d[0] = (double)dims[0]; Isize_d[1] = (double)dims[1]; 
  if(dimnum>2) 
  { 
      Isize_d[2] = (double)dims[2];
  } 
  else 
  { 
      Isize_d[2]=1; 
  }
          
  /* Assign pointers to each input. */
  Iin=mxGetPr(prhs[0]);
  M=mxGetPr(prhs[1]);
  ImageSize=mxGetPr(prhs[2]);
  check_bil_intp=mxGetPr(prhs[3]);

  dims_out3[0]=(mwSize)ImageSize[0]; dims_out3[1]=(mwSize)ImageSize[1]; dims_out3[2]=(mwSize)Isize_d[2];
  plhs[0] = mxCreateNumericArray(3, dims_out3, mxDOUBLE_CLASS, mxREAL);
 
  A[0] = M[mindex2(0,0,3,3)]; A[1] = M[mindex2(0,1,3,3)]; A[2] = M[mindex2(0,2,3,3)]; 
  A[3] = M[mindex2(1,0,3,3)]; A[4] = M[mindex2(1,1,3,3)]; A[5] = M[mindex2(1,2,3,3)]; 
  A[6] = M[mindex2(2,0,3,3)]; A[7] = M[mindex2(2,1,3,3)]; A[8] = M[mindex2(2,2,3,3)]; 
  
	mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads");
	Nthreadsd=mxGetPr(matlabCallOut[0]);
	Nthreads=(int)Nthreadsd[0];
	// Reserve room for handles of threads in ThreadList
	ThreadList = (HANDLE*)malloc(Nthreads* sizeof( HANDLE ));
	ThreadID = (double **)malloc( Nthreads* sizeof(double *) );
	ThreadArgs = (double ***)malloc( Nthreads* sizeof(double **) );
	
  
  /* Assign pointer to output. */
  Iout = mxGetPr(plhs[0]);
  
  /* Center of the volume */
  mean_in[0]=Isize_d[0]/2;  mean_in[1]=Isize_d[1]/2;  
   
  for (i=0; i<Nthreads; i++)
  {
    // Make Thread ID
    ThreadID1= (double *)malloc( 1* sizeof(double) );
    ThreadID1[0]=i;
    ThreadID[i]=ThreadID1;  
    
	// Make Thread Structure
    ThreadArgs1 = (double **)malloc( 8* sizeof( double * ) );  
	ThreadArgs1[0]=Isize_d;
	ThreadArgs1[1]=mean_in;
	ThreadArgs1[2]=A;
	ThreadArgs1[3]=Iin;
	ThreadArgs1[4]=Iout;
	ThreadArgs1[5]=ThreadID[i];
	ThreadArgs1[6]=ImageSize;
	ThreadArgs1[7]=check_bil_intp;
	ThreadArgs1[8]=Nthreadsd;
    // Start a Thread 
	ThreadArgs[i]=ThreadArgs1;
    ThreadList[i] = (HANDLE)_beginthreadex( NULL, 0, &transformvolume, ThreadArgs[i] , 0, NULL );
  }
   
  for (i=0; i<Nthreads; i++) { WaitForSingleObject(ThreadList[i], INFINITE); }
  for (i=0; i<Nthreads; i++) { CloseHandle( ThreadList[i] ); }


  for (i=0; i<Nthreads; i++) 
  { 
    free(ThreadArgs[i]);
    free(ThreadID[i]);
  }

  free(ThreadArgs);
  free(ThreadID );
  free(ThreadList);

}
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    /* Ox and Oy are the grid points */
    /* Zo is the input image */
    /* Zi is the transformed image */

    /* nx and ny are the number of grid points (inside the image) */
    double *Ox,*Oy,*Oz,*I1,*I2,*dxa, *dya,*dza, *E, *Egradient, *ThreadOut;
    mxArray *matlabCallOut[1]={0};
    mxArray *matlabCallIn[1]={0};
    double *Nthreadsd;
    int Nthreads;
	/* Finite difference step size */
	double step=0.01;
	/* index offsets */
	int offset1, offset2, offset3;
	/* Dims outputs */
	const int dims_error[2]={1,1};
	int dims_error_gradient[4]={1,1,1,3};
	/* double pointer array to store all needed function variables) */
    double ***ThreadArgs;
    double **ThreadArgs1;
    /* Handles to the worker threads */
		ThreadHANDLE *ThreadList;
    
    /* ID of Threads */
    double **ThreadID;              
    double *ThreadID1;
    
    /* Size of input image */
    mwSize  Isizex, Isizey, Isizez;
    double Isize_d[3]={0,0,0};
    const mwSize *dims;

    /* Size of grid */
    mwSize  Osizex, Osizey, Osizez;
	int Onumel;
    double Osize_d[3]={0,0,0};
   
    /* B-spline variablesl */
    double u,v,w;
    int u_index=0; 
    int v_index=0;
    int w_index=0;
    
    double *Bu, *Bv, *Bw;
    
    /* Loop variables  */
    int i,j;
	/* Grid distance */
    int dx,dy,dz; 
    /* X,Y,Z coordinates of current pixel */
    int x,y,z;
        
  /* Check for proper number of arguments. */
  if(nrhs!=8) {
    mexErrMsgTxt("Eight inputs are required.");
  }
 
  /* Get the sizes of the grid */
  dims = mxGetDimensions(prhs[0]);   
  Osizex = dims[0]; 
  Osizey = dims[1];
  Osizez = dims[2];
  Onumel = Osizex*Osizey*Osizez;
   
  /* Create image matrix for the return arguments with the size of input image  */  
  dims = mxGetDimensions(prhs[3]);  
  Isizex = dims[0]; 
  Isizey = dims[1];
  Isizez = dims[2];
  
  /* Create image matrix for the Error return argument  */  
  plhs[0] = mxCreateNumericArray(2, dims_error, mxDOUBLE_CLASS, mxREAL);
  if(nlhs>1) 
  {
    dims_error_gradient[0]=Osizex; dims_error_gradient[1]=Osizey; dims_error_gradient[2]=Osizez;
    /* Error Gradient needed */
	plhs[1] = mxCreateNumericArray(4, dims_error_gradient, mxDOUBLE_CLASS, mxREAL);
  }
  
  /* Assign pointers to each input. */
  Ox=(double *)mxGetData(prhs[0]);
  Oy=(double *)mxGetData(prhs[1]);
  Oz=(double *)mxGetData(prhs[2]);
  I1=(double *)mxGetData(prhs[3]);
  I2=(double *)mxGetData(prhs[4]);
  dxa=(double *)mxGetData(prhs[5]);
  dya=(double *)mxGetData(prhs[6]);
  dza=(double *)mxGetData(prhs[7]);
   
  /* Get the spacing of the uniform b-spline grid */
  dx=(int)dxa[0]; dy=(int)dya[0]; dz=(int)dza[0]; 
  
  /* Get number of allowed threads */
  mexCallMATLAB(1, matlabCallOut, 0, matlabCallIn, "maxNumCompThreads");
  Nthreadsd=mxGetPr(matlabCallOut[0]);
  Nthreads=(int)Nthreadsd[0];
  
    /* Reserve room for handles of threads in ThreadList  */
		ThreadList = (ThreadHANDLE*)malloc(Nthreads* sizeof( ThreadHANDLE ));

  ThreadID = (double **)malloc( Nthreads* sizeof(double *) );
  ThreadArgs = (double ***)malloc( Nthreads* sizeof(double **) );
  if(nlhs==1){	ThreadOut = (double *)malloc(Nthreads* sizeof(double) ); }
  else { ThreadOut = (double *)malloc(Nthreads*(1+Onumel*3)*sizeof(double) );  }

  /* Assign pointer to output. */
  E = mxGetPr(plhs[0]);
  if(nlhs>1) { Egradient = mxGetPr(plhs[1]); }
  
   /*  Make polynomial look up tables   */
  Bu=malloc(dx*4*sizeof(double));
  Bv=malloc(dy*4*sizeof(double));
  Bw=malloc(dz*4*sizeof(double));
  for (x=0; x<dx; x++)
  {
    u=((double)x/(double)dx)-floor((double)x/(double)dx);
    Bu[mindex2(0,x,4)] = (double)pow((1-u),3)/6;
    Bu[mindex2(1,x,4)] = (double)( 3*pow(u,3) - 6*pow(u,2) + 4)/6;
    Bu[mindex2(2,x,4)] = (double)(-3*pow(u,3) + 3*pow(u,2) + 3*u + 1)/6;
    Bu[mindex2(3,x,4)] = (double)pow(u,3)/6;
  }
  
  for (y=0; y<dy; y++)
  {
    v=((double)y/(double)dy)-floor((double)y/(double)dy);
    Bv[mindex2(0,y,4)] = (double)pow((1-v),3)/6;
    Bv[mindex2(1,y,4)] = (double)( 3*pow(v,3) - 6*pow(v,2) + 4)/6;
    Bv[mindex2(2,y,4)] = (double)(-3*pow(v,3) + 3*pow(v,2) + 3*v + 1)/6;
    Bv[mindex2(3,y,4)] = (double)pow(v,3)/6;
  }

  for (z=0; z<dz; z++)
  {
    w=((double)z/(double)dz)-floor((double)z/(double)dz);
    Bw[mindex2(0,z,4)] = (double)pow((1-w),3)/6;
    Bw[mindex2(1,z,4)] = (double)( 3*pow(w,3) - 6*pow(w,2) + 4)/6;
    Bw[mindex2(2,z,4)] = (double)(-3*pow(w,3) + 3*pow(w,2) + 3*w + 1)/6;
    Bw[mindex2(3,z,4)] = (double)pow(w,3)/6;
  }

  Isize_d[0]=(double)Isizex;  Isize_d[1]=(double)Isizey; Isize_d[2]=(double)Isizez;
  Osize_d[0]=(double)Osizex;  Osize_d[1]=(double)Osizey; Osize_d[2]=(double)Osizez;
  
 /* Reserve room for 16 function variables(arrays)   */
  for (i=0; i<Nthreads; i++)
  {
    /*  Make Thread ID  */
    ThreadID1= (double *)malloc( 1* sizeof(double) );
    ThreadID1[0]=(double)i;
    ThreadID[i]=ThreadID1;  
	
    /*  Make Thread Structure  */
    ThreadArgs1 = (double **)malloc( 16 * sizeof( double * ) );  
    ThreadArgs1[0]=Bu;
    ThreadArgs1[1]=Bv;
	ThreadArgs1[2]=Bw;
	ThreadArgs1[3]=Isize_d;
    ThreadArgs1[4]=Osize_d;
    ThreadArgs1[5]=ThreadOut;
    ThreadArgs1[6]=dxa;
    ThreadArgs1[7]=dya;
    ThreadArgs1[8]=dza;
    ThreadArgs1[9]=ThreadID[i];
    ThreadArgs1[10]=Ox;
    ThreadArgs1[11]=Oy;
	ThreadArgs1[12]=Oz;
	ThreadArgs1[13]=I1;
	ThreadArgs1[14]=I2;
	ThreadArgs1[15]=Nthreadsd;
    ThreadArgs[i]=ThreadArgs1;
       

		if(nlhs==1){
		   StartThread(ThreadList[i], &transformvolume_error, ThreadArgs[i])
		}
		else{
			StartThread(ThreadList[i], &transformvolume_gradient, ThreadArgs[i])
		}
  }
  
 for (i=0; i<Nthreads; i++) { WaitForThreadFinish(ThreadList[i]); }


  /* Add accumlated error of all threads */
  E[0]=0; for (i=0; i<Nthreads; i++) { E[0]+=ThreadOut[i]; } E[0]/=Nthreads;

  if(nlhs>1)
  {
		for (i=0; i<Nthreads; i++) 
		{ 
			offset1=i*(3*Onumel);
            offset2=offset1+Onumel;
			offset3=offset2+Onumel;
			for(j=0; j<Onumel; j++)
			{
				Egradient[j]+=ThreadOut[Nthreads+j+offset1]/step;
				Egradient[j+Onumel]+=ThreadOut[Nthreads+j+offset2]/step;
				Egradient[j+2*Onumel]+=ThreadOut[Nthreads+j+offset3]/step;
			}
		}
        for(j=0; j<3*Onumel; j++)
    	{
            Egradient[j]/=Nthreads;
        }
  }
  
  for (i=0; i<Nthreads; i++) 
  { 
    free(ThreadArgs[i]);
    free(ThreadID[i]);
  }

  free(ThreadArgs);
  free(ThreadID );
  free(ThreadList);
  
  free(Bu);
  free(Bv);
  free(Bw);
  
}
Exemplo n.º 12
0
// The matlab mex function
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) {
    // Ox and Oy are the grid points
    // Zo is the input image
    // Zi is the transformed image
    // nx and ny are the number of grid points (inside the image)
    double *Iin, *x1, *y1, *x2, *y2, *steps, *Iout;
    
    double Pi=3.14159265358979323846;
    
    // Dimensions of in and outputs
    const mwSize *Iin_dims;
    const mwSize *x1_dims;
    mwSize Iout_dims[3]={1, 1, 1};
    
    // Center of the image
    double center[2]={0, 0};
    
    // Position of current pixel
    double Tlocalx, Tlocaly;
    double current_angle=0;
    
    // Floor of coordinate
    double fTlocalx, fTlocaly;
    // Zero neighbor
    int xBas0, yBas0;
    // The location in between the pixels 0..1
    double tx, ty;
    // Neighbor loccations
    int xn[4], yn[4];
    
    // The vectors
    double vector_tx[4], vector_ty[4];
    double vector_qx[4]; //={0.25,0.25,0.25,0.25};
    double vector_qy[4]; //={0.25,0.25,0.25,0.25};
    double vector_b[4];
    // Interpolated Intensity;
    double Ipixel=0;
    // Temporary value boundary
    int b;
    
    // Percentage pixel position between center and outer position
    double perc=0;
    
    // Loop variables
    int i, j, k,l;
    
    // 2D to 1D index
    int index, indexoff1, indexoff2;
    
    /* Check for proper number of arguments. */
    if(nrhs!=6) {
        mexErrMsgTxt("6 inputs are required.");
    } else if(nlhs!=1) {
        mexErrMsgTxt("One output required");
    }
    
    
    // Get the sizes of the image
    Iin_dims = mxGetDimensions(prhs[0]);
    
    // Get the sizes of the position vectors
    x1_dims = mxGetDimensions(prhs[1]);
    
    /* Assign pointers to input. */
    Iin=mxGetPr(prhs[0]);
    x1=mxGetPr(prhs[1]);
    y1=mxGetPr(prhs[2]);
    x2=mxGetPr(prhs[3]);
    y2=mxGetPr(prhs[4]);
    steps=mxGetPr(prhs[5]);
    
    
    
    Iout_dims[0]=(int)steps[0];
    Iout_dims[1]=(int)x1_dims[0];
    
    // Make output array
    if(mxGetNumberOfDimensions(prhs[0])>2) {
        Iout_dims[2]=Iin_dims[2];
    }
    plhs[0] = mxCreateNumericArray(3, Iout_dims, mxDOUBLE_CLASS, mxREAL);
    
    /* Assign pointer to output. */
    Iout = mxGetPr(plhs[0]);
    
    
    // Loop through all positions
    for (i=0; i<(int)x1_dims[0]; i++) {
        for (j=0; j<(int)steps[0]; j++) {
            perc=((double)j)/steps[0];
            Tlocalx=x1[i]*(1-perc)+x2[i]*perc;
            Tlocaly=y1[i]*(1-perc)+y2[i]*perc;
            
            // Determine of the zero neighbor
            fTlocalx = floor(Tlocalx); fTlocaly = floor(Tlocaly);
            xBas0=(int) fTlocalx; yBas0=(int) fTlocaly;
            
            // Determine the location in between the pixels 0..1
            tx=Tlocalx-fTlocalx; ty=Tlocaly-fTlocaly;
            
            // Determine the t vectors
            vector_tx[0]= 0.5; vector_tx[1]= 0.5*tx; vector_tx[2]= 0.5*pow2(tx); vector_tx[3]= 0.5*pow3(tx);
            vector_ty[0]= 0.5; vector_ty[1]= 0.5*ty; vector_ty[2]= 0.5*pow2(ty); vector_ty[3]= 0.5*pow3(ty);
            
            // t vector multiplied with 4x4 bicubic kernel gives the to q vectors
            vector_qx[0]= -1.0*vector_tx[1]+2.0*vector_tx[2]-1.0*vector_tx[3];
            vector_qx[1]= 2.0*vector_tx[0]-5.0*vector_tx[2]+3.0*vector_tx[3];
            vector_qx[2]= 1.0*vector_tx[1]+4.0*vector_tx[2]-3.0*vector_tx[3];
            vector_qx[3]= -1.0*vector_tx[2]+1.0*vector_tx[3];
            vector_qy[0]= -1.0*vector_ty[1]+2.0*vector_ty[2]-1.0*vector_ty[3];
            vector_qy[1]= 2.0*vector_ty[0]-5.0*vector_ty[2]+3.0*vector_ty[3];
            vector_qy[2]= 1.0*vector_ty[1]+4.0*vector_ty[2]-3.0*vector_ty[3];
            vector_qy[3]= -1.0*vector_ty[2]+1.0*vector_ty[3];
            
            // Determine 1D neighbour coordinates
            xn[0]=xBas0-1; xn[1]=xBas0; xn[2]=xBas0+1; xn[3]=xBas0+2;
            yn[0]=yBas0-1; yn[1]=yBas0; yn[2]=yBas0+1; yn[3]=yBas0+2;
            
            // Clamp to image boundary if outside image
            if(xn[0]<0) { xn[0]=0;if(xn[1]<0) { xn[1]=0;if(xn[2]<0) { xn[2]=0; if(xn[3]<0) { xn[3]=0; }}}}
            if(yn[0]<0) { yn[0]=0;if(yn[1]<0) { yn[1]=0;if(yn[2]<0) { yn[2]=0; if(yn[3]<0) { yn[3]=0; }}}}
            b=Iin_dims[0]-1;
            if(xn[3]>b) { xn[3]=b;if(xn[2]>b) { xn[2]=b;if(xn[1]>b) { xn[1]=b; if(xn[0]>b) { xn[0]=b; }}}}
            b=Iin_dims[1]-1;
            if(yn[3]>b) { yn[3]=b;if(yn[2]>b) { yn[2]=b;if(yn[1]>b) { yn[1]=b; if(yn[0]>b) { yn[0]=b; }}}}
            
            // First do interpolation in the x direction followed by interpolation in the y direction
            index=mindex2(j, i, Iout_dims[0], Iout_dims[1]);
            for (k=0; k<Iout_dims[2]; k++) {
                indexoff1=k*Iout_dims[0]*Iout_dims[1];
                indexoff2=k*Iin_dims[0]*Iin_dims[1];
                Iout[index+indexoff1]=0;
                for(l=0; l<4; l++) {
                    vector_b[l] =vector_qx[0]*Iin[xn[0]+yn[l]*Iin_dims[0]+indexoff2];
                    vector_b[l]+=vector_qx[1]*Iin[xn[1]+yn[l]*Iin_dims[0]+indexoff2];
                    vector_b[l]+=vector_qx[2]*Iin[xn[2]+yn[l]*Iin_dims[0]+indexoff2];
                    vector_b[l]+=vector_qx[3]*Iin[xn[3]+yn[l]*Iin_dims[0]+indexoff2];
                    Iout[index+indexoff1]+= vector_qy[l]*vector_b[l];
                }
            }
            
        }
    }
}
/* The matlab mex function */
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
    double *Fx, *Fy, *Bx, *By, *H, *Num;
    
    /*  Size of input transformation fields */
    mwSize  Bsizex, Bsizey;
    const mwSize *Bdims;

    /* Size of the input kernel */
    mwSize  Hsizex, Hsizey;
    const mwSize *Hdims;
    int hx_center,  hy_center;
     
    /* Variables to store 1D index */
    int index;

    /* Variable to store vector */
    double valx, valy;
    
    /* Loop variable  */
    int i, t, iHx, iHy;
        
    /*  Linear interpolation variables */
    int xBas0, xBas1,yBas0,yBas1;
    double perc[4], perct;
    double xCom, yCom;
    double Tlocalx, Tlocaly;
    
    /* X,Y coordinates of current pixel */
    int x,y, tx, ty;
    
    /* Check for proper number of arguments. */
    if(nrhs!=3) {
        mexErrMsgTxt("Three inputs are required.");
    } else if(nlhs!=2) {
        mexErrMsgTxt("Two outputs are required");
    }
  
  /* Assign pointers to each input. */
  Bx=mxGetPr(prhs[0]);
  By=mxGetPr(prhs[1]);
  H=mxGetPr(prhs[2]);
 
  /* Get the sizes of the kernel  */
  Hdims = mxGetDimensions(prhs[2]);   
  Hsizex = Hdims[0]; Hsizey = Hdims[1];
  
  /* Get the sizes of the input transformation fields  */
  Bdims = mxGetDimensions(prhs[0]);   
  Bsizex = Bdims[0]; Bsizey = Bdims[1];

  /* Create array to count number of kernels added  */
  Num = (double *)malloc(Bsizex*Bsizey*sizeof(double));  
  for (i=0; i<(Bsizex*Bsizey); i++){ Num[i] = 0;}    

  /* Create output array */
  plhs[0] = mxCreateNumericArray(2, Bdims, mxDOUBLE_CLASS, mxREAL);
  plhs[1] = mxCreateNumericArray(2, Bdims, mxDOUBLE_CLASS, mxREAL);

  /* Assign pointer to output. */
  Fx = mxGetPr(plhs[0]);
  Fy = mxGetPr(plhs[1]);

  
  /* Gaussian kernel center */
  hx_center=(int)-floor((double)Hsizex/2); 
  hy_center=(int)-floor((double)Hsizey/2); 
  
  /*  Loop through all image pixel coordinates */
  for (y=0; y<Bsizey; y++)
  {
    for (x=0; x<Bsizex; x++)
    {
        valx=-Bx[mindex2(x,y,Bsizex)];
        valy=-By[mindex2(x,y,Bsizex)];
        Tlocalx =x-valx;
        Tlocaly =y-valy;
   
        /* 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);
        xBas1=xBas0+1;      
        yBas1=yBas0+1;

        /* Linear interpolation constants (percentages) */
        xCom=Tlocalx-floor(Tlocalx); yCom=Tlocaly-floor(Tlocaly);
        perc[0]=(1-xCom) * (1-yCom);
        perc[1]=(1-xCom) * yCom;
        perc[2]=xCom * (1-yCom);
        perc[3]=xCom * yCom;
        
        /*  Loop through the whole kernel */
        for (iHy=0; iHy<Hsizey; iHy++)
        {
            for (iHx=0; iHx<Hsizex; iHx++)
            {
                /*  Process all 4 neighbors */             
                for(t=0; t<4; t++)
                {
                   if(t==0){
                        tx=xBas0+iHx+hx_center; ty=yBas0+iHy+hy_center; 
                        perct=perc[0]*H[mindex2(iHx,iHy,Hsizex)];
                   }
                   else if(t==1){
                        tx=xBas0+iHx+hx_center; ty=yBas1+iHy+hy_center; 
                        perct=perc[1]*H[mindex2(iHx,iHy,Hsizex)];
                   }
                   else if(t==2){
                        tx=xBas1+iHx+hx_center; ty=yBas0+iHy+hy_center; 
                        perct=perc[2]*H[mindex2(iHx,iHy,Hsizex)];
                   }
                   else{
                        tx=xBas1+iHx+hx_center; ty=yBas1+iHy+hy_center; 
                        perct=perc[3]*H[mindex2(iHx,iHy,Hsizex)];
                   }
                   if((tx>=0)&&(ty>=0)&&(tx<Bsizex)&&(ty<Bsizey))
                   {
                        index=mindex2(tx,ty,Bsizex);
                        Fx[index]+=valx*perct; 
                        Fy[index]+=valy*perct;
                        Num[index]=Num[index]+perct;
                   }
               }
                
            }
        }
    }
  }
  for (y=0; y<Bsizey; y++)
  {
      for (x=0; x<Bsizex; x++)
      {
        index=mindex2(x,y,Bsizex);
        Fx[index]/=(Num[index]+0.00000001); 
        Fy[index]/=(Num[index]+0.00000001);
      }
  }
  free(Num);
}