void levelSet3Dfast(MATRIXD im, MATRIX init_mask, int max_its, double E, double T, double alpha, MATRIX *seg0, MATRIX *tmap, MATRIXD *phi, long **ls_vols, int offset){ long dx = im.dx, dy = im.dy, dz = im.dz; int *px, *py, *pz, *qx, *qy, *qz, k, tmap_it = 1; MATRIX intTmp; MATRIX intTmp2 = allocateMatrix(dx,dy,dz); // add a new temporary matrix MATRIXD dblTmp = allocateMatrixD(dx,dy,dz); MATRIXD gradPhi = allocateMatrixD(dx,dy,dz); int minx, maxx, miny, maxy, minz, maxz; *phi = allocateMatrixD(dx,dy,dz); *seg0 = allocateMatrix(dx,dy,dz); *tmap = allocateMatrix(dx,dy,dz); *ls_vols = (long *)calloc(max_its,sizeof(long)); // initialized with 0 initializeMatrix(tmap,0); initializeMatrix(seg0,0); // initialized with 0 initializeMatrix(&intTmp2,0); // initialized with 0 initializeGlobals4bwdist(dx,dy,dz,&px,&py,&pz,&qx,&qy,&qz,&intTmp); createSignedDistanceMap(init_mask,phi,px,py,pz,qx,qy,qz,intTmp,dblTmp); // temps: intTmp, dblTmp findLimits(init_mask,offset,&minx,&maxx,&miny,&maxy,&minz,&maxz); for (k = 1; k <= max_its; k++){ calculateCurvature(*phi,&dblTmp,minx,maxx,miny,maxy,minz,maxz); // dblTmp keeps the curvatures calculateF(im,dblTmp,&dblTmp,E,T,alpha,minx,maxx,miny,maxy,minz,maxz); // first dblTmp (input): curvatures, second dblTmp (output): F values calculateGradPhi(*phi,dblTmp,&gradPhi,minx,maxx,miny,maxy,minz,maxz); evolveCurve(phi,dblTmp,gradPhi,minx,maxx,miny,maxy,minz,maxz); if (k % 50 == 0) reinitializeDistanceFunction(phi,init_mask,px,py,pz,qx,qy,qz,intTmp,dblTmp); // temps: init_mask, intTmp, dblTmp (*ls_vols)[k-1] = selectNonpositive(*phi,&intTmp2,minx,maxx,miny,maxy,minz,maxz); // use the second temporarymatrix if (k == 1){ selectNonpositive(*phi,seg0,minx,maxx,miny,maxy,minz,maxz); copyMatrixWithLimits(tmap,*seg0,minx,maxx,miny,maxy,minz,maxz); findLimits(*tmap,offset,&minx,&maxx,&miny,&maxy,&minz,&maxz); } else if (k % 10 == 0){ selectNonpositive(*phi,&intTmp2,minx,maxx,miny,maxy,minz,maxz); // use the second temporarymatrix updateMaps(tmap,intTmp2,*seg0,tmap_it,minx,maxx,miny,maxy,minz,maxz); // use the second temporarymatrix copyMatrixWithLimits(seg0,intTmp2,minx,maxx,miny,maxy,minz,maxz); // use the second temporarymatrix tmap_it++; findLimits(*tmap,offset,&minx,&maxx,&miny,&maxy,&minz,&maxz); } } selectNonpositive(*phi,seg0,0,dx-1,0,dy-1,0,dz-1); //selectNonpositive(*phi,seg0,minx,maxx,miny,maxy,minz,maxz); ???? (consider this modification if there are more problems) freeMatrixD(gradPhi); freeMatrixD(dblTmp); freeMatrix(intTmp2); freeGlobals4bwdist(px,py,pz,qx,qy,qz,intTmp); }
void levelSet3D(MATRIXD im, MATRIX init_mask, int max_its, double E, double T, double alpha, MATRIX *seg0, MATRIX *tmap, MATRIXD *phi, long **ls_vols){ // some of these variables will be used as the local variables for other functions // they are defined outside (like global variables) because we want to decrease the overhead // corresponding to allocation and deallocation (since we have multiple calls for the same function long dx = im.dx, dy = im.dy, dz = im.dz; int *px, *py, *pz, *qx, *qy, *qz, k, tmap_it = 1; MATRIX intTmp; MATRIXD dblTmp = allocateMatrixD(dx,dy,dz); MATRIXD gradPhi = allocateMatrixD(dx,dy,dz); *phi = allocateMatrixD(dx,dy,dz); *seg0 = allocateMatrix(dx,dy,dz); *tmap = allocateMatrix(dx,dy,dz); *ls_vols = (long *)calloc(max_its,sizeof(long)); // initialized with 0 initializeMatrix(tmap,0); initializeGlobals4bwdist(dx,dy,dz,&px,&py,&pz,&qx,&qy,&qz,&intTmp); createSignedDistanceMap(init_mask,phi,px,py,pz,qx,qy,qz,intTmp,dblTmp); // temps: intTmp, dblTmp for (k = 1; k <= max_its; k++){ calculateCurvature(*phi,&dblTmp,0,dx-1,0,dy-1,0,dz-1); // dblTmp keeps the curvatures calculateF(im,dblTmp,&dblTmp,E,T,alpha,0,dx-1,0,dy-1,0,dz-1); // first dblTmp (input): curvatures, second dblTmp (output): F values calculateGradPhi(*phi,dblTmp,&gradPhi,0,dx-1,0,dy-1,0,dz-1); evolveCurve(phi,dblTmp,gradPhi,0,dx-1,0,dy-1,0,dz-1); if (k % 50 == 0) reinitializeDistanceFunction(phi,init_mask,px,py,pz,qx,qy,qz,intTmp,dblTmp); // temps: init_mask, intTmp, dblTmp (*ls_vols)[k-1] = selectNonpositive(*phi,&intTmp,0,dx-1,0,dy-1,0,dz-1); if (k == 1){ selectNonpositive(*phi,seg0,0,dx-1,0,dy-1,0,dz-1); copyMatrix(tmap,*seg0); } else if (k % 10 == 0){ selectNonpositive(*phi,&intTmp,0,dx-1,0,dy-1,0,dz-1); updateMaps(tmap,intTmp,*seg0,tmap_it,0,dx-1,0,dy-1,0,dz-1); copyMatrix(seg0,intTmp); tmap_it++; } } selectNonpositive(*phi,seg0,0,dx-1,0,dy-1,0,dz-1); freeMatrixD(gradPhi); freeMatrixD(dblTmp); freeGlobals4bwdist(px,py,pz,qx,qy,qz,intTmp); }
MATRIXD normalizeMatrixD(MATRIXD *M){ MATRIXD stats = allocateMatrixD(2,M->column); long i, j; for (i = 0; i < M->column; i++){ stats.data[0][i] = 0.0; for (j = 0; j < M->row; j++) stats.data[0][i] += M->data[j][i]; stats.data[0][i] /= M->row; stats.data[1][i] = 0; for (j = 0; j < M->row; j++) stats.data[1][i] += (M->data[j][i] - stats.data[0][i]) * (M->data[j][i] - stats.data[0][i]); stats.data[1][i] /= M->row - 1; stats.data[1][i] = sqrt(stats.data[1][i]); } for (i = 0; i < M->row; i++) for (j = 0; j < M->column; j++) if (stats.data[1][j] <= ZERO) M->data[i][j] = (M->data[i][j] - stats.data[0][j]); else M->data[i][j] = (M->data[i][j] - stats.data[0][j]) / stats.data[1][j]; return stats; }
MATRIXD inverseMatrixD(MATRIXD M){ MATRIXD inv, temp; int i; if (M.row != M.column){ printf("\nError: Matrix should be square for inverse computation\n"); exit(1); } temp = allocateMatrixD(M.row,M.column); copyMatrixD(&temp,M); inv = allocateMatrixD(M.row,M.column); initializeMatrixD(&inv,0.0); for (i = 0; i < M.row; i++) inv.data[i][i] = 1; gaussj(M.data,M.row,inv.data,inv.column); copyMatrixD(&M,temp); freeMatrixD(temp); return inv; }
void reallocateMatrixD(MATRIXD *M, long row, long column){ int i, j, minrow, mincol; MATRIXD tmp = allocateMatrixD(M->row,M->column); copyMatrixD(&tmp,*M); freeMatrixD(*M); *M = allocateMatrixD(row,column); initializeMatrixD(M,0.0); if (tmp.row > row) minrow = row; else minrow = tmp.row; if (tmp.column > column) mincol = column; else mincol = tmp.column; for (i = 0; i < minrow; i++) for (j = 0; j < mincol; j++) M->data[i][j] = tmp.data[i][j]; freeMatrixD(tmp); }
MATRIXD computeEigenValues(MATRIXD M, MATRIXD *V){ long i, j; int nrot; MATRIXD D; if (M.row != M.column){ printf("\nError: Matrix should be square for eigenvalue computation\n"); exit(1); } for (i = 0; i < M.row; i++) for (j = i+1; j < M.column; j++) if (M.data[i][j] != M.data[j][i]){ printf("\nError: Matrix should be symmetric for eigenvalue computation\n"); exit(1); } D = allocateMatrixD(1,M.row); *V = allocateMatrixD(M.row,M.row); jacobi(M.data,M.row,D.data[0],V->data,&nrot); eigsrt(D.data[0],V->data,D.column); return D; }
MATRIXD computeMeanMatrixD(MATRIXD A){ long i, j; MATRIXD M = allocateMatrixD(1,A.column); initializeMatrixD(&M,0.0); for (i = 0; i < A.row; i++) for (j = 0; j < A.column; j++) M.data[0][j] += A.data[i][j]; for (j = 0; j < M.column; j++) M.data[0][j] /= A.row; return M; }
MATRIXD computeCorrelationMatrixD(MATRIXD A){ long i, j; MATRIXD S = computeCovarianceMatrixD(A); MATRIXD R = allocateMatrixD(S.row,S.column); for (i = 0; i < S.row; i++) for (j = 0; j < S.column; j++) if (fabs(sqrt(S.data[i][i]) * sqrt(S.data[j][j])) > ZERO) R.data[i][j] = S.data[i][j] / (sqrt(S.data[i][i]) * sqrt(S.data[j][j])); else R.data[i][j] = 0; freeMatrixD(S); return R; }
MATRIXD addMatrixD(MATRIXD A, MATRIXD B){ long i, j; MATRIXD M; if (A.row != B.row || A.column != B.column){ printf("\nError: Matrix dimensions mismatch in add operation\n"); exit(1); } M = allocateMatrixD(A.row,A.column); for (i = 0; i < M.row; i++) for (j = 0; j < M.column; j++) M.data[i][j] = A.data[i][j] + B.data[i][j]; return M; }
MATRIXD computeCovarianceMatrixD(MATRIXD A){ long i, j, t; MATRIXD M = computeMeanMatrixD(A); MATRIXD S = allocateMatrixD(A.column,A.column); initializeMatrixD(&S,0.0); for (i = 0; i < S.row; i++) for (j = 0; j < S.column; j++) for (t = 0; t < A.row; t++) S.data[i][j] += (A.data[t][i] - M.data[0][i]) * (A.data[t][j] - M.data[0][j]); for (i = 0; i < S.row; i++) for (j = 0; j < S.column; j++) S.data[i][j] /= A.row - 1; freeMatrixD(M); return S; }
MATRIXD multiplyMatrixD(MATRIXD A, MATRIXD B){ MATRIXD result; long i, j, k; if (A.column != B.row){ printf("\nError: Matrix dimensions do not match in matrix multiplication\n"); exit(1); } result = allocateMatrixD(A.row,B.column); for (i = 0; i < A.row; i++) for (j = 0; j < B.column; j++){ result.data[i][j] = 0.0; for (k = 0; k < A.column; k++) result.data[i][j] += A.data[i][k] * B.data[k][j]; } return result; }
MATRIXD readMatrixD(char *filename){ MATRIXD M; long r, c, i, j; FILE *id = fopen(filename,"r"); if (id == NULL){ printf("Error: File %s does not exist...\n",filename); exit(1); } fscanf(id,"%ld%ld",&r,&c); M = allocateMatrixD(r,c); for (i = 0; i < r; i++) for (j = 0; j < c; j++) fscanf(id,"%lf",&(M.data[i][j])); fclose(id); return M; }