/* 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);
}
Exemple #2
0
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);
}