unsigned ThreadFunc( myargument arg ) { float *bias,*Estimate,*ima,*means,*variances,*average; double epsilon,mu1,var1,totalweight,wmax,t1,t1i,t2,d,w,distanciaminima; unsigned char *Label; int rows,cols,slices,ini,fin,v,f,init,i,j,k,rc,ii,jj,kk,ni,nj,nk,Ndims; extern int rician; extern double max; rows = arg.rows; cols = arg.cols; slices = arg.slices; ini = arg.ini; fin = arg.fin; ima = arg.in_image; means = arg.means_image; variances = arg.var_image; Estimate = arg.estimate; bias = arg.bias; Label = arg.label; v = arg.radioB; f = arg.radioS; /* filter */ epsilon = 0.00001; mu1 = 0.95; var1 = 0.5; init = 0; rc = rows*cols; Ndims = (2*f+1)*(2*f+1)*(2*f+1); average = (float*)malloc(Ndims*sizeof(float)); wmax = 0.0; for (k = ini;k<fin;k+= 2) for (j = 0;j<rows;j+= 2) for (i = 0;i<cols;i+= 2) { /* init */ for (init = 0 ; init < Ndims; init++) average[init] = 0.0; totalweight = 0.0; distanciaminima = 1e15; if (ima[k*rc+(j*cols)+i]>0 && (means[k*rc+(j*cols)+i])>epsilon && (variances[k*rc+(j*cols)+i]>epsilon)) { /* calculate minimum distance */ for (kk = -v;kk<= v;kk++) { nk = k+kk; for (jj = -v;jj<= v;jj++) { nj = j+jj; for (ii = -v;ii<= v;ii++) { ni = i+ii; if (ii == 0 && jj == 0 && kk == 0) continue; if (ni>= 0 && nj>= 0 && nk>= 0 && ni<cols && nj<rows && nk<slices) { if (ima[nk*rc+(nj*cols)+ni]>0 && (means[nk*(rc)+(nj*cols)+ni])> epsilon && (variances[nk*rc+(nj*cols)+ni]>epsilon)) { t1 = ((double)means[k*rc+(j*cols)+i])/((double)means[nk*rc+(nj*cols)+ni]); t1i = (max-(double)means[k*(rc)+(j*cols)+i])/(max-(double)means[nk*(rc)+(nj*cols)+ni]); t2 = ((double)variances[k*rc+(j*cols)+i])/((double)variances[nk*rc+(nj*cols)+ni]); if ( (t1>mu1 && t1<(1/mu1)) || (t1i>mu1 && t1i<(1/mu1)) && t2>var1 && t2<(1/var1)) { d = distance2(ima,means,i,j,k,ni,nj,nk,f,cols,rows,slices); if (d<distanciaminima) distanciaminima = d; } } } } } } if (distanciaminima == 0) distanciaminima = 1; /* rician correction */ if (rician) { for (kk = -f;kk<= f;kk++) { nk = k+kk; for (ii = -f;ii<= f;ii++) { ni = i+ii; for (jj = -f;jj<= f;jj++) { nj = j+jj; if (ni>= 0 && nj>= 0 && nk>= 0 && ni<cols && nj<rows && nk<slices) { if (distanciaminima == 1e15) bias[nk*(rc)+(nj*cols)+ni] = 0.0; else bias[nk*(rc)+(nj*cols)+ni] = (float)distanciaminima; } } } } } /* block filtering */ for (kk = -v;kk<= v;kk++) { nk = k+kk; for (jj = -v;jj<= v;jj++) { nj = j+jj; for (ii = -v;ii<= v;ii++) { ni = i+ii; if (ii == 0 && jj == 0 && kk == 0) continue; if (ni>= 0 && nj>= 0 && nk>= 0 && ni<cols && nj<rows && nk<slices) { if (ima[nk*rc+(nj*cols)+ni]>0 && (means[nk*(rc)+(nj*cols)+ni])> epsilon && (variances[nk*rc+(nj*cols)+ni]>epsilon)) { t1 = ((double)means[k*rc+(j*cols)+i])/((double)means[nk*rc+(nj*cols)+ni]); t1i = (max-(double)means[k*(rc)+(j*cols)+i])/(max-(double)means[nk*(rc)+(nj*cols)+ni]); t2 = ((double)variances[k*rc+(j*cols)+i])/((double)variances[nk*rc+(nj*cols)+ni]); if ( (t1>mu1 && t1<(1/mu1)) || (t1i>mu1 && t1i<(1/mu1)) && t2>var1 && t2<(1/var1)) { d = distance(ima,i,j,k,ni,nj,nk,f,cols,rows,slices); if (d>3*distanciaminima) w = 0; else w = exp(-d/distanciaminima); if (w>wmax) wmax = w; if (w>0) { Average_block(ima,ni,nj,nk,f,average,w,cols,rows,slices); totalweight = totalweight + w; } } } } } } } if (wmax == 0.0) wmax = 1.0; Average_block(ima,i,j,k,f,average,wmax,cols,rows,slices); totalweight = totalweight + wmax; Value_block(Estimate,Label,i,j,k,f,average,totalweight,cols,rows,slices); } else { wmax = 1.0; Average_block(ima,i,j,k,f,average,wmax,cols,rows,slices); totalweight = totalweight + wmax; Value_block(Estimate,Label,i,j,k,f,average,totalweight,cols,rows,slices); } } free(average); return 0; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { mxArray *xData; double *ima, *fima,*average; mxArray *Mxmeans, *Mxvariances, *MxEstimate, *MxLabel; double *means, *varianzas, *Estimate, *Label; mxArray *pv; double label,estimate,epsilon,mu1,var1,h,w,totalweight,wmax,d,mean,var,t1,t2,hh; int init,Ndims,i,j,k,ii,jj,kk,ni,nj,nk,v,f,ndim,indice; const int *dims; /*Copy input pointer x*/ xData = prhs[0]; /*Get matrix x*/ ima = mxGetPr(xData); ndim = mxGetNumberOfDimensions(prhs[0]); dims= mxGetDimensions(prhs[0]); /*Copy input parameters*/ pv = prhs[1]; /*Get the Integer*/ v = (int)(mxGetScalar(pv)); pv = prhs[2]; f = (int)(mxGetScalar(pv)); pv = prhs[3]; h = (double)(mxGetScalar(pv)); hh=2*h*h; Ndims = pow((2*f+1),ndim); /*Allocate memory and assign output pointer*/ plhs[0] = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS, mxREAL); Mxmeans = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS, mxREAL); Mxvariances = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS, mxREAL); MxEstimate = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS, mxREAL); MxLabel = mxCreateNumericArray(ndim,dims,mxDOUBLE_CLASS, mxREAL); average=(double*) malloc(Ndims*sizeof(double)); /*Get a pointer to the data space in our newly allocated memory*/ fima = mxGetPr(plhs[0]); means = mxGetPr(Mxmeans); varianzas = mxGetPr(Mxvariances); Estimate = mxGetPr(MxEstimate); Label = mxGetPr(MxLabel); for (i = 0; i < dims[2] *dims[1] * dims[0];i++) { Estimate[i] = 0.0; Label[i] = 0.0; fima[i] = 0.0; } for(k=0;k<dims[2];k++) { for(i=0;i<dims[1];i++) { for(j=0;j<dims[0];j++) { mean=0; indice=0; for(ii=-1;ii<=1;ii++) { for(jj=-1;jj<=1;jj++) { for(kk=-1;kk<=1;kk++) { ni=i+ii; nj=j+jj; nk=k+kk; if(ni<0) ni=-ni; if(nj<0) nj=-nj; if(nk<0) nk=-nk; if(ni>=dims[1]) ni=2*dims[1]-ni-1; if(nj>=dims[0]) nj=2*dims[0]-nj-1; if(nk>=dims[2]) nk=2*dims[2]-nk-1; mean = mean + ima[nk*(dims[0]*dims[1])+(ni*dims[0])+nj]; indice=indice+1; } } } mean=mean/indice; means[k*(dims[0]*dims[1])+(i*dims[0])+j]=mean; } } } for(k=0;k<dims[2];k++) { for(i=0;i<dims[1];i++) { for(j=0;j<dims[0];j++) { var=0; indice=0; for(ii=-1;ii<=1;ii++) { for(jj=-1;jj<=1;jj++) { for(kk=-1;kk<=1;kk++) { ni=i+ii; nj=j+jj; nk=k+kk; if(ni>=0 && nj>=0 && nk>0 && ni<dims[1] && nj<dims[0] && nk<dims[2]) { var = var + (ima[nk*(dims[0]*dims[1])+(ni*dims[0])+nj]-means[k*(dims[0]*dims[1])+(i*dims[0])+j])*(ima[nk*(dims[0]*dims[1])+(ni*dims[0])+nj]-means[k*(dims[0]*dims[1])+(i*dims[0])+j]); indice=indice+1; } } } } var=var/(indice-1); varianzas[k*(dims[0]*dims[1])+(i*dims[0])+j]=var; } } } /*filter*/ epsilon = 0.00001; mu1 = 0.95; var1 = 0.5; init = 0; for(k=0;k<dims[2];k+=2) { for(i=0;i<dims[1];i+=2) { for(j=0;j<dims[0];j+=2) { for (init=0 ; init < Ndims; init++) { average[init]=0.0; } /*average=0;*/ totalweight=0.0; if ((means[k*(dims[0]*dims[1])+(i*dims[0])+j])>epsilon && (varianzas[k*(dims[0]*dims[1])+(i*dims[0])+j]>epsilon)) { wmax=0.0; for(kk=-v;kk<=v;kk++) { for(ii=-v;ii<=v;ii++) { for(jj=-v;jj<=v;jj++) { ni=i+ii; nj=j+jj; nk=k+kk; if(ii==0 && jj==0 && kk==0) continue; if(ni>=0 && nj>=0 && nk>=0 && ni<dims[1] && nj<dims[0] && nk<dims[2]) { if ((means[nk*(dims[0]*dims[1])+(ni*dims[0])+nj])> epsilon && (varianzas[nk*(dims[0]*dims[1])+(ni*dims[0])+nj]>epsilon)) { t1 = (means[k*(dims[0]*dims[1])+(i*dims[0])+j])/(means[nk*(dims[0]*dims[1])+(ni*dims[0])+nj]); t2 = (varianzas[k*(dims[0]*dims[1])+(i*dims[0])+j])/(varianzas[nk*(dims[0]*dims[1])+(ni*dims[0])+nj]); if(t1>mu1 && t1<(1/mu1) && t2>var1 && t2<(1/var1)) { d=distance(ima,i,j,k,ni,nj,nk,f,dims[1],dims[0],dims[2]); w = exp(-d/(h*h)); if(w>wmax) wmax = w; Average_block(ima,ni,nj,nk,f,average,w,dims); /*average = average + w*ima[nk*(dims[0]*dims[1])+(ni*dims[0])+nj];*/ totalweight = totalweight + w; } } } } } } if(wmax==0.0) wmax=1.0; /*average = average + wmax*ima[k*(dims[0]*dims[1])+(i*dims[0])+j];*/ Average_block(ima,i,j,k,f,average,wmax,dims); totalweight = totalweight + wmax; /*fima[k*(dims[0]*dims[1])+(i*dims[0])+j] = average / totalweight;*/ if(totalweight != 0.0) Value_block(Estimate,Label,i,j,k,f,average,totalweight,dims,hh); } else { wmax=1.0; Average_block(ima,i,j,k,f,average,wmax,dims); totalweight = totalweight + wmax; Value_block(Estimate,Label,i,j,k,f,average,totalweight,dims,hh); } } } } label = 0.0; estimate = 0.0; /* Aggregation of the estimators (i.e. means computation) */ for (k = 0; k < dims[2]; k++ ) { for (i = 0; i < dims[1]; i++ ) { for (j = 0; j < dims[0]; j++ ) { label = Label[k*(dims[0]*dims[1])+(i*dims[0])+j]; if (label == 0.0) { fima[k*(dims[0]*dims[1])+(i*dims[1])+j] = ima[k*(dims[0]*dims[1])+(i*dims[0])+j]; } else { estimate = Estimate[k*(dims[0]*dims[1])+(i*dims[0])+j]; estimate = (estimate/label); fima[k*(dims[0]*dims[1])+(i*dims[0])+j]=estimate; } } } } return; }