/* The matlab mex function */ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { double *I, *p_in, *I_template, *Wn; double *p_out, *I_roi, *T_error; double *OptionsField; const mwSize *dimsI, *dimsT, *dimsP; mwSize dimsE[2]={1, 1}; int field_num; int sizeI[2]; int sizeT[2]; struct options Options; /* Check inputs */ /* [p,I_roi,T_error]=LucasKanadeInverseAffine(I,p,I_template,Options) */ /* Check number of inputs */ if(nrhs<3) { mexErrMsgTxt("3 or 4 input variables required."); } /* Check properties of image I */ if(mxGetNumberOfDimensions(prhs[0])!=2) { mexErrMsgTxt("Image must be 2D"); } if(!mxIsDouble(prhs[0])){ mexErrMsgTxt("Image must be double"); } dimsI = mxGetDimensions(prhs[0]); sizeI[0]=dimsI[0]; sizeI[1]=dimsI[1]; /* Check properties of affine parameters */ if(!mxIsDouble(prhs[1])){ mexErrMsgTxt("Parameters must be double"); } dimsP = mxGetDimensions(prhs[1]); if( mxGetNumberOfElements(prhs[1])!=6) { mexErrMsgTxt("Length of Parameters variable must be 6"); } /* Check properties of template image */ if(mxGetNumberOfDimensions(prhs[2])!=2) { mexErrMsgTxt("Template must be 2D"); } if(!mxIsDouble(prhs[2])){ mexErrMsgTxt("Template must be double"); } dimsT = mxGetDimensions(prhs[2]); sizeT[0]=dimsT[0]; sizeT[1]=dimsT[1]; /* Check properties of Weight matrix */ if(!mxIsDouble(prhs[3])){ mexErrMsgTxt("Weights must be double"); } if( mxGetNumberOfElements(prhs[2])!=mxGetNumberOfElements(prhs[3])) { mexErrMsgTxt("Weight matrix must be same size as image"); } /* Check options */ setdefaultoptions(&Options); if(nrhs==5) { if(!mxIsStruct(prhs[4])){ mexErrMsgTxt("Options must be structure"); } field_num = mxGetFieldNumber(prhs[4], "Padding"); if(field_num>=0) { OptionsField=mxGetPr(mxGetFieldByNumber(prhs[4], 0, field_num)); Options.Padding=(int)OptionsField[0]; } field_num = mxGetFieldNumber(prhs[4], "TranslationIterations"); if(field_num>=0) { OptionsField=mxGetPr(mxGetFieldByNumber(prhs[4], 0, field_num)); Options.TranslationIterations=(int)OptionsField[0]; } field_num = mxGetFieldNumber(prhs[4], "AffineIterations"); if(field_num>=0) { OptionsField=mxGetPr(mxGetFieldByNumber(prhs[4], 0, field_num)); Options.AffineIterations=(int)OptionsField[0]; } field_num = mxGetFieldNumber(prhs[4], "TolP"); if(field_num>=0) { OptionsField=mxGetPr(mxGetFieldByNumber(prhs[4], 0, field_num)); Options.TolP=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[4], "RoughSigma"); if(field_num>=0) { OptionsField=mxGetPr(mxGetFieldByNumber(prhs[4], 0, field_num)); Options.RoughSigma=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[4], "FineSigma"); if(field_num>=0) { OptionsField=mxGetPr(mxGetFieldByNumber(prhs[4], 0, field_num)); Options.FineSigma=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[4], "SigmaIterations"); if(field_num>=0) { OptionsField=mxGetPr(mxGetFieldByNumber(prhs[4], 0, field_num)); Options.SigmaIterations=(int)OptionsField[0]; } } /* Connect inputs */ I = mxGetPr(prhs[0]); p_in = mxGetPr(prhs[1]); I_template = mxGetPr(prhs[2]); Wn = mxGetPr(prhs[3]); /* Connect outputs */ plhs[0] = mxCreateNumericArray(2, dimsP, mxDOUBLE_CLASS, mxREAL); plhs[1] = mxCreateNumericArray(2, dimsT, mxDOUBLE_CLASS, mxREAL); plhs[2] = mxCreateNumericArray(2, dimsE, mxDOUBLE_CLASS, mxREAL); p_out = mxGetPr(plhs[0]); I_roi = mxGetPr(plhs[1]); T_error = mxGetPr(plhs[2]); /* Perform the Lucaks Kanade tracking */ LucasKanadeInverseAffine(I, sizeI, Wn, p_in, I_template, sizeT, &Options, p_out, I_roi, T_error); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { /* Input image and ouput image */ double *u, *u_new; /* Options structure variables */ mxArray *TempField; double *OptionsField; int field_num; struct options Options; /* Size input image */ int ndimsu; const mwSize *dimsu_const; int dimsu[3]; int npixels2; int npixels3; double *usigma; /* Gaussian filtered image */ double *ux, *uy; /* Gradients of smoothed image */ double *Jxx, *Jxy, *Jyy, *J[3]; /* Structure tensor */ double *Dxx, *Dxy, *Dyy; /* Diffusion tensor */ /* Check number of inputs/outputs */ if(nrhs<1) { mexErrMsgTxt("1 input variable is required, the other one is optional."); } if(nlhs<1) { mexErrMsgTxt("1 output variable is required"); } /* Check type of inputs */ if(!mxIsDouble(prhs[0])) { mexErrMsgTxt("Input Image must be of datatype Double");} if(nrhs==2){ if(!mxIsStruct(prhs[1])){ mexErrMsgTxt("Options must be of type structure"); } } /* Set Options struct */ setdefaultoptions(&Options); if(nrhs==2) { field_num = mxGetFieldNumber(prhs[1], "T"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("aValues in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.T=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "dt"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.dt=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "sigma"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.sigma=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "rho"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.rho=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "C"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.C=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "m"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.m=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[1], "alpha"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[1], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.alpha=OptionsField[0]; } } /* Check and get input image dimensions */ ndimsu=mxGetNumberOfDimensions(prhs[0]); if((ndimsu<2)||(ndimsu>3)) { mexErrMsgTxt("Input Image must be 2D"); } dimsu_const = mxGetDimensions(prhs[0]); dimsu[0]=dimsu_const[0]; dimsu[1]=dimsu_const[1]; if(ndimsu==3) { dimsu[2]=dimsu_const[2]; } else { dimsu[2]=1; } npixels2=dimsu[0]*dimsu[1]; npixels3=dimsu[0]*dimsu[1]*dimsu[2]; /* Connect input */ u =(double *)mxGetData(prhs[0]); /* Gaussian Filtering of input image */ usigma = mallocd(npixels3); GaussianFiltering2Dcolor_double(u, usigma, dimsu, Options.sigma, 4*Options.sigma); /* Calculate the image gradients of the smoothed image */ ux = mallocd(npixels3); uy = mallocd(npixels3); gradient2Dx_color(usigma, dimsu, ux); gradient2Dy_color(usigma, dimsu, uy); /* remove usigma from memory */ free(usigma); /* Compute the 2D structure tensors J of the image */ StructureTensor2D(ux,uy, J, dimsu, Options.rho); Jxx=J[0]; Jyy=J[1] ;Jxy=J[2]; /* remove gradients from memory */ free(ux); free(uy); /* Structure to Diffusion Tensor Weickert */ Dxx = mallocd(npixels2); Dyy = mallocd(npixels2); Dxy = mallocd(npixels2); StructureTensor2DiffusionTensor(Jxx,Jxy,Jyy,Dxx,Dxy,Dyy,dimsu,Options.C,Options.m,Options.alpha); /* remove structure tensor from memory */ free(Jxx); free(Jyy); free(Jxy); /* Create output array */ if(dimsu[2]==1) { plhs[0] = mxCreateNumericArray(2, dimsu, mxDOUBLE_CLASS, mxREAL); } else { plhs[0] = mxCreateNumericArray(3, dimsu, mxDOUBLE_CLASS, mxREAL); } /* Assign pointer to output. */ u_new = (double *)mxGetData(plhs[0]); /* Perform the image diffusion */ diffusion_scheme_2D_rotation_invariance(u,u_new,dimsu,Dxx,Dxy,Dyy,Options.dt); /* remove diffusion tensor from memory */ free(Dxx); free(Dyy); free(Dxy); }
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { float *Dxx, *Dxy, *Dxz, *Dyy, *Dyz, *Dzz; float *Jxx, *Jxy, *Jxz, *Jyy, *Jyz, *Jzz, *gradA; /* ID of Threads */ float **ThreadID; float *ThreadID1; float ***ThreadArgs; float **ThreadArgs1; float Nthreads_f[1]={0}; float dimsu_f[3]; float constants_f[7]; int Nthreads; int i; /* Handles to the worker threads */ #ifdef _WIN32 HANDLE *ThreadList; #else pthread_t *ThreadList; #endif /* Options structure variables */ mxArray *TempField; double *OptionsField; int field_num; struct options Options; /* Size input image volume */ int ndimsu; const mwSize *dimsu_const; int dimsu[3]; /* Check for proper number of arguments. */ if(nrhs<7) { mexErrMsgTxt("Seven inputs are required."); } else if(nlhs!=6) { mexErrMsgTxt("Six outputs are required"); } for(i=0; i<7; i++) { if(!mxIsSingle(prhs[i])){ mexErrMsgTxt("Inputs must be single"); } } /* Set Options struct */ setdefaultoptions(&Options); if(nrhs==8) { field_num = mxGetFieldNumber(prhs[7], "T"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("aValues in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.T=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "dt"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.dt=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "sigma"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.sigma=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "lambda_e"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.lambda_e=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "lambda_h"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.lambda_h=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "lambda_c"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.lambda_c=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "eigenmode"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.eigenmode=(int)OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "rho"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.rho=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "C"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.C=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "m"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.m=OptionsField[0]; } field_num = mxGetFieldNumber(prhs[7], "alpha"); if(field_num>=0) { TempField=mxGetFieldByNumber(prhs[7], 0, field_num); if(!mxIsDouble(TempField)) { mexErrMsgTxt("Values in options structure must be of datatype double"); } OptionsField=mxGetPr(TempField); Options.alpha=OptionsField[0]; } } /* Check and get input image dimensions */ ndimsu=mxGetNumberOfDimensions(prhs[0]); if(ndimsu!=3) { mexErrMsgTxt("Input Image must be 3D"); } dimsu_const = mxGetDimensions(prhs[0]); dimsu[0]=dimsu_const[0]; dimsu[1]=dimsu_const[1]; dimsu[2]=dimsu_const[2]; /* Create output Tensor Volumes */ plhs[0] = mxCreateNumericArray(3, dimsu, mxSINGLE_CLASS, mxREAL); plhs[1] = mxCreateNumericArray(3, dimsu, mxSINGLE_CLASS, mxREAL); plhs[2] = mxCreateNumericArray(3, dimsu, mxSINGLE_CLASS, mxREAL); plhs[3] = mxCreateNumericArray(3, dimsu, mxSINGLE_CLASS, mxREAL); plhs[4] = mxCreateNumericArray(3, dimsu, mxSINGLE_CLASS, mxREAL); plhs[5] = mxCreateNumericArray(3, dimsu, mxSINGLE_CLASS, mxREAL); /* Assign pointers to each input. */ Jxx = (float *)mxGetPr(prhs[0]); Jxy = (float *)mxGetPr(prhs[1]); Jxz = (float *)mxGetPr(prhs[2]); Jyy = (float *)mxGetPr(prhs[3]); Jyz = (float *)mxGetPr(prhs[4]); Jzz = (float *)mxGetPr(prhs[5]); gradA = (float *)mxGetPr(prhs[6]); /* Assign pointers to each output. */ Dxx = (float *)mxGetPr(plhs[0]); Dxy = (float *)mxGetPr(plhs[1]); Dxz = (float *)mxGetPr(plhs[2]); Dyy = (float *)mxGetPr(plhs[3]); Dyz = (float *)mxGetPr(plhs[4]); Dzz = (float *)mxGetPr(plhs[5]); Nthreads=2; Nthreads_f[0]=(float)Nthreads; for(i=0; i<3; i++) { dimsu_f[i]=(float)dimsu[i]; } constants_f[0]=(float)Options.eigenmode; constants_f[1]=(float)Options.C; constants_f[2]=(float)Options.m; constants_f[3]=(float)Options.alpha; constants_f[4]=(float)Options.lambda_e; constants_f[5]=(float)Options.lambda_h; constants_f[6]=(float)Options.lambda_c; /* 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 = (float **)malloc( Nthreads* sizeof(float *) ); ThreadArgs = (float ***)malloc( Nthreads* sizeof(float **) ); for (i=0; i<Nthreads; i++) { /* Make Thread ID */ ThreadID1= (float *)malloc( 1* sizeof(float) ); ThreadID1[0]=(float)i; ThreadID[i]=ThreadID1; /* Make Thread Structure */ ThreadArgs1 = (float **)malloc( 17* sizeof( float * ) ); ThreadArgs1[0]=Jxx; ThreadArgs1[1]=Jxy; ThreadArgs1[2]=Jxz; ThreadArgs1[3]=Jyy; ThreadArgs1[4]=Jyz; ThreadArgs1[5]=Jzz; ThreadArgs1[6]=Dxx; ThreadArgs1[7]=Dxy; ThreadArgs1[8]=Dxz; ThreadArgs1[9]=Dyy; ThreadArgs1[10]=Dyz; ThreadArgs1[11]=Dzz; ThreadArgs1[12]=gradA; ThreadArgs1[13]=dimsu_f; ThreadArgs1[14]=constants_f; ThreadArgs1[15]=ThreadID[i]; ThreadArgs1[16]=Nthreads_f; /* Start a Thread */ ThreadArgs[i]=ThreadArgs1; #ifdef _WIN32 ThreadList[i] = (HANDLE)_beginthreadex( NULL, 0, &StructureTensor2DiffusionTensorThread, ThreadArgs[i] , 0, NULL ); #else pthread_create ((pthread_t*)&ThreadList[i], NULL, (void *) &StructureTensor2DiffusionTensorThread, 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); }