VImage VImageManager::scaleImage( VImage src, VImage dest, double factor ) { int nPixel = VImageSize( src ) / VPixelSize( src ); if ( dest == NULL ) { dest = VCreateImage( VImageNBands( src ), VImageNRows( src ), VImageNColumns( src ), VUByteRepn ); } VUByte *destPtr = ( VUByte * ) VImageData( dest ); VShort *srcPtr = ( VShort * ) VImageData( src ); srcPtr = ( VShort * ) VImageData( src ); for ( int i = 0; i < nPixel; i++ ) { if ( *srcPtr <= m_xmin ) *destPtr = 0; else if ( *srcPtr >= m_xmax ) *destPtr = 255; else { int val = *srcPtr - m_xmin; *destPtr = ( VUByte ) ( val * factor ); } srcPtr++; destPtr++; } return dest; }
VImage VSelectDestImage (VStringConst routine, VImage dest, int nbands, int nrows, int ncolumns, VRepnKind pixel_repn) { /* If no destination image was specified, allocate one: */ if (! dest) return VCreateImage (nbands, nrows, ncolumns, pixel_repn); /* Otherwise check that the destination provided has the appropriate characteristics: */ if (VImageNBands (dest) != nbands) { VWarning ("%s: Destination image has %d bands; %d expected", routine, VImageNBands (dest), nbands); return NULL; } if (VImageNRows (dest) != nrows) { VWarning ("%s: Destination image has %d rows; %d expected", routine, VImageNRows (dest), nrows); return NULL; } if (VImageNColumns (dest) != ncolumns) { VWarning ("%s: Destination image has %d columns; %d expected", routine, VImageNColumns (dest), ncolumns); return NULL; } if (VPixelRepn (dest) != pixel_repn) { VWarning ("%s: Destination image has %s pixels; %s expected", routine, VPixelRepnName (dest), VRepnName (pixel_repn)); return NULL; } return dest; }
VImage VSGaussKernel(double sigma) { int i,dim,n; double x,u,step; VImage kernel=NULL; double sum; dim = 3.0 * sigma + 1; n = 2*dim+1; step = 1; kernel = VCreateImage(1,1,n,VFloatRepn); sum = 0; x = -(float)dim; for (i=0; i<n; i++) { u = xsgauss(x,sigma); sum += u; VPixel(kernel,0,0,i,VFloat) = u; x += step; } /* normalize */ for (i=0; i<n; i++) { u = VPixel(kernel,0,0,i,VFloat); u /= sum; VPixel(kernel,0,0,i,VFloat) = u; } return kernel; }
/* ** concordance mapping */ VImage VCCM2(float *A1,float *A2,VImage map,int type) { VImage dest=NULL; size_t b,r,c,i,j,k,kk,nvoxels; int nslices=0,nrows=0,ncols=0; double *arr1=NULL,*arr2=NULL,u; nslices = VPixel(map,0,3,0,VShort); nrows = VPixel(map,0,3,1,VShort); ncols = VPixel(map,0,3,2,VShort); nvoxels = VImageNColumns(map); dest = VCreateImage(nslices,nrows,ncols,VFloatRepn); VFillImage(dest,VAllBands,0); VCopyImageAttrs (map, dest); VSetAttr(VImageAttrList(dest),"modality",NULL,VStringRepn,"conimg"); arr1 = (double *) VCalloc(nvoxels,sizeof(double)); arr2 = (double *) VCalloc(nvoxels,sizeof(double)); fprintf(stderr," concordance mapping...\n"); for (i=0; i<nvoxels; i++) { if (i%50 == 0) fprintf(stderr," %6d of %d\r",i,nvoxels); b = (int)VPixel(map,0,0,i,VShort); r = (int)VPixel(map,0,1,i,VShort); c = (int)VPixel(map,0,2,i,VShort); for (j=0; j<nvoxels; j++) arr1[j] = arr2[j] = 0; kk = 0; for (j=0; j<i; j++) { k=j+i*(i+1)/2; arr1[kk] = (double)A1[k]; arr2[kk] = (double)A2[k]; kk++; } for (j=i+1; j<nvoxels; j++) { k=i+j*(j+1)/2; arr1[kk] = (double)A1[k]; arr2[kk] = (double)A2[k]; kk++; } u = 0; switch (type) { case 0: u = kendall(arr1,arr2,nvoxels); break; case 1: u = CCC(arr1,arr2,nvoxels); break; default: VError("illegal type"); } VPixel(dest,b,r,c,VFloat) = (VFloat)u; } fprintf(stderr,"\n"); return dest; }
/* ** read a 2nd level design file */ VImage VRead2ndLevel(FILE *fp) { VImage dest = NULL; int i, j, nrows, ncols; float val; char buf[LEN], token[32]; nrows = ncols = 0; while(!feof(fp)) { memset(buf, 0, LEN); if(!fgets(buf, LEN, fp)) break; if(strlen(buf) < 1) continue; if(buf[0] == '%') continue; j = 0; while(VStringToken(buf, token, j, 30)) { if(!sscanf(token, "%f", &val)) VError("illegal input string: %s", token); j++; } if(ncols == 0) ncols = j; if(j < 1) continue; else if(ncols != j) VError(" inconsistent number of columns in row %d", nrows + 1); nrows++; } rewind(fp); dest = VCreateImage(1, nrows, ncols, VFloatRepn); VFillImage(dest, VAllBands, 0); VSetAttr(VImageAttrList(dest), "modality", NULL, VStringRepn, "X"); VSetAttr(VImageAttrList(dest), "name", NULL, VStringRepn, "X"); VSetAttr(VImageAttrList(dest), "ntimesteps", NULL, VLongRepn, (VLong)VImageNRows(dest)); VSetAttr(VImageAttrList(dest), "nsessions", NULL, VShortRepn, (VShort)1); VSetAttr(VImageAttrList(dest), "designtype", NULL, VShortRepn, (VShort)2); i = 0; while(!feof(fp)) { memset(buf, 0, LEN); if(!fgets(buf, LEN, fp)) break; if(strlen(buf) < 1) continue; if(buf[0] == '%') continue; j = 0; while(VStringToken(buf, token, j, 30)) { sscanf(token, "%f", &val); VPixel(dest, 0, i, j, VFloat) = val; j++; } if(j < 1) continue; i++; } return dest; }
VImage VSelSlices (VImage src,VImage dest,VShort first,VShort last) { int nbands,nrows,ncols,nbands_neu,npixels; int i,b,bn; VRepnKind repn; nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); repn = VPixelRepn(src); if (first < 0) VError("VSelSlices: parameter <first> must be positive"); if (last < 0) last = nbands-1; if (last >= nbands) last = nbands-1; if (first > last) VError("VSelSlices: <first> must be less than <last>."); nbands_neu = last - first + 1; if (dest == NULL) dest = VCreateImage(nbands_neu,nrows,ncols,repn); npixels = nrows * ncols; #define SelSlices(type) \ { \ type *src_pp, *dest_pp; \ bn = 0; \ for (b=first; b<=last; b++) { \ src_pp = VPixelPtr(src,b,0,0); \ dest_pp = VPixelPtr(dest,bn,0,0); \ for (i=0; i<npixels; i++) *dest_pp++ = *src_pp++; \ bn++; \ } \ } /* Instantiate the macro once for each source pixel type: */ switch (repn) { case VBitRepn: SelSlices (VBit); break; case VUByteRepn: SelSlices (VUByte); break; case VSByteRepn: SelSlices (VSByte); break; case VShortRepn: SelSlices (VShort); break; case VLongRepn: SelSlices (VLong); break; case VFloatRepn: SelSlices (VFloat); break; case VDoubleRepn: SelSlices (VDouble); break; default: ; } /* Let the destination inherit any attributes of the source image: */ VCopyImageAttrs (src, dest); return dest; }
void FunctionalResize (VImage& Image, int Bands, int Rows, int Columns) { VImage zero; /* empty image */ /* resize image */ zero = VCreateImage (Bands, Rows, Columns, VShortRepn); VImageAttrList (zero) = VCopyAttrList (VImageAttrList (Image)); VFillImage (zero, VAllBands, 0); VDestroyImage (Image); Image = zero; } /* FunctionalResize */
/* ** convert a gsl matrix to a 2D vista raster image */ VImage Mat2Vista(gsl_matrix_float *A) { VImage dest = NULL; int i, j; float x; dest = VCreateImage(1, A->size1, A->size2, VFloatRepn); for(i = 0; i < A->size1; i++) { for(j = 0; j < A->size2; j++) { x = fmget(A, i, j); VPixel(dest, 0, i, j, VFloat) = x; } } return dest; }
VImage VCopyImageAttrs (VImage src, VImage dest) { VAttrList list; if (src == dest) return dest; if (! dest) { dest = VCreateImage (VImageNBands (src), VImageNRows (src), VImageNColumns (src), VPixelRepn (src)); if (! dest) return NULL; } /* Clone the source image's attribute list if it isn't empty: */ if (! VAttrListEmpty (VImageAttrList (src))) { list = VImageAttrList (dest); VImageAttrList (dest) = VCopyAttrList (VImageAttrList (src)); } else if (! VAttrListEmpty (VImageAttrList (dest))) { list = VImageAttrList (dest); VImageAttrList (dest) = VCreateAttrList (); } else list = NULL; if (list) VDestroyAttrList (list); /* Preserve band interpretation attributes only if the source and destination images have the same number of bands: */ if (VImageNBands (src) > 1 && VImageNBands (dest) == VImageNBands (src)) { VImageNFrames (dest) = VImageNFrames (src); VImageNViewpoints (dest) = VImageNViewpoints (src); VImageNColors (dest) = VImageNColors (src); VImageNComponents (dest) = VImageNComponents (src); } else { VExtractAttr (VImageAttrList (dest), VFrameInterpAttr, NULL, VBitRepn, NULL, FALSE); VExtractAttr (VImageAttrList (dest), VViewpointInterpAttr, NULL, VBitRepn, NULL, FALSE); VExtractAttr (VImageAttrList (dest), VColorInterpAttr, NULL, VBitRepn, NULL, FALSE); VExtractAttr (VImageAttrList (dest), VComponentInterpAttr, NULL, VBitRepn, NULL, FALSE); VImageNComponents (dest) = VImageNColors (dest) = VImageNViewpoints (dest) = 1; VImageNFrames (dest) = VImageNBands (dest); } return dest; }
static PyObject *python2vista(PyObject *self, PyObject *arg) { PyArrayObject *array; if (!PyArg_ParseTuple(arg, "O!", &PyArray_Type, &array)) return NULL; if (array->nd != 2) return NULL; npy_intp *dim = array->dimensions; npy_intp *strd = array->strides; //unsigned int data[dim[0]][dim[2]]; npy_intp strd0 = array->strides[0]; npy_intp strd1 = array->strides[1]; VImage image = VCreateImage (1, dim[0], dim[1], VLongRepn); printf("%i %i", dim[0],dim[1]); return PyString_FromString("sdkgfg"); }
VImage ConcatDesigns(VImage *design, int nimages) { VImage dest = NULL; VString buf = NULL; VDouble x; int i, r, c, row, col; int nrows, ncols; nrows = ncols = 0; for(i = 0; i < nimages; i++) { ncols += VImageNColumns(design[i]); nrows += VImageNRows(design[i]); } dest = VCreateImage(1, nrows, ncols, VFloatRepn); VFillImage(dest, VAllBands, 0); VCopyImageAttrs(design[0], dest); VSetAttr(VImageAttrList(dest), "nsessions", NULL, VShortRepn, (VShort)nimages); buf = (VString) VMalloc(80); buf[0] = '\0'; for(i = 0; i < nimages; i++) sprintf(buf, "%s %d", buf, (int)VImageNRows(design[i])); VSetAttr(VImageAttrList(dest), "session_lengths", NULL, VStringRepn, buf); buf[0] = '\0'; for(i = 0; i < nimages; i++) sprintf(buf, "%s %d", buf, (int)VImageNColumns(design[i])); VSetAttr(VImageAttrList(dest), "session_covariates", NULL, VStringRepn, buf); row = col = 0; for(i = 0; i < nimages; i++) { for(r = 0; r < VImageNRows(design[i]); r++) { for(c = 0; c < VImageNColumns(design[i]); c++) { x = VGetPixel(design[i], 0, r, c); if(row + r >= VImageNRows(dest)) VError(" row: %d\n", row + r); if(col + c >= VImageNColumns(dest)) VError(" column: %d\n", col + c); VSetPixel(dest, 0, row + r, col + c, x); } } row += VImageNRows(design[i]); col += VImageNColumns(design[i]); } return dest; }
VImage WriteOutput(VImage src,VImage map,int nslices,int nrows, int ncols, float *ev, int n) { VImage dest=NULL; int i,b,r,c; dest = VCreateImage(nslices,nrows,ncols,VFloatRepn); VFillImage(dest,VAllBands,0); VCopyImageAttrs (src, dest); VSetAttr(VImageAttrList(dest),"modality",NULL,VStringRepn,"conimg"); for (i=0; i<n; i++) { b = VPixel(map,0,0,i,VFloat); r = VPixel(map,0,1,i,VFloat); c = VPixel(map,0,2,i,VFloat); if (b < 0 || r < 0 || c < 0) VError(" WriteOutput: illegal address %d %d %d",b,r,c); VPixel(dest,b,r,c,VFloat) = ev[i]; } return dest; }
template <class T> void OpticalFlow (VImage S, VImage M, VImage G, VImage G2, VImage& V) { const float EPSILON = 1; /* threshold for denominator of optical flow */ int Pixels; /* number of pixels */ T *s, *m; /* source and model data pointer */ VFloat *g, *g2; /* gradient data pointer */ VFloat *v; /* optical flow data pointer */ float nom, denom; /* fraction */ int n; /* index */ /* get image size */ Pixels = VImageNPixels (S); /* create optical flow */ V = VCreateImage (VImageNBands (S), VImageNRows (S), VImageNColumns (S), VFloatRepn); /* compute optical flow */ s = (T*) VPixelPtr (S, 0, 0, 0); m = (T*) VPixelPtr (M, 0, 0, 0); g = (VFloat*) VPixelPtr (G, 0, 0, 0); g2 = (VFloat*) VPixelPtr (G2, 0, 0, 0); v = (VFloat*) VPixelPtr (V, 0, 0, 0); for (n = 0; n < Pixels; ++n) { /* compute fraction */ nom = (float) (*(m++) - *(s++)); denom = (float) (*(g2++) + (nom * nom)); /* assign optical flow */ if (denom < EPSILON) *(v++) = 0; else *(v++) = (VFloat) ((nom / denom) * *g); ++g; } } /* OpticalFlow */
VImage VCerebellum(VImage src) { VImage coronal, label_coronal; VImage sagital, label_sagital; VImage axial, label_axial; VImage bin0_image, bin1_image, label_image; VBit *bin0_pp, *src_pp; VUByte *ubyte_pp; int i, nbands, nrows, ncols, npixels, nl = 0; float x0, x1, x2; VString str; int b, r, c, cp, rp, bp, slice_extent, slice_origin, b0; nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); npixels = nbands * nrows * ncols; str = VMalloc(80); if(VGetAttr(VImageAttrList(src), "cp", NULL, VStringRepn, (VPointer) &str) != VAttrFound) VError(" attribute 'cp' not found"); sscanf(str, "%f %f %f", &x0, &x1, &x2); bp = (int) VRint((double) x2); rp = (int) VRint((double) x1); cp = (int) VRint((double) x0); if(VGetAttr(VImageAttrList(src), "extent", NULL, VStringRepn, (VPointer) &str) != VAttrFound) VError(" attribute 'extent' not found"); sscanf(str, "%f %f %f", &x0, &x1, &x2); slice_extent = (int) VRint((double) x2); if(VGetAttr(VImageAttrList(src), "origin", NULL, VStringRepn, (VPointer) &str) != VAttrFound) VError(" attribute 'origin' not found"); sscanf(str, "%f %f %f", &x0, &x1, &x2); slice_origin = (int) VRint((double) x2); /* erode */ bin1_image = VDTErode(src, NULL, (VDouble) 2.0); /* readdress to coronal slices and remove small 2D components */ coronal = VCreateImage(1, nbands, ncols, VBitRepn); label_coronal = VCreateImage(1, nbands, ncols, VUByteRepn); ubyte_pp = (VUByte *) VImageData(label_coronal); for(i = 0; i < (nbands * ncols); i++) *ubyte_pp++ = 0; for(r = rp; r < nrows; r++) { bin0_pp = (VBit *) VImageData(coronal); for(i = 0; i < (nbands * ncols); i++) *bin0_pp++ = 0; for(b = 0; b < nbands; b++) { for(c = 0; c < ncols; c++) { VPixel(coronal, 0, b, c, VBit) = VPixel(bin1_image, b, r, c, VBit); } } label_coronal = VLabelImage2d(coronal, label_coronal, 8, VUByteRepn, &nl); VDeleteCereb(label_coronal, &coronal, 110, (int) 0); for(b = 0; b < nbands; b++) { for(c = 0; c < ncols; c++) { if(VPixel(coronal, 0, b, c, VBit) == 0) VPixel(bin1_image, b, r, c, VBit) = 0; } } } /* readdress to sagital slices and remove small 2D components */ sagital = VCreateImage(1, nbands, nrows, VBitRepn); label_sagital = VCreateImage(1, nbands, nrows, VUByteRepn); ubyte_pp = (VUByte *) VImageData(label_sagital); for(i = 0; i < (nbands * nrows); i++) *ubyte_pp++ = 0; for(c = 0; c < ncols; c++) { if(ABS(c - 80) < 10) continue; bin0_pp = (VBit *) VImageData(sagital); for(i = 0; i < (nbands * nrows); i++) *bin0_pp++ = 0; for(b = 0; b < nbands; b++) { for(r = 0; r < nrows; r++) { VPixel(sagital, 0, b, r, VBit) = VPixel(bin1_image, b, r, c, VBit); } } label_sagital = VLabelImage2d(sagital, label_sagital, (int) 8, VUByteRepn, &nl); VDeleteCereb(label_sagital, &sagital, 115, cp); for(b = 0; b < nbands; b++) { for(r = 0; r < nrows; r++) { if(VPixel(sagital, 0, b, r, VBit) == 0) VPixel(bin1_image, b, r, c, VBit) = 0; } } } /* readdress to axial slices and remove small 2D components */ axial = VCreateImage(1, nrows, ncols, VBitRepn); label_axial = VCreateImage(1, nrows, ncols, VUByteRepn); ubyte_pp = (VUByte *) VImageData(label_axial); for(i = 0; i < (nrows * ncols); i++) *ubyte_pp++ = 0; /* for (b=bp; b<nbands; b++) { */ for(b = 105; b < nbands; b++) { bin0_pp = (VBit *) VImageData(axial); for(i = 0; i < (nrows * ncols); i++) *bin0_pp++ = 0; for(r = 0; r < nrows; r++) { for(c = 0; c < ncols; c++) { VPixel(axial, 0, r, c, VBit) = VPixel(bin1_image, b, r, c, VBit); } } label_sagital = VLabelImage2d(axial, label_axial, (int) 8, VUByteRepn, &nl); VDeleteCereb(label_axial, &axial, 0, 0); for(r = 0; r < nrows; r++) { for(c = 0; c < ncols; c++) { if(VPixel(axial, 0, r, c, VBit) == 0) VPixel(bin1_image, b, r, c, VBit) = 0; } } } /* remove everything below slice extent */ b0 = slice_extent + slice_origin; npixels = nrows * ncols; for(b = b0; b < nbands; b++) { bin0_pp = (VBit *) VPixelPtr(bin1_image, b, 0, 0); for(i = 0; i < npixels; i++) *bin0_pp++ = 0; } /* dilate */ bin0_image = VDTDilate(bin1_image, NULL, (VDouble) 3.0); npixels = nrows * ncols; for(b = 0; b < bp; b++) { bin0_pp = (VBit *) VPixelPtr(bin0_image, b, 0, 0); src_pp = (VBit *) VPixelPtr(src, b, 0, 0); for(i = 0; i < npixels; i++) *bin0_pp++ = *src_pp++; } for(b = bp; b < nbands; b++) { bin0_pp = (VBit *) VPixelPtr(bin0_image, b, 0, 0); src_pp = (VBit *) VPixelPtr(src, b, 0, 0); for(i = 0; i < npixels; i++) { if(*src_pp == 0) *bin0_pp = 0; src_pp++; bin0_pp++; } } /* ** remove small remaining components */ label_image = VLabelImage3d(bin0_image, NULL, (int) 26, VShortRepn, &nl); bin0_image = VSelectBig(label_image, bin0_image); VImageAttrList(bin0_image) = VCopyAttrList(VImageAttrList(src)); return bin0_image; }
VImage GetMap(VAttrList list1,VAttrList list2,VImage mask,VShort minval) { VAttrListPosn posn; VImage src1[NSLICES],src2[NSLICES],map=NULL; size_t b,r,c,i,n; int nrows,ncols,nslices,nrows2,ncols2,nslices2; /* ** get image dimensions */ i = nrows = ncols = 0; for (VFirstAttr (list1, & posn); VAttrExists (& posn); VNextAttr (& posn)) { if (VGetAttrRepn (& posn) != VImageRepn) continue; VGetAttrValue (& posn, NULL,VImageRepn, & src1[i]); if (VPixelRepn(src1[i]) != VShortRepn) continue; if (VImageNRows(src1[i]) > nrows) nrows = VImageNRows(src1[i]); if (VImageNColumns(src1[i]) > ncols) ncols = VImageNColumns(src1[i]); i++; if (i >= NSLICES) VError(" too many slices"); } nslices = i; i = nrows2 = ncols2 = 0; for (VFirstAttr (list2, & posn); VAttrExists (& posn); VNextAttr (& posn)) { if (VGetAttrRepn (& posn) != VImageRepn) continue; VGetAttrValue (& posn, NULL,VImageRepn, & src2[i]); if (VPixelRepn(src2[i]) != VShortRepn) continue; if (VImageNRows(src2[i]) > nrows2) nrows2 = VImageNRows(src2[i]); if (VImageNColumns(src2[i]) > ncols2) ncols2 = VImageNColumns(src2[i]); i++; if (i >= NSLICES) VError(" too many slices"); } nslices2 = i; if (nslices2 != nslices) VError(" inconsistent number of slices: %d %d",nslices,nslices2); if (nrows2 != nrows) VError(" inconsistent number of rows: %d %d",nrows,nrows2); if (ncols2 != ncols) VError(" inconsistent number of cols: %d %d",ncols,ncols2); /* count number of voxels */ n = 0; for (b=0; b<nslices; b++) { if (VImageNRows(src1[b]) < 2) continue; if (VImageNRows(src2[b]) < 2) continue; for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(src1[b],0,r,c,VShort) < minval) continue; if (VPixel(src2[b],0,r,c,VShort) < minval) continue; if (VGetPixel(mask,b,r,c) < 0.5) continue; n++; } } } fprintf(stderr," nvoxels: %ld\n",(long)n); /* ** voxel addresses */ map = VCreateImage(1,5,n,VShortRepn); if (map == NULL) VError(" error allocating addr map"); VFillImage(map,VAllBands,0); VCopyImageAttrs (src1[0],map); VPixel(map,0,3,0,VShort) = nslices; VPixel(map,0,3,1,VShort) = nrows; VPixel(map,0,3,2,VShort) = ncols; i = 0; for (b=0; b<nslices; b++) { if (VImageNRows(src1[b]) < 2) continue; if (VImageNRows(src2[b]) < 2) continue; for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(src1[b],0,r,c,VShort) < minval) continue; if (VPixel(src2[b],0,r,c,VShort) < minval) continue; if (VGetPixel(mask,b,r,c) < 0.5) continue; VPixel(map,0,0,i,VShort) = b; VPixel(map,0,1,i,VShort) = r; VPixel(map,0,2,i,VShort) = c; i++; } } } return map; }
VAttrList VNCM(VAttrList list,VImage mask,VShort minval,VShort first,VShort length,VFloat threshold) { VAttrList out_list=NULL; VAttrListPosn posn; VImage src[NSLICES],map=NULL; VImage dest=NULL; size_t b,r,c,i,j,i1,n,m,nt,last,ntimesteps,nrows,ncols,nslices; gsl_matrix_float *mat=NULL; float *A=NULL,*ev=NULL; /* ** get image dimensions */ i = ntimesteps = nrows = ncols = 0; for (VFirstAttr (list, & posn); VAttrExists (& posn); VNextAttr (& posn)) { if (VGetAttrRepn (& posn) != VImageRepn) continue; VGetAttrValue (& posn, NULL,VImageRepn, & src[i]); if (VPixelRepn(src[i]) != VShortRepn) continue; if (VImageNBands(src[i]) > ntimesteps) ntimesteps = VImageNBands(src[i]); if (VImageNRows(src[i]) > nrows) nrows = VImageNRows(src[i]); if (VImageNColumns(src[i]) > ncols) ncols = VImageNColumns(src[i]); i++; if (i >= NSLICES) VError(" too many slices"); } nslices = i; /* get time steps to include */ if (length < 1) length = ntimesteps-2; last = first + length -1; if (last >= ntimesteps) last = ntimesteps-1; if (first < 0) first = 1; nt = last - first + 1; i1 = first+1; if (nt < 2) VError(" not enough timesteps, nt= %d",nt); fprintf(stderr,"# ntimesteps: %d, first= %d, last= %d, nt= %d\n", (int)ntimesteps,(int)first,(int)last,(int)nt); /* count number of voxels */ n = 0; for (b=0; b<nslices; b++) { if (VImageNRows(src[b]) < 2) continue; for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(src[b],i1,r,c,VShort) < minval) continue; if (VGetPixel(mask,b,r,c) < 0.5) continue; n++; } } } fprintf(stderr," nvoxels: %ld\n",(long)n); /* ** voxel addresses */ map = VCreateImage(1,5,n,VFloatRepn); if (map == NULL) VError(" error allocating addr map"); VFillImage(map,VAllBands,0); VPixel(map,0,3,0,VFloat) = nslices; VPixel(map,0,3,1,VFloat) = nrows; VPixel(map,0,3,2,VFloat) = ncols; i = 0; for (b=0; b<nslices; b++) { if (VImageNRows(src[b]) < 2) continue; for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(src[b],i1,r,c,VShort) < minval) continue; if (VGetPixel(mask,b,r,c) < 0.5) continue; VPixel(map,0,0,i,VFloat) = b; VPixel(map,0,1,i,VFloat) = r; VPixel(map,0,2,i,VFloat) = c; i++; } } } /* ** avoid casting to float, copy data to matrix */ mat = gsl_matrix_float_calloc(n,nt); for (i=0; i<n; i++) { b = VPixel(map,0,0,i,VFloat); r = VPixel(map,0,1,i,VFloat); c = VPixel(map,0,2,i,VFloat); float *ptr = gsl_matrix_float_ptr(mat,i,0); int k; j = 0; for (k=first; k<=last; k++) { if (j >= mat->size2) VError(" j= %d %d",j,mat->size2); if (k >= VImageNBands(src[b])) VError(" k= %d %d",k, VImageNBands(src[b])); *ptr++ = (float) VPixel(src[b],k,r,c,VShort); j++; } } /* ** compute similarity matrix */ m = (n*(n+1))/2; fprintf(stderr," matrix computation, n= %ld...\n",(long)n); A = (float *) calloc(m,sizeof(float)); if (!A) VError(" err allocating correlation matrix"); memset(A,0,m*sizeof(float)); size_t progress=0; #pragma omp parallel for shared(progress) private(j) schedule(guided) firstprivate(mat,A) for (i=0; i<n; i++) { if (i%100 == 0) fprintf(stderr," %d00\r",(int)(++progress)); const float *arr1 = gsl_matrix_float_const_ptr(mat,i,0); for (j=0; j<i; j++) { const float *arr2 = gsl_matrix_float_const_ptr(mat,j,0); const double v = Correlation(arr1,arr2,nt); const size_t k=j+i*(i+1)/2; if (k >= m) VError(" illegal addr k= %d, m= %d",k,m); A[k] = (float)v; } } fprintf(stderr," matrix done.\n"); gsl_matrix_float_free(mat); /* ** eigenvector centrality */ ev = (float *) VCalloc(n,sizeof(float)); DegreeCentrality(A,ev,n,threshold); dest = WriteOutput(src[0],map,nslices,nrows,ncols,ev,n); VSetAttr(VImageAttrList(dest),"name",NULL,VStringRepn,"DegreeCM"); out_list = VCreateAttrList(); VAppendAttr(out_list,"image",NULL,VImageRepn,dest); return out_list; }
VImage VTopoclass(VImage src, VImage dest) { int b=0,r=0,c=0,i,u=0; int bb,rr,cc,n; int b0,b1,r0,r1,c0; int nbands,nrows,ncols; int c1,c2,c3; VBit adj[27]; VUByte v; nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); dest = VCreateImage(nbands,nrows,ncols,VUByteRepn); for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { VPixel(dest,b,r,c,VUByte) = 0; if (VPixel(src,b,r,c,VBit) == 0) continue; /* ** get number of connected components in N26 */ i = 0; for (bb=b-1; bb<=b+1; bb++) { for (rr=r-1; rr<=r+1; rr++) { for (cc=c-1; cc<=c+1; cc++) { if (bb >= 0 && bb < nbands && rr >= 0 && rr < nrows && cc >= 0 && cc < ncols) u = VPixel(src,bb,rr,cc,VBit); else u = 0; adj[i++] = u; } } } adj[13] = 0; c1 = VNumComp26(adj); /* ** get number of connected components in -N18 ** 6-adjacent to the center voxel */ for (i=0; i<27; i++) { u = adj[i]; adj[i] = (u > 0) ? 0 : 1; } adj[13] = 0; adj[0] = 0; adj[2] = 0; adj[6] = 0; adj[8] = 0; adj[18] = 0; adj[20] = 0; adj[24] = 0; adj[26] = 0; c2 = VANumComp6(adj); c3 = VBNumComp6(adj); if (c2 == 0) /* interior point */ VPixel(dest,b,r,c,VUByte) = 1; else if (c1 == 0) /* isolated point */ VPixel(dest,b,r,c,VUByte) = 2; else if (c2 == 1 && c1 == 1) /* border point */ VPixel(dest,b,r,c,VUByte) = 3; else if (c2 == 1 && c1 == 2) /* curve point */ VPixel(dest,b,r,c,VUByte) = 4; else if (c2 == 1 && c1 > 2) /* curves junction */ VPixel(dest,b,r,c,VUByte) = 5; /* else if (c2 == 2 && c1 == 1 && c3 > 2) VPixel(dest,b,r,c,VUByte) = 8; */ else if (c2 == 2 && c1 == 1) /* surface point */ VPixel(dest,b,r,c,VUByte) = 6; else if (c2 == 2 && c1 >= 2) /* surface/curve junction */ VPixel(dest,b,r,c,VUByte) = 7; else if (c2 > 2 && c1 == 1) /* surfaces junction */ VPixel(dest,b,r,c,VUByte) = 8; else if (c2 > 2 && c1 >= 2) /* surfaces/curve junction */ VPixel(dest,b,r,c,VUByte) = 9; else /* undefined */ VPixel(dest,b,r,c,VUByte) = 10; /* n = VPixel(dest,b,r,c,VUByte); fprintf(stderr," %2d %2d %2d : %d %d %d, %d\n",b,r,c,c1,c2,c3,n); */ } } } /* ** get missed curves junctions */ for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(dest,b,r,c,VUByte) == 4) { n = 0; b0 = (b < 1) ? 0 : b - 1; b1 = (b >= nbands - 1) ? nbands - 1 : b + 1; for (bb=b0; bb<=b1; bb++) { r0 = (r < 1) ? 0 : r - 1; r1 = (r >= nrows - 1) ? nrows - 1 : r + 1; for (rr=r0; rr<=r1; rr++) { c0 = (c < 1) ? 0 : c - 1; c1 = (c >= ncols - 1) ? ncols - 1 : c + 1; for (cc=c0; cc<=c1; cc++) { v = VPixel(dest,bb,rr,cc,VUByte); if (v == 3 || v == 4 || v == 5) n++; } } } if (n > 3) { VPixel(dest,b,r,c,VUByte) = 5; } } } } } VJunction(src,dest); VCopyImageAttrs (src, dest); return dest; }
VImage VDoMulticomp3d(VImage src, VImage multicomp, VBoolean verbose) { VString str; Volumes volumes; Volume vol; VImage tmp = NULL, label_image = NULL, dest = NULL; VFloat *src_pp, *dst_pp, u, zthr = 0, zmax = 0, voxsize = 1, sym = 0; VBit *bin_pp; int i, nl, size, nbands, nrows, ncols, npixels; int b, r, c, b0, r0, c0; int nflag, pflag; float x0, x1, x2; float sign = 1; float voxel[3], ca[3], extent[3]; /* ** read multicomp file header */ voxsize = 1; if(VGetAttr(VImageAttrList(multicomp), "voxel_size", NULL, VFloatRepn, (VPointer) & voxsize) != VAttrFound) VError(" attribute 'voxel_size' not found"); if(VGetAttr(VImageAttrList(multicomp), "zthr", NULL, VFloatRepn, (VPointer) &zthr) != VAttrFound) VError(" attribute 'zthr' not found"); /* ** read src header */ if(verbose) { if(VGetAttr(VImageAttrList(src), "voxel", NULL, VStringRepn, (VPointer) & str) != VAttrFound) VError(" attribute 'voxel' not found"); sscanf(str, "%f %f %f", &x0, &x1, &x2); if(ABS(x0 * x1 * x2 - voxsize) > 0.01) VError(" voxel sizes do not match %.3f %.3f %.3f", x0, x1, x2); voxel[0] = x0; voxel[1] = x1; voxel[2] = x2; if(VGetAttr(VImageAttrList(src), "ca", NULL, VStringRepn, (VPointer) & str) != VAttrFound) VError(" attribute 'ca' not found"); sscanf(str, "%f %f %f", &x0, &x1, &x2); ca[0] = x0; ca[1] = x1; ca[2] = x2; if(VGetAttr(VImageAttrList(src), "extent", NULL, VStringRepn, (VPointer) & str) != VAttrFound) VError(" attribute 'extent' not found"); sscanf(str, "%f %f %f", &x0, &x1, &x2); extent[0] = x0; extent[1] = x1; extent[2] = x2; } nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); npixels = VImageNPixels(src); tmp = VCreateImage(nbands, nrows, ncols, VBitRepn); dest = VCopyImage(src, NULL, VAllBands); VFillImage(dest, VAllBands, 0); /* ** positive threshold */ nflag = pflag = 0; src_pp = VImageData(src); bin_pp = VImageData(tmp); for(i = 0; i < npixels; i++) { *bin_pp = 0; u = *src_pp; if(u > 0 && u >= zthr) *bin_pp = 1; src_pp++; bin_pp++; } label_image = VLabelImage3d(tmp, label_image, (int)26, VShortRepn, &nl); if(nl < 1 && pflag == 0) { VWarning(" no voxels above threshold %.3f", zthr); goto next; } else pflag++; volumes = VImage2Volumes(label_image); for(vol = volumes->first; vol != NULL; vol = vol->next) { sign = 1; size = VolumeSize(vol); zmax = VolumeZMax(vol, src, (float)1, &b, &r, &c); sym = VolumeSym(vol, src, sign, zthr); if(CheckValueSymm(multicomp, size, zmax, sym) == FALSE) { VolumeZero(vol, tmp); } else { if(verbose) { VPixel2Tal(ca, voxel, extent, b, r, c, &x0, &x1, &x2); c0 = VRint(x0); r0 = VRint(x1); b0 = VRint(x2); fprintf(stderr, " nvoxels: %5d, zmax: %7.3f, sym: %.3f, addr: %3d %3d %3d\n", size, zmax, sym, c0, r0, b0); } } } src_pp = VImageData(src); dst_pp = VImageData(dest); bin_pp = VImageData(tmp); for(i = 0; i < npixels; i++) { if(*bin_pp > 0) *dst_pp = *src_pp; src_pp++; dst_pp++; bin_pp++; } /* ** negative threshold */ next: src_pp = VImageData(src); bin_pp = VImageData(tmp); for(i = 0; i < npixels; i++) { *bin_pp = 0; u = *src_pp; if(u < 0 && -u >= zthr) *bin_pp = 1; src_pp++; bin_pp++; } label_image = VLabelImage3d(tmp, label_image, (int)26, VShortRepn, &nl); if(nl < 1 && nflag == 0) { /* VWarning(" no voxels below negative threshold %.3f",-zthr); */ goto ende; } else nflag++; volumes = VImage2Volumes(label_image); for(vol = volumes->first; vol != NULL; vol = vol->next) { sign = -1; size = VolumeSize(vol); zmax = VolumeZMax(vol, src, sign, &b, &r, &c); sym = VolumeSym(vol, src, sign, zthr); if(CheckValueSymm(multicomp, size, zmax, sym) == FALSE) { VolumeZero(vol, tmp); } else { if(verbose) { VPixel2Tal(ca, voxel, extent, b, r, c, &x0, &x1, &x2); c0 = VRint(x0); r0 = VRint(x1); b0 = VRint(x2); fprintf(stderr, " nvoxels: %5d, zmax: %7.3f, sym: %.3f, addr: %3d %3d %3d\n", size, zmax, sym, c0, r0, b0); } } } src_pp = VImageData(src); dst_pp = VImageData(dest); bin_pp = VImageData(tmp); for(i = 0; i < npixels; i++) { if(*bin_pp > 0) *dst_pp = *src_pp; src_pp++; dst_pp++; bin_pp++; } ende: if(nflag == 0 && pflag == 0) VError(" no voxels passed threshold"); return dest; }
/*! \fn void VDeriche2d(VImage src,VFloat alpha,VImage *gradr,VImage *gradc); \param src input image (ubyte repn) \param alpha parameter controlling edge strength \param *gradr output gradient in row direction (float repn) \param *gradc output gradient in column direction (float repn) */ void VDeriche2d (VImage src,VFloat alpha,VImage *gradr,VImage *gradc) { int b,r,c; int nbands,nrows,ncols,npixels,len; double s,a,a0,a1,a2,a3,b1,b2,exp_alpha; float *left,*right; nbands = VImageNBands (src); nrows = VImageNRows (src); ncols = VImageNColumns (src); npixels = nbands * nrows * ncols; len = (ncols > nrows) ? ncols : nrows; left = (float *) VMalloc(sizeof(float) * len); right = (float *) VMalloc(sizeof(float) * len); exp_alpha = exp((double) ( - alpha)); a = 1.0 * exp_alpha; b1 = -2.0 * exp_alpha; b2 = exp((double) (-2.0 * alpha)); s = ((1.0 - exp_alpha) * (1.0 - exp_alpha)) / (1.0 + 2.0 * alpha * exp_alpha - b2); a0 = s; a1 = s * (alpha - 1.0) * exp_alpha; a2 = a1 - s * b1; a3 = - s * b2; /* col-grad */ *gradc = VCreateImage(nbands,nrows,ncols,VFloatRepn); for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { /* left-to-right */ left[0] = 0; left[1] = 0; for (c=2; c<ncols; c++) { left[c] = (VFloat) VGetPixel(src,b,r,c-1) - b1 * left[c-1] - b2 * left[c-2]; } /* right-to-left */ right[ncols-1] = 0; right[ncols-2] = 0; for (c=ncols-3; c>=0; c--) { right[c] = (VFloat) VGetPixel(src,b,r,c+1) - b1 * right[c+1] - b2 * right[c+2]; } /* combine */ for (c=0; c<ncols; c++) { VPixel(*gradc,b,r,c,VFloat) = a * (left[c] - right[c]); } } } /* row-smooth */ for (b=0; b<nbands; b++) { for (c=0; c<ncols; c++) { /* left-to-right */ left[0] = 0; left[1] = 0; for (r=2; r<nrows; r++) { left[r] = a0 * (VFloat) VPixel(*gradc,b,r,c,VFloat) + a1 * (VFloat) VPixel(*gradc,b,r-1,c,VFloat) - b1 * left[r-1] - b2 * left[r-2]; } /* right-to-left */ right[nrows-1] = 0; right[nrows-2] = 0; for (r=nrows-3; r>=0; r--) { right[r] = a2 * (VFloat) VPixel(*gradc,b,r+1,c,VFloat) + a3 * (VFloat) VPixel(*gradc,b,r+2,c,VFloat) - b1 * right[r+1] - b2 * right[r+2]; } /* combine */ for (r=0; r<nrows; r++) { VPixel(*gradc,b,r,c,VFloat) += left[r] + right[r]; } } } /* ** row-grad */ *gradr = VCreateImage(nbands,nrows,ncols,VFloatRepn); /* row-deriv */ for (b=0; b<nbands; b++) { for (c=0; c<ncols; c++) { /* left-to-right */ left[0] = 0; left[1] = 0; for (r=2; r<nrows; r++) { left[r] = (VFloat) VGetPixel(src,b,r-1,c) - b1 * left[r-1] - b2 * left[r-2]; } /* right-to-left */ right[ncols-1] = 0; right[ncols-2] = 0; for (r=nrows-3; r>=0; r--) { right[r] = (VFloat) VGetPixel(src,b,r+1,c) - b1 * right[r+1] - b2 * right[r+2]; } /* combine */ for (r=0; r<nrows; r++) { VPixel(*gradr,b,r,c,VFloat) = a * (left[r] - right[r]); } } } /* col-smooth */ for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { /* left-to-right */ left[0] = 0; left[1] = 0; for (c=2; c<ncols; c++) { left[c] = a0 * (VFloat) VPixel(*gradr,b,r,c,VFloat) + a1 * (VFloat) VPixel(*gradr,b,r,c-1,VFloat) - b1 * left[c-1] - b2 * left[c-2]; } /* right-to-left */ right[ncols-1] = 0; right[ncols-2] = 0; for (c=ncols-3; c>=0; c--) { right[r] = a2 * (VFloat) VPixel(*gradr,b,r,c+1,VFloat) + a3 * (VFloat) VPixel(*gradr,b,r,c+2,VFloat) - b1 * right[c+1] - b2 * right[c+2]; } /* combine */ for (c=0; c<ncols; c++) { VPixel(*gradr,b,r,c,VFloat) += left[c] + right[c]; } } } VFree(left); VFree(right); }
VImage SimilarityMatrix(VAttrList list, VImage mask, VShort minval, VShort fisher) { VAttrListPosn posn; VImage src[NSLICES], dest = NULL, map = NULL; int b, r, c, i, j, n, ntimesteps, nrows, ncols, nslices; double u, x, y, smin, smax, tiny = 1.0e-6; gsl_matrix_float *mat = NULL; /* ** get image dimensions */ i = ntimesteps = nrows = ncols = 0; for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src[i]); if(VPixelRepn(src[i]) != VShortRepn) continue; if(VImageNBands(src[i]) > ntimesteps) ntimesteps = VImageNBands(src[i]); if(VImageNRows(src[i]) > nrows) nrows = VImageNRows(src[i]); if(VImageNColumns(src[i]) > ncols) ncols = VImageNColumns(src[i]); i++; if(i >= NSLICES) VError(" too many slices"); } nslices = i; n = 0; for(b = 0; b < nslices; b++) { if(VImageNRows(src[b]) < 2) continue; for(r = 0; r < nrows; r++) { for(c = 0; c < ncols; c++) { if(VPixel(src[b], 0, r, c, VShort) < minval) continue; if(VGetPixel(mask, b, r, c) < 0.1) continue; n++; } } } fprintf(stderr, " n: %d\n", n); /* ** voxel addresses */ map = VCreateImage(1, 5, n, VFloatRepn); VFillImage(map, VAllBands, 0); VPixel(map, 0, 3, 0, VFloat) = nslices; VPixel(map, 0, 3, 1, VFloat) = nrows; VPixel(map, 0, 3, 2, VFloat) = ncols; i = 0; for(b = 0; b < nslices; b++) { if(VImageNRows(src[b]) < 2) continue; for(r = 0; r < nrows; r++) { for(c = 0; c < ncols; c++) { if(VPixel(src[b], 0, r, c, VShort) < minval) continue; if(VGetPixel(mask, b, r, c) < 0.1) continue; VPixel(map, 0, 0, i, VFloat) = b; VPixel(map, 0, 1, i, VFloat) = r; VPixel(map, 0, 2, i, VFloat) = c; i++; } } } /* ini output image */ if(n < 8000) dest = VCreateImage(1, n, n, VFloatRepn); else if(n >= 8000 && n < 10000) dest = VCreateImage(1, n, n, VShortRepn); else dest = VCreateImage(1, n, n, VSByteRepn); VFillImage(dest, VAllBands, 0); smin = VPixelMinValue(dest); smax = VPixelMaxValue(dest); /* ** avoid casting to float, copy data to matrix */ mat = gsl_matrix_float_calloc(n, ntimesteps); for(i = 0; i < n; i++) { b = VPixel(map, 0, 0, i, VFloat); r = VPixel(map, 0, 1, i, VFloat); c = VPixel(map, 0, 2, i, VFloat); float *ptr = gsl_matrix_float_ptr(mat, i, 0); int k; j = 0; for(k = 0; k < ntimesteps; k++) { if(j >= mat->size2) VError(" j= %d %d", j, mat->size2); if(k >= VImageNBands(src[b])) VError(" k= %d %d", k, VImageNBands(src[b])); *ptr++ = (float) VPixel(src[b], k, r, c, VShort); j++; } } /* ** main process loop */ for(i = 0; i < n; i++) { if(i % 50 == 0) fprintf(stderr, " i: %4d\r", i); const float *arr1 = gsl_matrix_float_const_ptr(mat, i, 0); for(j = 0; j <= i; j++) { const float *arr2 = gsl_matrix_float_const_ptr(mat, j, 0); u = Correlation(arr1, arr2, ntimesteps); /* Fisher r-to-z transform */ if(fisher) { x = 1 + u; y = 1 - u; if(x < tiny) x = tiny; if(y < tiny) y = tiny; u = 0.5 * log(x / y); } if(VPixelRepn(dest) != VFloatRepn) { u *= smax; if(u < smin) u = smin; if(u > smax) u = smax; } VSetPixel(dest, 0, i, j, u); VSetPixel(dest, 0, j, i, u); } } VCopyImageAttrs(src[0], dest); VSetAttr(VImageAttrList(dest), "similarity_metric", NULL, VStringRepn, "corr_pearson"); VSetAttr(VImageAttrList(dest), "name", NULL, VStringRepn, "similarity_matrix"); VSetAttr(VImageAttrList(dest), "map", NULL, VImageRepn, map); return dest; }
int main(int argc, char *argv[]) { static VFloat reso = -1.0; static VLong itype = 0; static VBoolean flip = TRUE; static VBoolean reorder = TRUE; static VOptionDescRec options[] = { { "reso", VFloatRepn, 1, (VPointer) &reso, VOptionalOpt, NULL, "New voxel resolution in mm, def: -1 means min(1.0,\"best source resolution\")" }, { "flip", VBooleanRepn, 1, (VPointer) &flip, VOptionalOpt, NULL, "Whether to flip to natural convention" }, { "reorder", VBooleanRepn, 1, (VPointer) &reorder, VOptionalOpt, NULL, "Whether to reorder axial slices from axial source image" }, { "interpolation", VLongRepn, 1, & itype, VOptionalOpt, ITYPDict, "Type of interpolation (0: linear, 1: nearest neighbour, 2: cubic spline)" } }; FILE *in_file, *out_file; VAttrList list; VAttrListPosn posn; int nobjects = 0; VImage src = NULL, dest = NULL, result = NULL; int i, b, r, c, nbands, nrows, ncols; VString str, newstr, fixpointString, caString, cpString; float fix_c, fix_r, fix_b; float ca_c, ca_r, ca_b; float cp_c, cp_r, cp_b; float x, y, z, min; VDouble v, scale_band, scale_row, scale_col; float scale[3], shift[3]; /* print information */ char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "visotrop V%s", ver); fprintf(stderr, "%s\n", prg_name); fflush(stderr); /* Parse command line arguments: */ VParseFilterCmd(VNumber(options), options, argc, argv, & in_file, & out_file); /* Read source image(s): */ if(!(list = VReadFile(in_file, NULL))) exit(EXIT_FAILURE); /* Scale each object: */ for(VFirstAttr(list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { switch(VGetAttrRepn(& posn)) { case VImageRepn: VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VGetAttr(VImageAttrList(src), "voxel", NULL, VStringRepn, (VPointer) & str) == VAttrFound) { sscanf(str, "%f %f %f", &x, &y, &z); fprintf(stderr, " voxel: %f %f %f\n", x, y, z); min = x < y ? x : y; min = z < min ? z : min; /* if resolution is not set, use default value 1 or smaler value if the image resolution is better */ if(reso < 0.0) reso = min < 1.0 ? min : 1.0; if(reso <= 0.0) exit(EXIT_FAILURE); fprintf(stderr, " new resolution: %f \n", reso); scale_col = x / reso; scale_row = y / reso; scale_band = z / reso; nbands = VImageNBands(src) * scale_band; nrows = VImageNRows(src) * scale_row; ncols = VImageNColumns(src) * scale_col; if(VImageNBands(src) == nbands && VImageNRows(src) == nrows && VImageNColumns(src) == ncols) { itype = 0; } fprintf(stderr, " interpolation type: %s\n", ITYPDict[itype].keyword); fprintf(stderr, " old dim: %3d %3d %3d\n", VImageNBands(src), VImageNRows(src), VImageNColumns(src)); for(i = 0; i < 3; i++) shift[i] = scale[i] = 0; scale[0] = scale_band; scale[1] = scale_row; scale[2] = scale_col; switch(itype) { /* trilinear interpolation resampling */ case 0: dest = VTriLinearScale3d(src, NULL, (int)nbands, (int)nrows, (int)ncols, shift, scale); break; /* nearest neightbour resampling */ case 1: dest = VNNScale3d(src, NULL, (int)nbands, (int)nrows, (int)ncols, shift, scale); break; /* cubic spline */ case 2: dest = VCubicSplineScale3d(src, NULL, (int)nbands, (int)nrows, (int)ncols, shift, scale); break; case 3: /* no interpolation, just reshuffle */ dest = VCopyImage(src, NULL, VAllBands); break; default: VError(" unknown resampling type %d", itype); } if(! dest) exit(EXIT_FAILURE); /*aa 2003/09/11 added function not to rotate siemens data*/ if(! VGetAttr(VImageAttrList(src), "orientation", NULL, VStringRepn, (VPointer) & str) == VAttrFound) VError(" attribute 'orientation' missing"); if(strcmp(str, "axial") == 0) { fprintf(stderr, " new dim: %3d %3d %3d\n", nbands, nrows, ncols); result = VCreateImage(nbands, nrows, ncols, VPixelRepn(src)); VFillImage(result, VAllBands, 0); for(b = 0; b < nbands; b++) for(r = 0; r < nrows; r++) for(c = 0; c < ncols; c++) { v = VGetPixel(dest, b, r, c); if((flip == FALSE) && (reorder == FALSE)) VSetPixel(result, b, r, ncols - c - 1, v); else if((flip == TRUE) && (reorder == FALSE)) VSetPixel(result, b, r, c, v); else if((flip == FALSE) && (reorder == TRUE)) VSetPixel(result, nbands - b - 1, r, ncols - c - 1, v); else if((flip == TRUE) && (reorder == TRUE)) VSetPixel(result, nbands - b - 1, r, c, v); } } else if(strcmp(str, "sagittal") == 0) { /* re-arrange from sagittal to axial orientation */ fprintf(stderr, " new dim: %3d %3d %3d\n", nrows, ncols, nbands); result = VCreateImage(nrows, ncols, nbands, VPixelRepn(src)); VFillImage(result, VAllBands, 0); for(b = 0; b < nbands; b++) for(r = 0; r < nrows; r++) for(c = 0; c < ncols; c++) { v = VGetPixel(dest, b, r, c); if(flip == FALSE) VSetPixel(result, r, c, nbands - b - 1, v); else VSetPixel(result, r, c, b, v); } } else if(strcmp(str, "coronal") == 0) { /* re-arrange from coronal to axial orientation */ fprintf(stderr, " new dim: %3d %3d %3d\n", nrows, nbands, ncols); result = VCreateImage(nrows, nbands, ncols, VPixelRepn(src)); VFillImage(result, VAllBands, 0); for(b = 0; b < nbands; b++) for(r = 0; r < nrows; r++) for(c = 0; c < ncols; c++) { v = VGetPixel(dest, b, r, c); if(flip == FALSE) VSetPixel(result, r, b, ncols - c - 1, v); else VSetPixel(result, r, b, c, v); } } else { VError(" unknown resampling type %d", itype); exit(EXIT_FAILURE); } /* copy attributes from source image */ VCopyImageAttrs(src, result); // [TS] 08/03/27 // correct 'fixpoint', 'ca' and 'cp' if they exist in the source image // // NOTE: // this is only done when no flipping or reordering is requested :-( // (WARNING!!!!) '-flip true' actually means that no flipping is done (WHAAAAT ????) // and therefore we test for reorder = false and flip = true fixpointString = VMalloc(80); caString = VMalloc(80); cpString = VMalloc(80); VBoolean _issueWarning = FALSE; if(VGetAttr(VImageAttrList(src), "fixpoint", NULL, VStringRepn, (VPointer)&fixpointString) == VAttrFound) { if(reorder == FALSE && flip == TRUE) { sscanf(fixpointString, "%f %f %f", &fix_c, &fix_r, &fix_b); fix_c *= scale_col; fix_r *= scale_row; fix_b *= scale_band; sprintf((char *)fixpointString, "%f %f %f", fix_c, fix_r, fix_b); VSetAttr(VImageAttrList(result), "fixpoint", NULL, VStringRepn, fixpointString); } else { _issueWarning = TRUE; } } if(VGetAttr(VImageAttrList(src), "ca", NULL, VStringRepn, (VPointer)&caString) == VAttrFound) { if(reorder == FALSE && flip == TRUE) { sscanf(caString, "%f %f %f", &ca_c, &ca_r, &ca_b); ca_c *= scale_col; ca_r *= scale_row; ca_b *= scale_band; sprintf((char *)caString, "%f %f %f", ca_c, ca_r, ca_b); VSetAttr(VImageAttrList(result), "ca", NULL, VStringRepn, caString); } else { _issueWarning = TRUE; } } if(VGetAttr(VImageAttrList(src), "cp", NULL, VStringRepn, (VPointer)&cpString) == VAttrFound) { if(reorder == FALSE && flip == TRUE) { sscanf(cpString, "%f %f %f", &cp_c, &cp_r, &cp_b); cp_c *= scale_col; cp_r *= scale_row; cp_b *= scale_band; sprintf((char *)cpString, "%f %f %f", cp_c, cp_r, cp_b); VSetAttr(VImageAttrList(result), "cp", NULL, VStringRepn, cpString); } else { _issueWarning = TRUE; } } if(_issueWarning) { VWarning("Attributes 'fixpoint', 'ca' and 'cp' exist but were not corrected and are therefore likely to be wrong"); VWarning("This was caused by setting -flip to false or -reorder to true"); VWarning("Please correct the values manually using vattredit"); } /* set the attributes to the changed values */ newstr = VMalloc(80); sprintf((char *)newstr, "%f %f %f", reso, reso, reso); VSetAttr(VImageAttrList(result), "voxel", NULL, VStringRepn, newstr); VSetAttr(VImageAttrList(result), "orientation", NULL, VStringRepn, "axial"); if(flip) VSetAttr(VImageAttrList(result), "convention", NULL, VStringRepn, "natural"); else VSetAttr(VImageAttrList(result), "convention", NULL, VStringRepn, "radiologic"); } VSetAttrValue(& posn, NULL, VImageRepn, result); VDestroyImage(src); break; default: continue; } nobjects++; } /* Make History */ VHistory(VNumber(options), options, prg_name, &list, &list); /* Write the results to the output file: */ if(! VWriteFile(out_file, list)) exit(EXIT_FAILURE); fprintf(stderr, "%s: done.\n", argv[0]); return EXIT_SUCCESS; }
int main (int argc, char* argv[]) { VString inname; /* name of input images */ VString outname; /* name of output images */ VString fieldname; /* name of deformation field */ VBoolean verbose = TRUE; /* verbose flag */ VOptionDescRec options[] = /* options of program */ { {"in", VStringRepn, 1, &inname, VRequiredOpt, NULL, "Input image"}, {"out", VStringRepn, 1, &outname, VRequiredOpt, NULL, "Deformed output image"}, {"field", VStringRepn, 1, &fieldname, VRequiredOpt, NULL, "3D deformation field"}, {"verbose", VBooleanRepn, 1, &verbose, VOptionalOpt, NULL, "Show status messages. Optional"} }; VAttrList in_history=NULL; /* history of input images */ VAttrList field_history=NULL; /* history of deformation field */ VAttrList In; /* input images */ VImage Dx, Dy, Dz; /* field images */ VAttrListPosn pos; /* position in list */ VImage in; /* image in list */ float fx, fy, fz; /* scaling factors */ VImage dx, dy, dz; /* scaled deformation field */ VAttrListPosn rider; /* functional data rider */ int bands, rows, columns, steps; /* size of functional data */ VImage data; /* functional data */ VShort *src, *dest; /* functional data pointer */ VBoolean success; /* success flag */ int n, t, z; /* indices */ /* print information */ char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "vdeform V%s", ver); fprintf (stderr, "%s\n", prg_name); fflush (stderr); /* parse command line */ if (!VParseCommand (VNumber (options), options, &argc, argv)) { if (argc > 1) VReportBadArgs (argc, argv); VReportUsage (argv[0], VNumber (options), options, NULL); exit (1); } /* read input images */ if (verbose) {fprintf (stderr, "Reading input image '%s' ...\n", inname); fflush (stderr);} ReadImages (inname, In, in_history); if (!In) exit (2); /* read deformation field */ if (verbose) {fprintf (stderr, "Reading 3D deformation field '%s' ...\n", fieldname); fflush (stderr);} ReadField (fieldname, Dx, Dy, Dz, field_history); if (!Dx || !Dy || !Dz) exit (3); /* deform anatomical images */ for (VFirstAttr (In, &pos); VAttrExists (&pos); VNextAttr (&pos)) { /* get image */ VGetAttrValue (&pos, NULL, VImageRepn, &in); if (VPixelRepn (in) != VUByteRepn) break; /* compare image and field */ if (verbose) {fprintf (stderr, "Comparing anatomical image and deformation field ...\n"); fflush (stderr);} if (!Compatible (in, Dx)) exit (4); if (!Compatible (in, Dy)) exit (4); if (!Compatible (in, Dz)) exit (4); /* deform image */ if (verbose) {fprintf (stderr, "Deforming anatomical image ...\n"); fflush (stderr);} RTTI (in, TrilinearInverseDeform, (in, Dx, Dy, Dz)); VSetAttrValue (&pos, NULL, VImageRepn, in); } /* deform map images */ for (; VAttrExists (&pos); VNextAttr (&pos)) { /* get image */ VGetAttrValue (&pos, NULL, VImageRepn, &in); if (VPixelRepn (in) != VFloatRepn) break; /* scale field */ if (verbose) {fprintf (stderr, "Scaling deformation field ...\n"); fflush (stderr);} fx = (float) VImageNColumns (in) / (float) VImageNColumns (Dx); fy = (float) VImageNRows (in) / (float) VImageNRows (Dy); fz = (float) VImageNBands (in) / (float) VImageNBands (Dz); TrilinearScale<VFloat> (Dx, fx, fy, fz, dx); Multiply<VFloat> (dx, fx); TrilinearScale<VFloat> (Dy, fx, fy, fz, dy); Multiply<VFloat> (dy, fy); TrilinearScale<VFloat> (Dz, fx, fy, fz, dz); Multiply<VFloat> (dz, fz); /* compare image and field */ if (verbose) {fprintf (stderr, "Comparing map image and deformation field ...\n"); fflush (stderr);} if (!Compatible (in, dx)) exit (5); if (!Compatible (in, dy)) exit (5); if (!Compatible (in, dz)) exit (5); /* deform image */ if (verbose) {fprintf (stderr, "Deforming map image ...\n"); fflush (stderr);} RTTI (in, TrilinearInverseDeform, (in, dx, dy, dz)); VSetAttrValue (&pos, NULL, VImageRepn, in); /* clean-up */ VDestroyImage (dx); VDestroyImage (dy); VDestroyImage (dz); } /* deform functional images */ if (VAttrExists (&pos)) { /* get data size */ bands = rows = columns = steps = 0; for (rider = pos; VAttrExists (&rider); VNextAttr (&rider)) { /* get image */ VGetAttrValue (&rider, NULL, VImageRepn, &data); if (VPixelRepn (data) != VShortRepn) break; /* store image size */ if (VImageNBands (data) > steps) steps = VImageNBands (data); if (VImageNRows (data) > rows) rows = VImageNRows (data); if (VImageNColumns (data) > columns) columns = VImageNColumns (data); bands++; } in = VCreateImage (bands, rows, columns, VShortRepn); /* scale field */ if (verbose) {fprintf (stderr, "Scaling deformation field ...\n"); fflush (stderr);} fx = (float) VImageNColumns (in) / (float) VImageNColumns (Dx); fy = (float) VImageNRows (in) / (float) VImageNRows (Dy); fz = (float) VImageNBands (in) / (float) VImageNBands (Dz); TrilinearScale<VFloat> (Dx, fx, fy, fz, dx); Multiply<VFloat> (dx, fx); TrilinearScale<VFloat> (Dy, fx, fy, fz, dy); Multiply<VFloat> (dy, fy); TrilinearScale<VFloat> (Dz, fx, fy, fz, dz); Multiply<VFloat> (dz, fz); /* compare image and field */ if (verbose) {fprintf (stderr, "Comparing functional images and deformation field ...\n"); fflush (stderr);} if (!Compatible (in, dx)) exit (6); if (!Compatible (in, dy)) exit (6); if (!Compatible (in, dz)) exit (6); /* expand zero images */ for (rider = pos, z = 0; z < bands; z++, VNextAttr (&rider)) { VGetAttrValue (&rider, NULL, VImageRepn, &data); if (FunctionalZero (data)) { FunctionalResize (data, steps, rows, columns); VSetAttrValue (&rider, NULL, VImageRepn, data); } } /* deform images */ if (verbose) {fprintf (stderr, "Deforming functional images ...\n"); fflush (stderr);} for (t = 0; t < steps; t++) { /* collect data */ dest = (VShort*) VPixelPtr (in, 0, 0, 0); for (rider = pos, z = 0; z < bands; z++, VNextAttr (&rider)) { VGetAttrValue (&rider, NULL, VImageRepn, &data); src = (VShort*) VPixelPtr (data, t, 0, 0); for (n = 0; n < rows * columns; ++n) *(dest++) = *(src++); } /* deform image */ if (verbose) {fprintf (stderr, "Timestep %d of %d ...\r", t + 1, steps); fflush (stderr);} RTTI (in, TrilinearInverseDeform, (in, dx, dy, dz)); /* spread data */ src = (VShort*) VPixelPtr (in, 0, 0, 0); for (rider = pos, z = 0; z < bands; z++, VNextAttr (&rider)) { VGetAttrValue (&rider, NULL, VImageRepn, &data); dest = (VShort*) VPixelPtr (data, t, 0, 0); for (n = 0; n < rows * columns; ++n) *(dest++) = *(src++); } } /* collapse zero images */ for (rider = pos, z = 0; z < bands; z++, VNextAttr (&rider)) { VGetAttrValue (&rider, NULL, VImageRepn, &data); if (FunctionalZero (data)) { FunctionalResize (data, 1, 1, 1); VSetAttrValue (&rider, NULL, VImageRepn, data); } } /* clean-up */ VDestroyImage (in); VDestroyImage (dx); VDestroyImage (dy); VDestroyImage (dz); /* proceed */ pos = rider; } /* check list */ if (VAttrExists (&pos)) { VError ("Remaining image does not contain valid data"); exit (7); } /* Prepend History */ VPrependHistory(VNumber(options),options,prg_name,&in_history); /* write output images */ if (verbose) {fprintf (stderr, "Writing output image '%s' ...\n", outname); fflush (stderr);} success = WriteImages (outname, In, in_history); if (!success) exit (8); /* clean-up VDestroyAttrList (inhistory); VDestroyAttrList (fieldhistory); VDestroyAttrList (In); VDestroyImage (Dx); VDestroyImage (Dy); VDestroyImage (Dz); */ /* exit */ if (verbose) {fprintf (stderr, "Finished.\n"); fflush (stderr);} return 0; } /* main */
VImage VTopSmoothImage3d(VImage bit_image, VImage grey_image, VImage result, VLong neighb, VLong numiter) { long nbands, nrows, ncols, npixels; VRepnKind repn; long i, i0, i1, n, iter, npts, u; long b0, b1, r0, r1, c0, c1, b, r, c; long n1, n6, n18, n26; int isum; double sum, norm = 0; VBit *dest_pp, *bit_pp; VUByte *ubyte_pp; int background = 0; VPoint *array = NULL; repn = VPixelRepn(bit_image); if(repn != VBitRepn) VError("Smooth3d: repn must be bit"); nbands = VImageNBands(bit_image); nrows = VImageNRows(bit_image); ncols = VImageNColumns(bit_image); npixels = nbands * nrows * ncols; if(result == NULL) result = VCreateImage(nbands, nrows, ncols, repn); if(! result) return NULL; bit_pp = VPixelPtr(bit_image, 0, 0, 0); dest_pp = VPixelPtr(result, 0, 0, 0); for(i = 0; i < npixels; i++) *dest_pp++ = *bit_pp++; n1 = 8; n6 = 4; n18 = 2; n26 = 1; switch(neighb) { case 0: norm = n1 + 6 * n6; break; case 1: norm = n1 + 6 * n6 + 12 * n18; break; case 2: norm = n1 + 6 * n6 + 12 * n18 + 8 * n26; break; default: ; } n = 1; ubyte_pp = VPixelPtr(grey_image, 0, 0, 0); for(i = 0; i < npixels; i++) if(*ubyte_pp++ > background) n++; array = (VPoint *) VMalloc(sizeof(VPoint) * (n + 2)); for(i = 0; i < n + 2; i++) array[i].val = array[i].b = array[i].r = array[i].c = 0; n = 1; for(b = 0; b < nbands; b++) { for(r = 0; r < nrows; r++) { for(c = 0; c < ncols; c++) { u = VPixel(grey_image, b, r, c, VUByte); if(u > background) { array[n].b = b; array[n].r = r; array[n].c = c; array[n].val = (float)u; n++; } } } } npts = n; VPoint_hpsort(n - 1, array); iter = 0; n = 100; while(n > 1 && iter < numiter) { iter++; n = 0; for(i = 1; i < npts; i++) { b = array[i].b; r = array[i].r; c = array[i].c; b0 = (b < 1) ? 0 : b - 1; b1 = (b > nbands - 2) ? nbands - 1 : b + 1; r0 = (r < 1) ? 0 : r - 1; r1 = (r > nrows - 2) ? nrows - 1 : r + 1; c0 = (c < 1) ? 0 : c - 1; c1 = (c > ncols - 2) ? ncols - 1 : c + 1; isum = 0; i1 = VPixel(bit_image, b, r, c, VBit); isum += (int) i1 * n1; isum += (int) VPixel(bit_image, b0, r, c, VBit) * n6; isum += (int) VPixel(bit_image, b, r0, c, VBit) * n6; isum += (int) VPixel(bit_image, b, r, c0, VBit) * n6; isum += (int) VPixel(bit_image, b1, r, c, VBit) * n6; isum += (int) VPixel(bit_image, b, r1, c, VBit) * n6; isum += (int) VPixel(bit_image, b, r, c1, VBit) * n6; if(neighb == 1) { isum += VPixel(bit_image, b0, r0, c, VBit) * n18; isum += (int) VPixel(bit_image, b, r0, c0, VBit) * n18; isum += (int) VPixel(bit_image, b0, r, c0, VBit) * n18; isum += (int) VPixel(bit_image, b1, r1, c, VBit) * n18; isum += (int) VPixel(bit_image, b, r1, c1, VBit) * n18; isum += (int) VPixel(bit_image, b1, r, c1, VBit) * n18; isum += (int) VPixel(bit_image, b1, r0, c, VBit) * n18; isum += (int) VPixel(bit_image, b, r1, c0, VBit) * n18; isum += (int) VPixel(bit_image, b1, r, c0, VBit) * n18; isum += (int) VPixel(bit_image, b0, r1, c, VBit) * n18; isum += (int) VPixel(bit_image, b, r0, c1, VBit) * n18; isum += (int) VPixel(bit_image, b0, r, c1, VBit) * n18; } if(neighb == 2) { isum += (int) VPixel(bit_image, b0, r0, c0, VBit) * n26; isum += (int) VPixel(bit_image, b1, r0, c0, VBit) * n26; isum += (int) VPixel(bit_image, b0, r1, c0, VBit) * n26; isum += (int) VPixel(bit_image, b0, r0, c1, VBit) * n26; isum += (int) VPixel(bit_image, b1, r1, c0, VBit) * n26; isum += (int) VPixel(bit_image, b1, r0, c1, VBit) * n26; isum += (int) VPixel(bit_image, b0, r1, c1, VBit) * n26; isum += (int) VPixel(bit_image, b1, r1, c1, VBit) * n26; } sum = (double) isum / (double) norm; i0 = 0; if(sum >= 0.5) i0 = 1; if(i1 == 1 && i0 == 0) { if(VSimplePoint(result, b, r, c, 26) == 0) i0 = 1; } else if(i1 == 0 && i0 == 1) { VPixel(result, b, r, c, VBit) = 1; if(VSimplePoint(result, b, r, c, 26) == 0) i0 = 0; } VPixel(result, b, r, c, VBit) = i0; if(i0 != i1) n++; } if(numiter > 1) { bit_pp = (VBit *) VImageData(bit_image); dest_pp = (VBit *) VImageData(result); for(i = 0; i < npixels; i++) *bit_pp++ = *dest_pp++; } } /* Successful completion: */ VCopyImageAttrs(bit_image, result); return result; }
VImage IniShift(VImage ref, VImage src, int minval, float shift[], int band1, int band2) { VImage dest; int b = 0, r = 0, c = 0; int bb, nbands3; int i, npixels; int nbands1, nrows1, ncols1; int nbands2, nrows2, ncols2; VUByte *dest_pp, *src_pp; float sumr = 0, sumc = 0, len = 0; float meanr, meanc; nbands1 = VImageNBands(ref); nrows1 = VImageNRows(ref); ncols1 = VImageNColumns(ref); nbands2 = VImageNBands(src); nrows2 = VImageNRows(src); ncols2 = VImageNColumns(src); if(band1 < 0 || band2 >= nbands2) VError("illegal choice of bands"); if(band2 < band1) VError("illegal choice of bands"); if(VPixelRepn(ref) != VUByteRepn) VError(" ref must be ubyte"); if(VPixelRepn(src) != VUByteRepn) VError(" src must be ubyte"); /* ** get center of gravity of foreground voxels */ sumr = sumc = len = 0; for(b = band1; b <= band2; b++) { for(r = 0; r < nrows2; r++) { for(c = 0; c < ncols2; c++) { if(VPixel(src, b, r, c, VUByte) > minval) { sumr += r; sumc += c; len++; } } } } meanr = sumr / len; meanc = sumc / len; /* ** initial shift: adjust center of gravity */ shift[0] = 0; shift[1] = (float)nrows1 * 0.5 - meanr; shift[2] = (float)ncols1 * 0.5 - meanc; /* ** create output image, reshuffle slices */ nbands3 = band2 - band1 + 1; dest = VCreateImage(nbands3, nrows2, ncols2, VUByteRepn); VFillImage(dest, VAllBands, 0); npixels = nrows2 * ncols2; bb = nbands3 - 1; for(b = band1; b <= band2; b++) { dest_pp = (VUByte *) VPixelPtr(dest, bb, 0, 0); src_pp = (VUByte *) VPixelPtr(src, b, 0, 0); for(i = 0; i < npixels; i++) { *dest_pp++ = *src_pp++; } bb--; } return dest; }
VBoolean DemonMatch (VImage S, VImage M, VImage& Dx, VImage& Dy, VImage& Dz, VFloat Sigma, VLong Iter, VLong Scale, VBoolean Verbose) { int Factor = 4; /* scaling factor of iterations at each step */ int scale; /* scaling level */ int iter; /* number of iteration */ VImage *s, *m; /* source and model pyramid */ VImage gsx, gsy, gsz, gs2; /* source gradient field */ VImage gmx, gmy, gmz, gm2; /* model gradient field */ VImage dsx, dsy, dsz; /* source deformation field */ VImage dmx, dmy, dmz; /* model deformation field */ VImage vx, vy, vz; /* optical flow field */ VImage rx, ry, rz; /* residual deformation field */ int width = 2 * (2 * (int) floor (Sigma) + 1) + 1; /* Lohmann, G. "Volumetric Image Analysis", p. 141, Teubner, 1998 */ VImage tmp; /* temporal storage */ /* create multi-scale pyramids */ s = (VImage*) malloc ((Scale + 1) * sizeof (VImage)); m = (VImage*) malloc ((Scale + 1) * sizeof (VImage)); /* compute multi-scale pyramids */ s[0] = S; m[0] = M; for (scale = 1; scale <= Scale; scale++, Iter *= Factor) { RTTI (S, GaussianFilter, (s[scale-1], 0.5, 3, s[scale])); RTTI (S, TrilinearScale, (s[scale], 0.5, 0.5, 0.5)); RTTI (M, GaussianFilter, (m[scale-1], 0.5, 3, m[scale])); RTTI (M, TrilinearScale, (m[scale], 0.5, 0.5, 0.5)); } /* create deformation fields */ dsx = VCreateImage (VImageNBands (s[Scale]), VImageNRows (s[Scale]), VImageNColumns (s[Scale]), VFloatRepn); dsy = VCreateImage (VImageNBands (s[Scale]), VImageNRows (s[Scale]), VImageNColumns (s[Scale]), VFloatRepn); dsz = VCreateImage (VImageNBands (s[Scale]), VImageNRows (s[Scale]), VImageNColumns (s[Scale]), VFloatRepn); dmx = VCreateImage (VImageNBands (m[Scale]), VImageNRows (m[Scale]), VImageNColumns (m[Scale]), VFloatRepn); dmy = VCreateImage (VImageNBands (m[Scale]), VImageNRows (m[Scale]), VImageNColumns (m[Scale]), VFloatRepn); dmz = VCreateImage (VImageNBands (m[Scale]), VImageNRows (m[Scale]), VImageNColumns (m[Scale]), VFloatRepn); /* initialize deformation fields */ VFillImage (dsx, VAllBands, 0); VFillImage (dsy, VAllBands, 0); VFillImage (dsz, VAllBands, 0); VFillImage (dmx, VAllBands, 0); VFillImage (dmy, VAllBands, 0); VFillImage (dmz, VAllBands, 0); /* multi-scale scheme */ for (scale = Scale; scale >= 0; scale--, Iter /= Factor) { /* print status */ if (Verbose) {fprintf (stderr, "Working hard at scale %d ... \n", scale + 1); fflush (stderr);} /* compute gradients */ RTTI (S, Gradient, (s[scale], gsx, gsy, gsz)); SquaredGradient (gsx, gsy, gsz, gs2); RTTI (M, Gradient, (m[scale], gmx, gmy, gmz)); SquaredGradient (gmx, gmy, gmz, gm2); /* diffusion process */ for (iter = 1; iter <= Iter; iter++) { /* print status */ if (Verbose) {fprintf (stderr, "Iteration %d of %d ...\r", iter, Iter); fflush (stderr);} /* FORWARD */ /* interpolate deformed image */ RTTI (S, TrilinearInverseDeform, (s[scale], dmx, dmy, dmz, tmp)); /* compute deformation */ RTTI (M, OpticalFlow, (m[scale], tmp, gmx, gm2, vx)); RTTI (M, OpticalFlow, (m[scale], tmp, gmy, gm2, vy)); RTTI (M, OpticalFlow, (m[scale], tmp, gmz, gm2, vz)); Subtract<VFloat> (dmx, vx); Subtract<VFloat> (dmy, vy); Subtract<VFloat> (dmz, vz); /* clean-up */ VDestroyImage (tmp); VDestroyImage (vx); VDestroyImage (vy); VDestroyImage (vz); /* BACKWARD */ /* interpolate deformed image */ RTTI (M, TrilinearInverseDeform, (m[scale], dsx, dsy, dsz, tmp)); /* compute deformation */ RTTI (S, OpticalFlow, (s[scale], tmp, gsx, gs2, vx)); RTTI (S, OpticalFlow, (s[scale], tmp, gsy, gs2, vy)); RTTI (S, OpticalFlow, (s[scale], tmp, gsz, gs2, vz)); Subtract<VFloat> (dsx, vx); Subtract<VFloat> (dsy, vy); Subtract<VFloat> (dsz, vz); /* clean-up */ VDestroyImage (tmp); VDestroyImage (vx); VDestroyImage (vy); VDestroyImage (vz); /* BIJECTIVE */ /* compute residual deformation */ TrilinearInverseDeform<VFloat> (dsx, dmx, dmy, dmz, rx); TrilinearInverseDeform<VFloat> (dsy, dmx, dmy, dmz, ry); TrilinearInverseDeform<VFloat> (dsz, dmx, dmy, dmz, rz); Add<VFloat> (rx, dmx); Add<VFloat> (ry, dmy); Add<VFloat> (rz, dmz); Multiply<VFloat> (rx, 0.5); Multiply<VFloat> (ry, 0.5); Multiply<VFloat> (rz, 0.5); /* update deformation fields */ Subtract<VFloat> (dmx, rx); Subtract<VFloat> (dmy, ry); Subtract<VFloat> (dmz, rz); TrilinearInverseDeform<VFloat> (rx, dsx, dsy, dsz); TrilinearInverseDeform<VFloat> (ry, dsx, dsy, dsz); TrilinearInverseDeform<VFloat> (rz, dsx, dsy, dsz); Subtract<VFloat> (dsx, rx); Subtract<VFloat> (dsy, ry); Subtract<VFloat> (dsz, rz); /* clean-up */ VDestroyImage (rx); VDestroyImage (ry); VDestroyImage (rz); /* regularize deformation fields */ GaussianFilter<VFloat> (dsx, Sigma, width); GaussianFilter<VFloat> (dsy, Sigma, width); GaussianFilter<VFloat> (dsz, Sigma, width); GaussianFilter<VFloat> (dmx, Sigma, width); GaussianFilter<VFloat> (dmy, Sigma, width); GaussianFilter<VFloat> (dmz, Sigma, width); } if (scale > 0) { /* downscale deformation fields */ TrilinearScale<VFloat> (dsx, 2.0, 2.0, 2.0); Multiply<VFloat> (dsx, 2.0); TrilinearScale<VFloat> (dsy, 2.0, 2.0, 2.0); Multiply<VFloat> (dsy, 2.0); TrilinearScale<VFloat> (dsz, 2.0, 2.0, 2.0); Multiply<VFloat> (dsz, 2.0); TrilinearScale<VFloat> (dmx, 2.0, 2.0, 2.0); Multiply<VFloat> (dmx, 2.0); TrilinearScale<VFloat> (dmy, 2.0, 2.0, 2.0); Multiply<VFloat> (dmy, 2.0); TrilinearScale<VFloat> (dmz, 2.0, 2.0, 2.0); Multiply<VFloat> (dmz, 2.0); /* clean-up */ VDestroyImage (s[scale]); VDestroyImage (m[scale]); } /* clean-up */ VDestroyImage (gsx); VDestroyImage (gsy); VDestroyImage (gsz); VDestroyImage (gs2); VDestroyImage (gmx); VDestroyImage (gmy); VDestroyImage (gmz); VDestroyImage (gm2); } /* return inverse deformation field */ Dx = dsx; Dy = dsy; Dz = dsz; /* clean-up */ VDestroyImage (dmx); VDestroyImage (dmy); VDestroyImage (dmz); free (s); free (m); return TRUE; } /* DemonMatch */
/* ** general linear regression */ VAttrList VRegression(ListInfo *linfo, int nlists, VShort minval, VImage design, VFloat sigma, VLong itr) { VAttrList out_list; VImageInfo *xinfo; int nbands = 0, nslices = 0, nrows = 0, ncols = 0, slice, row, col, nr, nc; VImage src[NSLICES], res_image = NULL; VImage beta_image[MBETA], BCOV = NULL, KX_image = NULL; VImage res_map[ETMP]; float smooth_fwhm = 0, vx = 0, vy = 0, vz = 0; VFloat *float_pp, df; VRepnKind repn; float d, err; int i, k, l, n, m = 0, nt, fd = 0, npix = 0; int i0 = 0, i1 = 0; double u, sig, trace = 0, trace2 = 0, var = 0, sum = 0, nx = 0, mean = 0, sum2; float *ptr1, *ptr2; double x; gsl_matrix_float *X = NULL, *XInv = NULL, *SX = NULL; gsl_vector_float *y, *z, *beta, *ys; gsl_vector *kernel; gsl_matrix_float *S = NULL, *Vc = NULL, *F = NULL, *P = NULL, *Q = NULL; gsl_matrix_float *R = NULL, *RV = NULL; VBoolean smooth = TRUE; /* no smoothness estimation */ gsl_set_error_handler_off(); /* ** read input data */ nslices = nbands = nrows = ncols = 0; for(k = 0; k < nlists; k++) { n = linfo[k].nslices; nr = linfo[k].nrows; nc = linfo[k].ncols; nt = linfo[k].ntimesteps; nbands += nt; if(nslices == 0) nslices = n; else if(nslices != n) VError(" inconsistent image dimensions, slices: %d %d", n, nslices); if(nrows == 0) nrows = nr; else if(nrows != nr) VError(" inconsistent image dimensions, rows: %d %d", nr, nrows); if(ncols == 0) ncols = nc; else if(ncols != nc) VError(" inconsistent image dimensions, cols: %d %d", nc, ncols); } fprintf(stderr, " num images: %d, image dimensions: %d x %d x %d\n", nlists, nslices, nrows, ncols); /* ** get design dimensions */ m = VImageNRows(design); /* number of timesteps */ n = VImageNColumns(design); /* number of covariates */ fprintf(stderr, " ntimesteps=%d, num covariates=%d\n", m, n); if(n >= MBETA) VError(" too many covariates (%d), max is %d", n, MBETA); if(m != nbands) VError(" design dimension inconsistency: %d %d", m, nbands); fprintf(stderr, " working...\n"); /* ** read design matrix */ X = gsl_matrix_float_alloc(m, n); for(k = 0; k < m; k++) { for(l = 0; l < n; l++) { x = VGetPixel(design, 0, k, l); fmset(X, k, l, (float)x); } } /* ** pre-coloring, set up K-matrix, S=K, V = K*K^T with K=S */ S = gsl_matrix_float_alloc(m, m); GaussMatrix((double)sigma, S); Vc = fmat_x_matT(S, S, NULL); /* ** compute pseudoinverse */ SX = fmat_x_mat(S, X, NULL); XInv = fmat_PseudoInv(SX, NULL); /* ** get variance estimate */ Q = fmat_x_mat(XInv, Vc, Q); F = fmat_x_matT(Q, XInv, F); BCOV = VCreateImage(1, n, n, VFloatRepn); float_pp = VImageData(BCOV); ptr1 = F->data; for(i = 0; i < n * n; i++) *float_pp++ = *ptr1++; gsl_matrix_float_free(Q); gsl_matrix_float_free(F); /* ** get effective degrees of freedom */ R = gsl_matrix_float_alloc(m, m); P = fmat_x_mat(SX, XInv, P); gsl_matrix_float_set_identity(R); gsl_matrix_float_sub(R, P); RV = fmat_x_mat(R, Vc, NULL); trace = 0; for(i = 0; i < m; i++) trace += fmget(RV, i, i); P = fmat_x_mat(RV, RV, P); trace2 = 0; for(i = 0; i < m; i++) trace2 += fmget(P, i, i); df = (trace * trace) / trace2; fprintf(stderr, " df= %.3f\n", df); /* ** create output images */ xinfo = linfo[0].info; out_list = VCreateAttrList(); res_image = VCreateImage(nslices, nrows, ncols, VFloatRepn); VFillImage(res_image, VAllBands, 0); VSetAttr(VImageAttrList(res_image), "name", NULL, VStringRepn, "RES/trRV"); VSetAttr(VImageAttrList(res_image), "modality", NULL, VStringRepn, "RES/trRV"); VSetAttr(VImageAttrList(res_image), "df", NULL, VFloatRepn, df); VSetAttr(VImageAttrList(res_image), "patient", NULL, VStringRepn, xinfo->patient); VSetAttr(VImageAttrList(res_image), "voxel", NULL, VStringRepn, xinfo->voxel); VSetAttr(VImageAttrList(res_image), "repetition_time", NULL, VLongRepn, itr); VSetAttr(VImageAttrList(res_image), "talairach", NULL, VStringRepn, xinfo->talairach); /* neu */ VSetAttr(VImageAttrList(res_image),"indexOrigin",NULL,VStringRepn,xinfo->indexOrigin); VSetAttr(VImageAttrList(res_image),"columnVec",NULL,VStringRepn,xinfo->columnVec); VSetAttr(VImageAttrList(res_image),"rowVec",NULL,VStringRepn,xinfo->rowVec); VSetAttr(VImageAttrList(res_image),"sliceVec",NULL,VStringRepn,xinfo->sliceVec); VSetAttr(VImageAttrList(res_image),"FOV",NULL,VStringRepn,xinfo->FOV); /*--------*/ if(xinfo->fixpoint[0] != 'N') VSetAttr(VImageAttrList(res_image), "fixpoint", NULL, VStringRepn, xinfo->fixpoint); if(xinfo->ca[0] != 'N') { VSetAttr(VImageAttrList(res_image), "ca", NULL, VStringRepn, xinfo->ca); VSetAttr(VImageAttrList(res_image), "cp", NULL, VStringRepn, xinfo->cp); VSetAttr(VImageAttrList(res_image), "extent", NULL, VStringRepn, xinfo->extent); } VAppendAttr(out_list, "image", NULL, VImageRepn, res_image); for(i = 0; i < n; i++) { beta_image[i] = VCreateImage(nslices, nrows, ncols, VFloatRepn); VFillImage(beta_image[i], VAllBands, 0); VSetAttr(VImageAttrList(beta_image[i]), "patient", NULL, VStringRepn, xinfo->patient); VSetAttr(VImageAttrList(beta_image[i]), "voxel", NULL, VStringRepn, xinfo->voxel); VSetAttr(VImageAttrList(beta_image[i]), "repetition_time", NULL, VLongRepn, itr); VSetAttr(VImageAttrList(beta_image[i]), "talairach", NULL, VStringRepn, xinfo->talairach); /* neu */ VSetAttr(VImageAttrList(beta_image[i]),"indexOrigin",NULL,VStringRepn,xinfo->indexOrigin); VSetAttr(VImageAttrList(beta_image[i]),"columnVec",NULL,VStringRepn,xinfo->columnVec); VSetAttr(VImageAttrList(beta_image[i]),"rowVec",NULL,VStringRepn,xinfo->rowVec); VSetAttr(VImageAttrList(beta_image[i]),"sliceVec",NULL,VStringRepn,xinfo->sliceVec); VSetAttr(VImageAttrList(beta_image[i]),"FOV",NULL,VStringRepn,xinfo->FOV); /*--------*/ if(xinfo->fixpoint[0] != 'N') VSetAttr(VImageAttrList(beta_image[i]), "fixpoint", NULL, VStringRepn, xinfo->fixpoint); if(xinfo->ca[0] != 'N') { VSetAttr(VImageAttrList(beta_image[i]), "ca", NULL, VStringRepn, xinfo->ca); VSetAttr(VImageAttrList(beta_image[i]), "cp", NULL, VStringRepn, xinfo->cp); VSetAttr(VImageAttrList(beta_image[i]), "extent", NULL, VStringRepn, xinfo->extent); } VSetAttr(VImageAttrList(beta_image[i]), "name", NULL, VStringRepn, "BETA"); VSetAttr(VImageAttrList(beta_image[i]), "modality", NULL, VStringRepn, "BETA"); VSetAttr(VImageAttrList(beta_image[i]), "beta", NULL, VShortRepn, i + 1); VSetAttr(VImageAttrList(beta_image[i]), "df", NULL, VFloatRepn, df); VAppendAttr(out_list, "image", NULL, VImageRepn, beta_image[i]); } VSetAttr(VImageAttrList(design), "name", NULL, VStringRepn, "X"); VSetAttr(VImageAttrList(design), "modality", NULL, VStringRepn, "X"); VAppendAttr(out_list, "image", NULL, VImageRepn, design); KX_image = Mat2Vista(SX); VSetAttr(VImageAttrList(KX_image), "name", NULL, VStringRepn, "KX"); VSetAttr(VImageAttrList(KX_image), "modality", NULL, VStringRepn, "KX"); VAppendAttr(out_list, "image", NULL, VImageRepn, KX_image); VSetAttr(VImageAttrList(BCOV), "name", NULL, VStringRepn, "BCOV"); VSetAttr(VImageAttrList(BCOV), "modality", NULL, VStringRepn, "BCOV"); VAppendAttr(out_list, "image", NULL, VImageRepn, BCOV); /* ** create temporary images for smoothness estimation */ /* smoothness estim only for 3D images, i.e. CA/CP known */ /* if(xinfo->ca[0] == 'N') smooth = FALSE;*/ if(smooth) { i0 = 20; i1 = i0 + 30; if(i1 > m) i1 = m; for(i = i0; i < i1; i++) { if(i - i0 >= ETMP) VError(" too many tmp images"); res_map[i - i0] = VCreateImage(nslices, nrows, ncols, VFloatRepn); VFillImage(res_map[i - i0], VAllBands, 0); } } /* ** process */ ys = gsl_vector_float_alloc(m); y = gsl_vector_float_alloc(m); z = gsl_vector_float_alloc(m); beta = gsl_vector_float_alloc(n); kernel = GaussKernel((double)sigma); for(k = 0; k < nlists; k++) { src[k] = VCreateImage(linfo[k].ntimesteps, nrows, ncols, linfo[k].repn); VFillImage(src[k], VAllBands, 0); } npix = 0; for(slice = 0; slice < nslices; slice++) { if(slice % 5 == 0) fprintf(stderr, " slice: %3d\r", slice); for(k = 0; k < nlists; k++) { if(linfo[k].zero[slice] == 0) goto next1; fd = open(linfo[k].filename, O_RDONLY); if(fd == -1) VError("could not open file %s", linfo[k].filename); nt = linfo[k].ntimesteps; if(! VReadBandDataFD(fd, &linfo[k].info[slice], 0, nt, &src[k])) VError(" error reading data"); close(fd); } repn = linfo[0].repn; for(row = 0; row < nrows; row++) { for(col = 0; col < ncols; col++) { for(k = 0; k < nlists; k++) if(VPixel(src[k], 0, row, col, VShort) < minval + 1) goto next; npix++; /* read time series data */ sum = sum2 = nx = 0; ptr1 = y->data; for(k = 0; k < nlists; k++) { nt = VImageNBands(src[k]); for(i = 0; i < nt; i++) { u = VPixel(src[k], i, row, col, VShort); (*ptr1++) = u; sum += u; sum2 += u * u; nx++; } } mean = sum / nx; sig = sqrt((double)((sum2 - nx * mean * mean) / (nx - 1.0))); if(sig < 0.001) continue; /* centering and scaling, Seber, p.330 */ ptr1 = y->data; for(i = 0; i < m; i++) { u = ((*ptr1) - mean) / sig; (*ptr1++) = u + 100.0; } /* S x y */ ys = VectorConvolve(y, ys, kernel); /* compute beta's */ fmat_x_vector(XInv, ys, beta); /* residuals */ fmat_x_vector(SX, beta, z); err = 0; ptr1 = ys->data; ptr2 = z->data; for(i = 0; i < m; i++) { d = ((*ptr1++) - (*ptr2++)); err += d * d; } /* sigma^2 */ var = err / trace; /* write residuals output */ VPixel(res_image, slice, row, col, VFloat) = (VFloat)var; /* save residuals of several timesteps for smoothness estimation */ if(smooth) { ptr1 = ys->data; ptr2 = z->data; err = 0; for(i = i0; i < i1; i++) { d = ((*ptr1++) - (*ptr2++)); err += d * d; VPixel(res_map[i - i0], slice, row, col, VFloat) = d; } if (err > 0) err = sqrt(err); for(i = i0; i < i1; i++) { d = VPixel(res_map[i - i0], slice, row, col, VFloat); if (err > 1.0e-6) d /= err; else d = 0; VPixel(res_map[i - i0], slice, row, col, VFloat) = d / err; } } /* write beta output */ ptr1 = beta->data; for(i = 0; i < n; i++) VPixel(beta_image[i], slice, row, col, VFloat) = (VFloat)(*ptr1++); next: ; } } next1: ; } /* ** Smoothness estimation based on residual images */ if(smooth) { smooth_fwhm = VSmoothnessEstim(res_map, i1 - i0); sscanf(xinfo->voxel, "%f %f %f", &vx, &vy, &vz); vx = (vx + vy + vz) / 3.0; /* voxels should be isotropic */ smooth_fwhm *= vx; fprintf(stderr, " smoothness: %f\n", smooth_fwhm); VSetAttr(VImageAttrList(res_image), "smoothness", NULL, VFloatRepn, smooth_fwhm); for(i = 0; i < n; i++) { VSetAttr(VImageAttrList(beta_image[i]), "smoothness", NULL, VFloatRepn, smooth_fwhm); } for(i = 0; i < i1 - i0; i++) VDestroyImage(res_map[i]); } ende: if(npix == 0) VError(" no voxels above threshold %d found", minval); return out_list; }
VImage VAddCovariates(VImage design, VString cfile) { VImage dest = NULL, tmp = NULL; FILE *fp = NULL; char buf[LEN], token[80]; int i, j, r, c, ncols, nrows, add_cols; double u; float x; add_cols = 0; nrows = VImageNRows(design); ncols = VImageNColumns(design); /* read first file */ fp = fopen(cfile, "r"); if(fp == NULL) VError(" err opening file %s", cfile); tmp = VCreateImage(1, nrows, NCOV, VFloatRepn); VFillImage(tmp, VAllBands, 0); i = 0; while(!feof(fp)) { for(j = 0; j < LEN; j++) buf[j] = '\0'; fgets(buf, LEN, fp); if(buf[0] == '#' || buf[0] == '%') continue; if(strlen(buf) < 2) continue; if(i > nrows) VError(" too many rows in file (%d), max is %d", i, nrows); j = 0; while(VStringToken(buf, token, j, 30)) { sscanf(token, "%f", &x); if(j >= NCOV) VError(" too many additional covariates (%d), max is %d", j, NCOV - 1); VPixel(tmp, 0, i, j, VFloat) = x; j++; } if(j < 1) continue; if(add_cols > 0 && j > add_cols) VError(" inconsistent number of columns (%d, %d), line %d", j, add_cols, i + 1); if(add_cols == 0 && j > add_cols) add_cols = j; if(i >= nrows) continue; i++; } fclose(fp); if(i != nrows) VError(" file: inconsistent number of rows: %d %d", i, nrows); /* ** create new design file */ dest = VCreateImage(1, nrows, ncols + add_cols, VPixelRepn(design)); VFillImage(dest, VAllBands, 1); VCopyImageAttrs(design, dest); for(r = 0; r < nrows; r++) { for(c = 0; c < ncols; c++) { u = VGetPixel(design, 0, r, c); VSetPixel(dest, 0, r, c, u); } } /* add covariates */ for(r = 0; r < nrows; r++) { for(c = 0; c < add_cols; c++) { u = VPixel(tmp, 0, r, c, VFloat); VSetPixel(dest, 0, r, c + ncols - 1, u); } } fprintf(stderr, " %d columns added to design file\n", add_cols); return dest; }
void VImageManager::init( VAttrList list ) { VAttrListPosn posn; int nbands = 0; int nrows = 0; int ncols = 0; int timeSlices = 2; VImage src; VString str; for ( VFirstAttr ( list, & posn ); VAttrExists ( & posn ); VNextAttr ( & posn ) ) { if ( VGetAttrRepn ( & posn ) != VImageRepn ) continue; VGetAttrValue ( &posn, NULL, VImageRepn, &src ); if ( VPixelRepn( src ) != VShortRepn ) continue; // check if we have a functional data image if ( ( VGetAttr ( VImageAttrList ( src ), "MPIL_vista_0", NULL, VStringRepn, ( VPointer ) & str ) == VAttrFound ) || ( VGetAttr ( VImageAttrList ( src ), "repetition_time", NULL, VStringRepn, ( VPointer ) & str ) == VAttrFound ) ) { if ( VImageNRows( src ) > nrows ) nrows = VImageNRows( src ); if ( VImageNColumns( src ) > ncols ) ncols = VImageNColumns( src ); if ( VImageNBands( src ) > timeSlices ) timeSlices = VImageNBands( src ); nbands++; } } if ( nbands == 0 ) VError( "No raw data found" ); // now loading the vimages int currentTimeSlice = 0; // curr slice for ( currentTimeSlice = 0; currentTimeSlice < timeSlices; currentTimeSlice++ ) { VImage dest = VCreateImage( nbands, nrows, ncols, VShortRepn ); vtimestep( list, dest, currentTimeSlice ); m_imageList.append( dest ); } prepareScaleValue(); // creating data arrays int size = ncols * nbands; m_coronarData = new unsigned char[size]; memset( m_coronarData, 0, size * sizeof( unsigned char ) ); size = ncols * nrows; m_axialData = new unsigned char[size]; memset( m_axialData, 0, size * sizeof( unsigned char ) ); size = nbands * nrows; m_sagittalData = new unsigned char[size]; memset( m_sagittalData, 0, size * sizeof( unsigned char ) ); }
VImage VCovariates(VString cfile, VFloat tr, VBoolean normalize) { VImage dest = NULL; FILE *fp = NULL; char buf[LEN], token[80]; int i, j, nt, m, ncols, nrows; float x; double u, sum1, sum2, nx, mean, sigma, tiny = 1.0e-4; fp = fopen(cfile, "r"); if(fp == NULL) VError(" err opening file %s", cfile); nrows = ncols = 0; while(!feof(fp)) { for(j = 0; j < LEN; j++) buf[j] = '\0'; fgets(buf, LEN, fp); if(buf[0] == '#' || buf[0] == '%') continue; if(strlen(buf) < 3) continue; j = 0; while(VStringToken(buf, token, j, 30)) { sscanf(token, "%f", &x); if(j >= NCOV) VError(" too many additional covariates (%d), max is %d", j, NCOV - 1); j++; } if(j > ncols) ncols = j; nrows++; } fprintf(stderr, "# num rows: %d, num cols: %d\n", nrows, ncols); dest = VCreateImage(1, nrows, ncols + 1, VFloatRepn); VSetAttr(VImageAttrList(dest), "modality", NULL, VStringRepn, "X"); VSetAttr(VImageAttrList(dest), "name", NULL, VStringRepn, "X"); VSetAttr(VImageAttrList(dest), "repetition_time", NULL, VLongRepn, (VLong)(tr * 1000.0)); VSetAttr(VImageAttrList(dest), "ntimesteps", NULL, VLongRepn, (VLong)nrows); VSetAttr(VImageAttrList(dest), "derivatives", NULL, VShortRepn, (VFloat) 0); VSetAttr(VImageAttrList(dest), "delay", NULL, VFloatRepn, (VFloat) 0); VSetAttr(VImageAttrList(dest), "undershoot", NULL, VFloatRepn, (VFloat) 0); VSetAttr(VImageAttrList(dest), "understrength", NULL, VFloatRepn, (VFloat) 0); VSetAttr(VImageAttrList(dest), "nsessions", NULL, VShortRepn, (VShort)1); VSetAttr(VImageAttrList(dest), "designtype", NULL, VShortRepn, (VShort)1); VFillImage(dest, VAllBands, 0); for(j = 0; j < nrows; j++) VPixel(dest, 0, j, ncols, VFloat) = 1; rewind(fp); i = 0; while(!feof(fp)) { for(j = 0; j < LEN; j++) buf[j] = '\0'; fgets(buf, LEN, fp); if(buf[0] == '#' || buf[0] == '%') continue; if(strlen(buf) < 3) continue; if(i > nrows) VError(" too many rows in file (%d), max is %d", i, nrows); j = 0; while(VStringToken(buf, token, j, 30)) { sscanf(token, "%f", &x); if(j >= NCOV) VError(" too many additional covariates (%d), max is %d", j, NCOV - 1); VPixel(dest, 0, i, j, VFloat) = x; j++; } if(j < 1) continue; if(i >= nrows) continue; i++; } fclose(fp); if(i != nrows) VError(" file: inconsistent number of rows: %d %d", i, nrows); if(!normalize) return dest; nt = VImageNRows(dest); m = VImageNColumns(dest); for(i = 0; i < m; i++) { sum1 = sum2 = nx = 0; for(j = 0; j < nt; j++) { u = VPixel(dest, 0, j, i, VFloat); sum1 += u; sum2 += u * u; nx++; } mean = sum1 / nx; sigma = sqrt((sum2 - nx * mean * mean) / (nx - 1.0)); if(sigma < tiny) continue; for(j = 0; j < nt; j++) { u = VPixel(dest, 0, j, i, VFloat); u = (u - mean) / sigma; VPixel(dest, 0, j, i, VFloat) = u; } } return dest; }
/*! \fn VImage VDTClose(VImage src,VImage dest,VDouble radius) \brief 3D morphological closing (dilation+erosion) \param src input image (bit repn) \param dest output image (bit repn) \param radius radius of the spherical structural element */ VImage VDTClose(VImage src,VImage dest,VDouble radius) { VImage float_image=NULL,tmp=NULL; VBit *bin_pp; VFloat *float_pp; int i,nbands,nrows,ncols,npixels,b,r,c; int border = 7; border = (int) (radius - 1); if (VPixelRepn(src) != VBitRepn) VError("Input image must be of type VBit"); nbands = VImageNBands(src) + 2*border; nrows = VImageNRows(src) + 2*border; ncols = VImageNColumns(src) + 2*border; npixels = nbands * nrows * ncols; tmp = VCreateImage(nbands,nrows,ncols,VBitRepn); for (b=border; b<nbands-border; b++) { for (r=border; r<nrows-border; r++) { for (c=border; c<ncols-border; c++) { VPixel(tmp,b,r,c,VBit) = VPixel(src,b-border,r-border,c-border,VBit); } } } float_image = VChamferDist3d(tmp,NULL,VFloatRepn); if (! float_image) VError("VDTClose failed.\n"); float_pp = (VFloat *) VPixelPtr(float_image,0,0,0); bin_pp = (VBit *) VPixelPtr(tmp,0,0,0); for (i=0; i<npixels; i++) *bin_pp++ = ((*float_pp++ > radius) ? 1 : 0); float_image = VChamferDist3d(tmp,float_image,VFloatRepn); if (! float_image) VError("VDTClose failed.\n"); float_pp = (VFloat *) VPixelPtr(float_image,0,0,0); bin_pp = (VBit *) VPixelPtr(tmp,0,0,0); for (i=0; i<npixels; i++) *bin_pp++ = ((*float_pp++ > radius) ? 1 : 0); VDestroyImage(float_image); dest = VSelectDestImage("VDTClose",dest,VImageNBands(src),VImageNRows(src),VImageNColumns(src), VBitRepn); if (! dest) return NULL; for (b=border; b<nbands-border; b++) { for (r=border; r<nrows-border; r++) { for (c=border; c<ncols-border; c++) { VPixel(dest,b-border,r-border,c-border,VBit) = VPixel(tmp,b,r,c,VBit); } } } VDestroyImage(tmp); VCopyImageAttrs (src, dest); return dest; }