/*! \fn VImage VDTDilate(VImage src,VImage dest,VDouble radius) \brief 3D morphological dilation \param src input image (bit repn) \param dest output image (bit repn) \param radius radius of the spherical structural element */ VImage VDTDilate(VImage src,VImage dest,VDouble radius) { VImage float_image; VBit *bin_pp; VFloat *float_pp; int i,nbands,nrows,ncols,npixels; if (VPixelRepn(src) != VBitRepn) VError("Input image must be of type VBit"); nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); npixels = nbands * nrows * ncols; float_image = VChamferDist3d(src,NULL,VFloatRepn); if (! float_image) VError("VDTDilate failed.\n"); dest = VSelectDestImage("VDTDilate",dest,nbands,nrows,ncols,VBitRepn); if (! dest) return NULL; float_pp = (VFloat *) VPixelPtr(float_image,0,0,0); bin_pp = (VBit *) VPixelPtr(dest,0,0,0); for (i=0; i<npixels; i++) *bin_pp++ = ((*float_pp++ > radius) ? 0 : 1); VDestroyImage(float_image); VCopyImageAttrs (src,dest); return dest; }
/* ** read several bands of data from a file */ VBoolean VReadBandDataFD (int fd,VImageInfo *imageInfo, int band,int num_bands,VImage *buf) { size_t band1; size_t offset; size_t ncolumns,nrows,nbands; size_t size,nitems,nbytes; VPointer *dest_pp; size = imageInfo->pixelSize; ncolumns = imageInfo->ncolumns; nrows = imageInfo->nrows; nbands = imageInfo->nbands; /* Seek start of binary data */ lseek(fd,0L,SEEK_SET); if (lseek(fd,imageInfo->offsetHdr,SEEK_SET) == -1) { return FALSE; } band1 = num_bands + band; if (band1 > nbands) { VWarning(" illegal band addr: %d",band1); band1 = nbands; num_bands = band1 - band; } /* read all rows and all columns */ nitems = ncolumns * nrows * num_bands; nbytes = nitems * size; offset = imageInfo->data + (nrows * ncolumns * (size_t)band) * size; if (lseek(fd,offset,SEEK_CUR) == -1) { return FALSE; } dest_pp = (VPointer*)VPixelPtr((*buf),0,0,0); if (read(fd,dest_pp,nbytes) < 0) { return FALSE; } /* if little-endian, then swap bytes: */ if (MachineByteOrder() == VLsbFirst) { dest_pp = (VPointer*)VPixelPtr((*buf),0,0,0); SwapBytes(nitems,size,(char*)dest_pp); } return TRUE; }
/* ** read several rows of data from a file using file pointer of type FILE */ VBoolean VReadBlockData (FILE *fp,VImageInfo *imageInfo, int row,int num_rows,VImage *buf) { int i,column; size_t offset,offset2,ncolumns,nrows,nbands; size_t size,nitems; VPointer *dest_pp; /* Seek start of binary data */ if (fseek(fp,imageInfo->offsetHdr,SEEK_SET) != 0) return FALSE; size = imageInfo->pixelSize; ncolumns = imageInfo->ncolumns; nrows = imageInfo->nrows; nbands = imageInfo->nbands; /* fprintf(stderr," size; %d, ncol: %d nrows: %d, nb: %d, fp: %x data: %d \n", size,ncolumns,num_rows,nbands,fp,imageInfo->data); */ nitems = ncolumns * num_rows; column = 0; offset = imageInfo->data + (row*ncolumns + column) * size; offset2 = (nrows * ncolumns - num_rows * ncolumns) * size; fprintf(stderr, "offset: %d\n", offset); fprintf(stderr, "offset2: %d\n", offset2); /* read data from file */ for (i=0; i<nbands; i++) { if (fseek(fp,offset,SEEK_CUR) != 0) return FALSE; dest_pp = (VPointer*)VPixelPtr((*buf),i,0,0); if (fread(dest_pp,size,nitems,fp) <= 0) return FALSE; dest_pp = (VPointer*)VPixelPtr((*buf),i,0,0); offset = offset2; } dest_pp = (VPointer*)VPixelPtr((*buf),0,0,0); /* if little-endian, then swap bytes: */ if (MachineByteOrder() == VLsbFirst) { for (i=0; i<nbands; i++) { dest_pp = (VPointer*)VPixelPtr((*buf),i,0,0); SwapBytes(nitems,size,(char*)dest_pp); } } return TRUE; }
/* ** read several bands of data from a file */ VBoolean VReadBandData (FILE *fp,VImageInfo *imageInfo, int band,int num_bands,VImage *buf) { int band1; size_t offset,ncolumns,nrows,nbands; size_t size,nitems; VPointer *dest_pp; size = imageInfo->pixelSize; ncolumns = imageInfo->ncolumns; nrows = imageInfo->nrows; nbands = imageInfo->nbands; /* fprintf(stderr," size; %d, ncol: %d nrows: %d, nb: %d, band: %d data: %d \n", size,ncolumns,nrows,nbands,band,imageInfo->data); */ /* Seek start of binary data */ fseek(fp,0L,SEEK_SET); if (fseek(fp,(long)imageInfo->offsetHdr,SEEK_SET) != 0) return FALSE; band1 = num_bands + band; if (band1 > nbands) { VWarning(" illegal band addr: %d",band1); band1 = nbands; num_bands = band1 - band; } /* read all rows and all columns */ nitems = ncolumns * nrows * num_bands; offset = imageInfo->data + (nrows * ncolumns * band) * size; if (fseek(fp,offset,SEEK_CUR) != 0) return FALSE; dest_pp = (VPointer*)VPixelPtr((*buf),0,0,0); if (fread(dest_pp,size,nitems,fp) <= 0) return FALSE; /* if little-endian, then swap bytes: */ if (MachineByteOrder() == VLsbFirst) { dest_pp = (VPointer*)VPixelPtr((*buf),0,0,0); SwapBytes(nitems,size,(char*)dest_pp); } return TRUE; }
VImage VImageManager::vtimestep( VAttrList list, VImage dest, int step ) { VFillImage( dest, VAllBands, 0 ); VPointer src_pp = NULL; VPointer dest_pp = NULL; VAttrListPosn posn; VShort *ptr1 = NULL; VShort *ptr2 = NULL; VString str; VImage src; int n = 0; int npixels = 0; bool revert = false; for ( VFirstAttr ( list, & posn ); VAttrExists ( & posn ); VNextAttr ( & posn ) ) { if ( VGetAttrRepn ( & posn ) != VImageRepn ) continue; VGetAttrValue ( &posn, NULL, VImageRepn, &src ); if ( VPixelRepn( src ) != VShortRepn ) continue; if ( ( VGetAttr ( VImageAttrList ( src ), "MPIL_vista_0", NULL, VStringRepn, ( VPointer ) & str ) != VAttrFound ) && ( VGetAttr ( VImageAttrList ( src ), "repetition_time", NULL, VStringRepn, ( VPointer ) & str ) != VAttrFound ) ) continue; /* doch nicht rumdrehen! if (VGetAttr (VImageAttrList (src), "extent", NULL, VStringRepn, (VPointer) & str) != VAttrFound) revert = true; */ if ( n == 0 ) VCopyImageAttrs ( src, dest ); if ( VImageNRows( src ) > 1 ) { if ( VSelectBand ( "vtimestep", src, step, &npixels, &src_pp ) == FALSE ) VError( "err reading data" ); int destBand = ( revert ) ? VImageNBands( dest ) - n - 1 : n; dest_pp = VPixelPtr( dest, destBand, 0, 0 ); ptr1 = ( VShort * ) src_pp; ptr2 = ( VShort * ) dest_pp; memcpy ( ptr2, ptr1, npixels * sizeof( VShort ) ); } n++; } return dest; }
/* Output an image in the ppm format (see ppm man page for details). */ void WritePnmFile (FILE *outfile, VImage image, VBand band) { VUByte *src_pp; int i,u,r,c; int nrows = VImageNRows (image), ncols = VImageNColumns (image); if (VImageColorInterp(image) == VBandInterpRGB) { /* color map */ fprintf (outfile, "P6\n%d %d\n255\n",ncols,nrows); for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { u = (int)VPixel(image,0,r,c,VUByte); putc(u,outfile); u = (int)VPixel(image,1,r,c,VUByte); putc(u,outfile); u = (int)VPixel(image,2,r,c,VUByte); putc(u,outfile); } } } else { /* gray map */ fprintf (outfile, "P5\n%d %d\n255\n",ncols,nrows); src_pp = (VUByte *) VPixelPtr (image, band, 0, 0); for (i=0; i<nrows*ncols; i++) { u = *src_pp++; putc(u,outfile); } } fclose(outfile); }
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 */
void VSetPixel(VImage image, int band, int row, int column, VDoublePromoted value) { VPointer p = VPixelPtr (image, band, row, column); switch (VPixelRepn (image)) { case VBitRepn: *(VBit *) p = value; break; case VUByteRepn: *(VUByte *) p = value; break; case VSByteRepn: *(VSByte *) p = value; break; case VShortRepn: *(VShort *) p = value; break; case VLongRepn: *(VLong *) p = value; break; case VFloatRepn: *(VFloat *) p = value; break; case VDoubleRepn: *(VDouble *) p = value; break; default: VError("VSetPixel: %s images not supported", VPixelRepnName (image)); } }
VDouble VGetPixel (VImage image, int band, int row, int column) { VPointer p = VPixelPtr (image, band, row, column); switch (VPixelRepn (image)) { case VBitRepn: return (VDouble) *(VBit *) p; case VUByteRepn: return (VDouble) *(VUByte *) p; case VSByteRepn: return (VDouble) *(VSByte *) p; case VShortRepn: return (VDouble) *(VShort *) p; case VLongRepn: return (VDouble) *(VLong *) p; case VFloatRepn: return (VDouble) *(VFloat *) p; case VDoubleRepn: return (VDouble) *(VDouble *) p; default: VError("VGetPixel: %s images not supported", VPixelRepnName (image)); } return 0.0; /* to make lint happy */ }
/* Output an image in the pgm format (see pgm man page for details). */ void WritePgmFile (FILE *outfile, VImage image, VBand band) { VUByte *ppixel; int i; int rows = VImageNRows (image), columns = VImageNColumns (image); /* Output header information for pgm. */ fprintf (outfile, "P2\n%d %d\n255\n", columns, rows); ppixel = (VUByte *) VPixelPtr (image, band, 0, 0); for (i = 0; i < rows * columns; i++) { fprintf (outfile, " %3d", *ppixel++); if (i%10 == 9) fprintf (outfile, "\n"); } fprintf (outfile, "\n"); }
VBoolean FunctionalZero (VImage Image) { int Pixels; /* number of pixels */ VShort* image; /* image data pointer */ int n; /* index */ /* check image size */ if ((VImageNBands (Image) == 1) && (VImageNRows (Image) == 1) && (VImageNColumns (Image) == 1)) return TRUE; /* check image content */ Pixels = VImageNBands (Image) * VImageNRows (Image) * VImageNColumns (Image); image = (VShort*) VPixelPtr (Image, 0, 0, 0); for (n = 0; n < Pixels; ++n) if (*(image++) != 0) return FALSE; return TRUE; } /* FunctionalZero */
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 */
/*! \fn VImage VCDT3d (VImage src,VImage dest, VLong inside,VLong outside,VLong obstacle,VRepnKind repn) \param src input image (VUByte) \param dest output image (VFloat) \param inside ubyte value representing inside voxels \param outside ubyte value representing outside voxels \param obstacle ubyte value representing obstacle voxels \param repn output pixel repn (VShortRepn or VFloatRepn) */ VImage VCDT3d (VImage src,VImage dest, VLong inside,VLong outside,VLong obstacle,VRepnKind repn) { int nbands,nrows,ncols,b,r,c; int i,n_new,n_old,iter,npixels; VFloat d1,d2,d3; VFloat u,x,y; VUByte *src_pp; VFloat *dest_pp,inf; VShort *short_pp; VImage result=NULL; if (repn != VShortRepn && repn != VFloatRepn) VError(" VCDT3d: illegal output pixel repn: %d, short= %d, float= %d", repn,VShortRepn,VFloatRepn); /* Check the input image */ if (VPixelRepn(src) != VUByteRepn) VError("VCDT3d: input image must be of type VUByte"); nbands = VImageNBands(src); nrows = VImageNRows (src); ncols = VImageNColumns (src); npixels = nbands * nrows * ncols; dest = VSelectDestImage("VCDT3d",dest,nbands,nrows,ncols,VFloatRepn); VFillImage(dest,VAllBands,0); inf = VPixelMaxValue(dest) - 2; dest_pp = (VFloat *) VPixelPtr(dest,0,0,0); src_pp = (VUByte *) VPixelPtr(src,0,0,0); npixels = nbands * nrows * ncols; for (i=0; i<npixels; i++) { x = *src_pp++; if (x == (VFloat) inside) y = inf; else if (x == (VFloat) outside) y = 0; else y = -100.0; *dest_pp++ = y; } /* optimal chamfer distances (Borgefors,1984, p. 334) */ d1 = 1.0; d2 = 1.314; d3 = 1.628; /* optimal distances (see Beckers, Smeulders, 1992). */ d1 = 0.88750; d2 = 1.34224; d3 = 1.59772; /* optimal distances (see Verwer, 1991). */ /* d1 = 0.894; d2 = 1.3409; d3 = 1.5879; */ /* optimal distances (see Kiryati, 1993). */ /* d1 = 0.9016; d2 = 1.289; d3 = 1.615; */ iter = 0; n_old = 1; n_new = 0; while (n_old != n_new && iter < 6) { /* forward scan */ for (b=1; b<nbands; b++) { for (r=1; r<nrows-1; r++) { for (c=1; c<ncols-1; c++) { if (VPixel(src,b,r,c,VUByte) != inside) continue; u = VPixel(dest,b,r,c,VFloat); x = VPixel(dest,b-1,r-1,c-1,VFloat) + d3; if (x < u && x >= 0) u = x; x = VPixel(dest,b-1,r-1,c,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b-1,r-1,c+1,VFloat) + d3; if (x < u && x >= 0) u = x; x = VPixel(dest,b-1,r,c-1,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b-1,r,c,VFloat) + d1; if (x < u && x >= 0) u = x; x = VPixel(dest,b-1,r,c+1,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b-1,r+1,c-1,VFloat) + d3; if (x < u && x >= 0) u = x; x = VPixel(dest,b-1,r+1,c,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b-1,r+1,c+1,VFloat) + d3; if (x < u && x >= 0) u = x; x = VPixel(dest,b,r-1,c-1,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b,r-1,c,VFloat) + d1; if (x < u && x >= 0) u = x; x = VPixel(dest,b,r-1,c+1,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b,r,c-1,VFloat) + d1; if (x < u && x >= 0) u = x; if (u >= 0) VPixel(dest,b,r,c,VFloat) = u; } } } /* backward scan */ for (b=nbands-2; b>=0; b--) { for (r=nrows-2; r>=1; r--) { for (c=ncols-2; c>=1; c--) { if (VPixel(src,b,r,c,VUByte) != inside) continue; u = VPixel(dest,b,r,c,VFloat); x = VPixel(dest,b,r,c+1,VFloat) + d1; if (x < u && x >= 0) u = x; x = VPixel(dest,b,r+1,c-1,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b,r+1,c,VFloat) + d1; if (x < u && x >= 0) u = x; x = VPixel(dest,b,r+1,c+1,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r-1,c-1,VFloat) + d3; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r-1,c,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r-1,c+1,VFloat) + d3; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r,c-1,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r,c,VFloat) + d1; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r,c+1,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r+1,c-1,VFloat) + d3; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r+1,c,VFloat) + d2; if (x < u && x >= 0) u = x; x = VPixel(dest,b+1,r+1,c+1,VFloat) + d3; if (x < u && x >= 0) u = x; if (u >= 0) VPixel(dest,b,r,c,VFloat) = u; } } } dest_pp = (VFloat *) VPixelPtr(dest,0,0,0); n_old = n_new; n_new = 0; for (i=0; i<npixels; i++) { if (*dest_pp++ >= 9999) n_new++; } iter++; } dest_pp = (VFloat *) VPixelPtr(dest,0,0,0); for (i=0; i<npixels; i++) { if (*dest_pp >= 9999 || *dest_pp < 0) *dest_pp = 0; dest_pp++; } /* copy to a short image */ if (repn == VShortRepn) { result = VCreateImage(nbands,nrows,ncols,VShortRepn); dest_pp = (VFloat *) VPixelPtr(dest,0,0,0); short_pp = (VShort *) VPixelPtr(result,0,0,0); for (i=0; i<npixels; i++) { *short_pp = VRint((float)(*dest_pp * 10.0f)); dest_pp++; short_pp++; } VDestroyImage(dest); VCopyImageAttrs (src, result); return result; } else if (repn == VFloatRepn) { VCopyImageAttrs (src, dest); return dest; } return NULL; }
/*! \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; }
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; }
/*! \fn VImage VSkel3d (VImage src,VImage dest) \param src input image (bit repn) \param dest output image (bit repn) */ VImage VSkel3d(VImage src,VImage dest) { int b,r,c,nbands,nrows,ncols,npixels; int ndel=0; VBit *tmp_pp,*dst_pp; VImage tmp=NULL,dt=NULL; int i,j,n,n0,n1,mdel; float depth,maxdepth,step=0.5; VPoint *array; VBit *src_pp,*dest_pp; nrows = VImageNRows (src); ncols = VImageNColumns (src); nbands = VImageNBands (src); npixels = nbands*nrows*ncols; dest = VCopyImage(src,dest,VAllBands); VFillImage(dest,VAllBands,0); tmp = VCreateImage(nbands,nrows,ncols,VBitRepn); VFillImage(tmp,VAllBands,0); for (b=2; b<nbands-2; b++) { for (r=2; r<nrows-2; r++) { for (c=2; c<ncols-2; c++) { VPixel(dest,b,r,c,VBit) = VPixel(src,b,r,c,VBit); } } } /* ** generate masks */ GenerateMaps(); /* ** sort foreground voxels by depth */ src_pp = (VBit *) VPixelPtr(src, 0, 0, 0); dest_pp = (VBit *) VPixelPtr(dest, 0, 0, 0); n = 0; for (i=0; i<npixels; i++) { if (*src_pp > 0) n++; *src_pp = (*src_pp > 0) ? 0 : 1; src_pp++; } dt = VChamferDist3d(src,NULL,VFloatRepn); src_pp = (VBit *) VPixelPtr(src, 0, 0, 0); for (i=0; i<npixels; i++) { *src_pp = (*src_pp > 0) ? 0 : 1; src_pp++; } array = (VPoint *) VMalloc(sizeof(VPoint) * (n+1)); array[0].b = 0; array[0].r = 0; array[0].c = 0; array[0].val = 0; n = 1; for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { if (VPixel(dt, b, r, c,VFloat) > 0.1) { array[n].b = b; array[n].r = r; array[n].c = c; array[n].val = VPixel(dt,b,r,c,VFloat); n++; } } } } VDestroyImage(dt); VPoint_hpsort((n-1),array); /* ** now start deleting voxels */ maxdepth = array[n-1].val; fprintf(stderr," maxdepth= %f\n",maxdepth); mdel = 0; for (depth=0; depth <= maxdepth; depth += step) { fprintf(stderr," depth= %7.2f\r",depth); fflush(stderr); n0 = 1; for (j=n-1; j>=1; j--) { if (array[j].val < depth-2.0*step) { n0 = j; break; } } n1 = n; for (j=1; j<=n; j++) { if (array[j].val > depth) { n1 = j-1; break; } } /* ** delete all deletable voxels within this depth level */ ndel = 1; while (ndel > 0) { ndel = 0; VFillImage(tmp,VAllBands,0); for (j=n0; j<=n1; j++) { if (array[j].val > depth) continue; b = array[j].b; r = array[j].r; c = array[j].c; if (b < 2 || b >= nbands-2) continue; if (r < 2 || r >= nrows-2) continue; if (c < 2 || c >= ncols-2) continue; if (VPixel(dest,b,r,c,VBit) == 0) continue; if (Border_3d(dest,b,r,c) == FALSE) continue; if (Beta1_3d(dest,b,r,c) == FALSE) continue; if (Beta0_3d(dest,b,r,c) == FALSE) continue; /* alpha conditions */ if (Alpha_3d(dest,alpha0_pos,alpha0_neg,b,r,c) == FALSE && Alpha_3d(dest,alpha1_pos,alpha1_neg,b,r,c) == FALSE && Alpha_3d(dest,alpha2_pos,alpha2_neg,b,r,c) == FALSE) continue; /* mark for deletion */ VPixel(tmp,b,r,c,VBit) = 1; ndel++; } /* perform parallel deletion */ tmp_pp = (VBit *) VPixelPtr(tmp,0,0,0); dst_pp = (VBit *) VPixelPtr(dest,0,0,0); for (i=0; i<npixels; i++) { if (*tmp_pp == 1) *dst_pp = 0; tmp_pp++; dst_pp++; } } } VDestroyImage(tmp); return dest; }
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 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; }
/* ** correct topological labelling. Some surface points must be relabelled ** as junctions. */ VImage VJunction(VImage src,VImage topo) { VImage tmp1,tmp2; int nbands,nrows,ncols; int b,r,c,bb,rr,cc,bbb,rrr,ccc; VBit *bit_pp,*bin_pp,u; int i,npix; nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); ldest = VCreateImage(5,5,5,VUByteRepn); tmp1 = VCreateImage(5,5,5,VBitRepn); tmp2 = VCreateImage(5,5,5,VBitRepn); npix = 5 * 5 * 5; QueueSize = npix; queue.A = (Voxel *) VMalloc(sizeof(Voxel) * QueueSize); for (b=2; b<nbands-2; b++) { for (r=2; r<nrows-2; r++) { for (c=2; c<ncols-2; c++) { if (VPixel(topo,b,r,c,VUByte) != 6) continue; bit_pp = (VBit *) VPixelPtr(tmp1,0,0,0); for (i=0; i<npix; i++) *bit_pp++ = 0; bit_pp = VPixelPtr(tmp2,0,0,0); for (i=0; i<npix; i++) *bit_pp++ = 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 (ABS(bb-b) + ABS(rr-r) + ABS(cc-c) > 2) continue; u = VPixel(src,bb,rr,cc,VBit); VPixel(tmp1,bb-b+1,rr-r+1,cc-c+1,VBit) = ~ u; } } } VPixel(tmp1,2,2,2,VBit) = 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 (VPixel(topo,bb,rr,cc,VUByte) != 6) continue; bit_pp = VPixelPtr(tmp2,0,0,0); for (i=0; i<npix; i++) *bit_pp++ = 0; for (bbb=bb-1; bbb<=bb+1; bbb++) { for (rrr=rr-1; rrr<=rr+1; rrr++) { for (ccc=cc-1; ccc<=cc+1; ccc++) { if (ABS(bbb-bb) + ABS(rrr-rr) + ABS(ccc-cc) > 2) continue; u = VPixel(src,bbb,rrr,ccc,VBit); VPixel(tmp2,bbb-bb+1,rrr-rr+1,ccc-cc+1,VBit) = ~ u; } } } VPixel(tmp2,2,2,2,VBit) = 0; bit_pp = (VBit *) VPixelPtr(tmp1,0,0,0); bin_pp = (VBit *) VPixelPtr(tmp2,0,0,0); for (i=0; i<npix; i++) { *bin_pp++ = *bit_pp | *bit_pp; bin_pp++; bit_pp++; } if (CountComponents(tmp2) > 2) { VPixel(topo,b,r,c,VUByte) = 7; goto skip; } } } } skip: ; } } } return topo; }
VBoolean VReadBlockDataCompress (FILE *fp,VImageInfo *imageInfo, int row,int num_rows,VImage *buf) { int i,r; int ori_ncols; int top_margin,left_margin; size_t data,offset,ncolumns,nrows,nbands; size_t size,nitems; VPointer *dest_pp; data = imageInfo->data; size = imageInfo->pixelSize; ncolumns = imageInfo->ncolumns; nrows = imageInfo->nrows; nbands = imageInfo->nbands; ori_ncols = imageInfo->ori_ncolumns; top_margin = imageInfo->top_margin; left_margin = imageInfo->left_margin; fprintf(stderr," size; %d, ncol: %d nrows: %d, nb: %d, fp: %x data: %d \n", size,ncolumns,nrows,nbands,fp,imageInfo->data); /* initialize buffer */ dest_pp = VPixelPtr((*buf),0,0,0); memset(dest_pp,0,(int)(ori_ncols * num_rows * size)); if (row+num_rows < top_margin) return TRUE; /* Seek start of binary data */ if (fseek(fp,imageInfo->offsetHdr,SEEK_SET) == -1) return FALSE; nitems = ncolumns; /* read data from file */ for (i=0; i<nbands; i++) { if (i%50 == 0) fprintf(stderr,"b: %5d\r",i); for (r=0; r<num_rows; r++) { if (r+row < top_margin) continue; dest_pp = VPixelPtr((*buf),i,r,left_margin); offset = data + ((row+r-top_margin)*ncolumns) * size; fprintf(stderr,"off: %5d, d: %6d, %d %d %d %d\n\n", offset,data,row,r,top_margin,left_margin); if (fseek(fp,offset,SEEK_SET) != 0) return FALSE; if (fread(dest_pp,size,nitems,fp) <= 0) return FALSE; dest_pp = VPixelPtr((*buf),i,r,left_margin); fprintf(stderr,"x: %d\n",(int)(*dest_pp)); exit(0); } } return TRUE; }
int main(int argc, char *argv[]) { /* Command line options: */ static VString mat = NULL; static VBoolean funconly = FALSE; static VOptionDescRec options[] = { {"out", VStringRepn, 1, &mat, VRequiredOpt, 0, "Matfile"}, {"funconly", VBooleanRepn, 1, &funconly, VOptionalOpt, 0, "Functional data only (in one single 4D-object)"}, }; FILE *in_file; VAttrList in_list; VAttrListPosn posn; VImage src = NULL; VBit *bit_pp = NULL, *pbSRC = NULL; VShort *short_pp = NULL, *psSRC = NULL; VUByte *ubyte_pp = NULL, *puSRC = NULL; VFloat *float_pp = NULL, *pfSRC = NULL; VDouble *double_pp = NULL, *pdSRC = NULL; VString mode = NULL, name = NULL; mxArray *SRC = NULL; MATFile *fp; int n = 0, dims[4]; int bands = 0, rows = 0, cols = 0; char prg_name[100]; char ver[100]; getLipsiaVersion(ver, sizeof(ver)); sprintf(prg_name, "vtomat V%s", ver); fprintf(stderr, "%s\n", prg_name); /* Parse command line arguments and identify files: */ VParseFilterCmd(VNumber(options), options, argc, argv, &in_file,/* &out_file */ NULL); /* Read the input file */ in_list = VReadFile(in_file, NULL); if(!in_list) exit(1); /* strings */ mode = (VString)malloc(sizeof(char)); name = (VString)malloc(sizeof(char) * 50); strcpy(mode, "w"); fp = matOpen(mat, mode); if(funconly == TRUE) { /******************************************************************* * * * L O O P over objects in vista file * * * *******************************************************************/ n = 0; for(VFirstAttr(in_list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) == VShortRepn) { if(bands < 2) bands = VImageNBands(src); if(rows < 2) rows = VImageNRows(src); if(cols < 2) cols = VImageNColumns(src); if(bands != VImageNBands(src)) VError("Different bands in functional objects"); if(rows != VImageNRows(src)) VError("Different rows in functional objects"); if(cols != VImageNColumns(src)) VError("Different cols in functional objects"); n++; } } /*dimensions */ dims[3] = n; dims[2] = bands; dims[1] = rows; dims[0] = cols; SRC = mxCreateNumericArray(4, dims, mxINT16_CLASS, mxREAL); psSRC = (VShort *) mxGetPr(SRC); /* copy data to SRC */ for(VFirstAttr(in_list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); if(VPixelRepn(src) == VShortRepn) { short_pp = (VShort *) VPixelPtr(src, 0, 0, 0); memcpy(psSRC, short_pp, sizeof(VShort) * dims[0] * dims[1] * dims[2]); psSRC += dims[0] * dims[1] * dims[2]; } } /* save data into file */ if(matPutVariable(fp, "fnc", SRC)) VError("Could not save data in MATLAB file"); /* destroy array */ mxDestroyArray(SRC); } else { /******************************************************************* * * * L O O P over objects in vista file * * * *******************************************************************/ n = 0; for(VFirstAttr(in_list, & posn); VAttrExists(& posn); VNextAttr(& posn)) { if(VGetAttrRepn(& posn) != VImageRepn) continue; VGetAttrValue(& posn, NULL, VImageRepn, & src); /*dimensions */ dims[3] = 1; dims[2] = VImageNBands(src); dims[1] = VImageNRows(src); dims[0] = VImageNColumns(src); sprintf(name, "obj%d\0", n); /* Bit ONLY */ if(VPixelRepn(src) == VBitRepn) { SRC = mxCreateNumericArray(3, dims, mxLOGICAL_CLASS, mxREAL); pbSRC = (VBit *) mxGetPr(SRC); bit_pp = (VBit *) VPixelPtr(src, 0, 0, 0); memcpy(pbSRC, bit_pp, sizeof(VBit) * dims[0] * dims[1] * dims[2]); } /* Short ONLY */ if(VPixelRepn(src) == VShortRepn) { SRC = mxCreateNumericArray(3, dims, mxINT16_CLASS, mxREAL); psSRC = (VShort *) mxGetPr(SRC); short_pp = (VShort *) VPixelPtr(src, 0, 0, 0); memcpy(psSRC, short_pp, sizeof(VShort) * dims[0] * dims[1] * dims[2]); } /* UByte ONLY */ if(VPixelRepn(src) == VUByteRepn) { SRC = mxCreateNumericArray(3, dims, mxUINT8_CLASS, mxREAL); puSRC = (VUByte *) mxGetPr(SRC); ubyte_pp = (VUByte *) VPixelPtr(src, 0, 0, 0); memcpy(puSRC, ubyte_pp, sizeof(VUByte) * dims[0] * dims[1] * dims[2]); } /* Float ONLY */ if(VPixelRepn(src) == VFloatRepn) { SRC = mxCreateNumericArray(3, dims, mxSINGLE_CLASS, mxREAL); pfSRC = (VFloat *) mxGetPr(SRC); float_pp = (VFloat *) VPixelPtr(src, 0, 0, 0); memcpy(pfSRC, float_pp, sizeof(VFloat) * dims[0] * dims[1] * dims[2]); } /* Double ONLY */ if(VPixelRepn(src) == VDoubleRepn) { SRC = mxCreateNumericArray(3, dims, mxDOUBLE_CLASS, mxREAL); pdSRC = (VDouble *) mxGetPr(SRC); double_pp = (VDouble *) VPixelPtr(src, 0, 0, 0); memcpy(pdSRC, double_pp, sizeof(VDouble) * dims[0] * dims[1] * dims[2]); } /* save data into file */ if(matPutVariable(fp, name, SRC)) VError("Could not save data in MATLAB file"); /* destroy array */ mxDestroyArray(SRC); n++; } } /* Terminate */ matClose(fp); return 0; }