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 VCombineBands (int nels, VImage src_images[], VBand src_bands[], VImage dest) { int n, i; VImage result, src = src_images[0]; /* Count the number of bands needed in the destination image: */ for (i = n = 0; i < nels; i++) n += (src_bands[i] == VAllBands) ? VImageNBands (src_images[i]) : 1; /* Check or allocate the destination image: */ result = VSelectDestImage ("VCombineBands", dest, n, VImageNRows (src), VImageNColumns (src), VPixelRepn (src)); if (! result) return NULL; /* Copy each source band into the destination image: */ for (i = n = 0; i < nels; i++) { if (! VCopyBand (src_images[i], src_bands[i], result, n)) { if (result != dest) VDestroyImage (result); return NULL; } n += (src_bands[i] == VAllBands) ? VImageNBands (src_images[i]) : 1; } return result; }
VBandInterp VImageColorInterp (VImage image) { VLong interp; VGetAttrResult result; if (VImageNBands (image) != (VImageNFrames (image) * VImageNViewpoints (image) * VImageNColors (image) * VImageNComponents (image))) VWarning ("VImageColorInterp: No. bands (%d) conflicts with no. " "of frames, etc. (%d %d %d %d)", VImageNBands (image), VImageNFrames (image), VImageNViewpoints (image), VImageNColors (image), VImageNComponents (image)); if (! VImageAttrList (image) || (result = VGetAttr (VImageAttrList (image), VColorInterpAttr, VBandInterpDict, VLongRepn, & interp)) == VAttrMissing) return VImageNColors (image) > 1 ? VBandInterpOther : VBandInterpNone; if (result == VAttrBadValue) return VBandInterpOther; switch (interp) { case VBandInterpRGB: if (VImageNColors (image) != 3) { VWarning ("VBandColorInterp: RGB image has %d color dimension(s)", VImageNColors (image)); return VBandInterpOther; } return VBandInterpRGB; } return VBandInterpOther; }
VBoolean Compatible (VImage Image1, VImage Image2) { /* compare image sizes */ if ((VImageNBands (Image1) != VImageNBands (Image2)) || (VImageNRows (Image1) != VImageNRows (Image2)) || (VImageNColumns (Image1) != VImageNColumns (Image2))) { VError ("Images have different sizes"); return FALSE; } return TRUE; } /* Compatible */
/* ** read several rows of data from a file */ void VReadObjectData (FILE *fp,int object_id,VImage *image) { static VImageInfo imageInfo; static VAttrList list=NULL; fseek(fp,0L,SEEK_SET); if (! ReadHeader (fp)) VError("error reading header"); if (! (list = ReadAttrList (fp))) VError("error reading attr list"); if (! VGetImageInfo(fp,list,object_id,&imageInfo)) VError(" error reading image info"); if (imageInfo.nbands != VImageNBands((*image))) VError("incorrect number of bands"); if (imageInfo.nrows != VImageNRows((*image))) VError("incorrect number of rows"); if (imageInfo.ncolumns != VImageNColumns((*image))) VError("incorrect number of columns"); if (imageInfo.repn != VPixelRepn((*image))) VError("incorrect pixel representation"); if (! VReadBlockData (fp,&imageInfo,0,imageInfo.nrows,image)) VError(" error reading data"); }
/*! \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; }
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; }
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; }
/* * Zero out one hemisphere of a raster image */ void VImageHemi(VImage *src,VLong hemi) { int nbands,nrows,ncols; int b,r,c,c0,c1,half; ncols = VImageNColumns (*src); nrows = VImageNRows (*src); nbands = VImageNBands (*src); half = ncols/2; if (hemi == 1) { c0 = 0; c1 = half; } else { c0 = half; c1 = ncols; } for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { for (c=c0; c<c1; c++) { VSetPixel((*src),b,r,c,(VDouble) 0); } } } }
VBoolean VSetBandInterp (VImage image, VBandInterp frame_interp, int nframes, VBandInterp viewpoint_interp, int nviewpoints, VBandInterp color_interp, int ncolors, VBandInterp component_interp, int ncomponents) { VBoolean result = TRUE; VString str; if (VImageNBands (image) != nframes * nviewpoints * ncolors * ncomponents) { VWarning ("VSetBandInterp: No. bands (%d) conflicts with no. " "of frames, etc. (%d %d %d %d)", VImageNBands (image), nframes, nviewpoints, ncolors, ncomponents); result = FALSE; } if (frame_interp == VBandInterpNone) result &= VExtractAttr (VImageAttrList (image), VFrameInterpAttr, NULL, VStringRepn, & str, FALSE); else VSetAttr (VImageAttrList (image), VFrameInterpAttr, VBandInterpDict, VLongRepn, (VLong) frame_interp); VImageNFrames (image) = nframes; if (viewpoint_interp == VBandInterpNone) result &= VExtractAttr (VImageAttrList (image), VViewpointInterpAttr, NULL, VStringRepn, & str, FALSE); else VSetAttr (VImageAttrList (image), VViewpointInterpAttr, VBandInterpDict, VLongRepn, (VLong) viewpoint_interp); VImageNViewpoints (image) = nviewpoints; if (color_interp == VBandInterpNone) result &= VExtractAttr (VImageAttrList (image), VColorInterpAttr, NULL, VStringRepn, & str, FALSE); else VSetAttr (VImageAttrList (image), VColorInterpAttr, VBandInterpDict, VLongRepn, (VLong) color_interp); VImageNColors (image) = ncolors; if (component_interp == VBandInterpNone) result &= VExtractAttr (VImageAttrList (image), VComponentInterpAttr, NULL, VStringRepn, & str, FALSE); else VSetAttr (VImageAttrList (image), VComponentInterpAttr, VBandInterpDict, VLongRepn, (VLong) component_interp); VImageNComponents (image) = ncomponents; return result; }
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; }
int main (int argc, char *argv[]) { static VShort band; static VOptionDescRec options[] = { { "band", VShortRepn, 1, & band, VOptionalOpt, NULL,"Image band to convert" } }; FILE *infile, *outfile; int nimages; VAttrList attributes; VImage *images, image; char prg[50]; sprintf(prg,"vtopgm V%s", getVersion()); fprintf (stderr, "%s\n", prg); /* Parse command line arguments and identify the input and output files */ VParseFilterCmd (VNumber (options), options, argc, argv, & infile, & outfile); /* Read all images from the input file */ if ((nimages = VReadImages (infile, & attributes, & images)) == 0) exit (EXIT_FAILURE); /* no images found */ fclose (infile); /* Ensure that the specified band exists: */ if (nimages != 1) VWarning ("Only the first of %d images will be converted", nimages); if (band < 0 || band >= VImageNBands (images[0])) VError ("Image of %d band(s) has no band %d", VImageNBands (images[0]), band); /* Convert the image to UByte: */ if (VPixelRepn(images[0]) != VUByteRepn) { image = VConvertImageRange (images[0], NULL, (VBand) band, VUByteRepn); if (! image) exit (EXIT_FAILURE); band = 0; } else image = images[0]; /* Output the first image as a pgm file. */ WritePgmFile (outfile, image, (VBand) band); return EXIT_SUCCESS; }
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; }
VBoolean VCopyBand (VImage src, VBand src_band, VImage dest, VBand dest_band) { int nbands, src_npixels, dest_npixels; VPointer src_pixels, dest_pixels; /* The destination image must exist: */ if (! dest) { VWarning ("VCopyBand: No destination specified"); return FALSE; } /* VAllBands not accepted for destination band: */ if (dest_band < 0 || dest_band >= VImageNBands (dest)) { VWarning ("VCopyBand: Band %d referenced in image of %d bands", (int) dest_band, (int) VImageNBands (dest)); return FALSE; } /* Ensure that the destination image has the appropriate dimensions and pixel representation: */ nbands = dest_band; if (src_band == VAllBands) nbands += VImageNBands (src) - 1; if (nbands < VImageNBands (dest)) nbands = VImageNBands (dest); if (! VSelectDestImage ("VCopyBand", dest, nbands, VImageNRows (src), VImageNColumns (src), VPixelRepn (src))) return FALSE; /* Locate the specified source and destination bands: */ if (! VSelectBand ("VCopyBand", src, src_band, & src_npixels, & src_pixels)) return FALSE; if (! VSelectBand ("VCopyBand", dest, dest_band, & dest_npixels, & dest_pixels)) return FALSE; /* Copy from the source band to the destination band: */ memcpy (dest_pixels, src_pixels, src_npixels * VPixelSize (src)); return TRUE; }
VBoolean VSelectBand (VStringConst routine, VImage image, VBand band, int *npixels, VPointer *first_pixel) { if (band == VAllBands) { if (npixels) *npixels = VImageNPixels (image); if (first_pixel) *first_pixel = VImageData (image); } else if (band >= 0 && band < VImageNBands (image)) { if (npixels) *npixels = VImageNRows (image) * VImageNColumns (image); if (first_pixel) *first_pixel = image->band_index[band][0]; } else { VWarning ("%s: Band %d referenced in image of %d band(s)", routine, band, VImageNBands (image)); return FALSE; } return TRUE; }
VImage VCopyImage (VImage src, VImage dest, VBand band) { VImage result; if (src == dest && (band == VAllBands || (band == 0 && VImageNBands (src) == 1))) return src; if ((result = VCopyImagePixels (src, dest, band)) != 0) VCopyImageAttrs (src, result); return result; }
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 */
unsigned short CVImage::getSize( Direction dir, VImage image ) { switch( dir ) { case read: return VImageNColumns( image ); break; case phase: return VImageNRows( image ); break; case slice: return VImageNBands( image ); break; } }
VImage VCombineBandsVa (VImage dest, ...) { va_list args; VImage src, result; int nbands; VBand src_band, dest_band; /* Count the number of bands to be combined: */ va_start (args, dest); for (nbands = 0; (src = va_arg (args, VImage)) != 0; nbands += (va_arg (args, VBand) == VAllBands) ? VImageNBands (src) : 1) ; va_end (args); /* Check or allocate the destination image: */ va_start (args, dest); src = va_arg (args, VImage); va_end (args); result = VSelectDestImage ("VCombineBandsVa", dest, nbands, VImageNRows (src), VImageNColumns (src), VPixelRepn (src)); if (! result) return NULL; /* Copy each source band into the destination image: */ va_start (args, dest); for (dest_band = 0; (src = va_arg (args, VImage)) != 0; ) { src_band = va_arg (args, VBand); if (! VCopyBand (src, src_band, result, dest_band)) { if (result != dest) VDestroyImage (result); return NULL; } dest_band += (src_band == VAllBands) ? VImageNBands (src) : 1; } va_end (args); return result; }
/*! \fn VImage VMedianImage2d (VImage src, VImage dest, int dim, VBoolean ignore) \param src input image \param dest output image \param dim kernel size \param ignore whether to ignore zero voxels */ VImage VMedianImage2d (VImage src, VImage dest, int dim, VBoolean ignore) { int nbands,nrows,ncols; int i,len,b,r,c,rr,cc,d=0; gsl_vector *vec=NULL; double u,tiny=1.0e-10; if (dim%2 == 0) VError("VMedianImage2d: dim (%d) must be odd",dim); nrows = VImageNRows (src); ncols = VImageNColumns (src); nbands = VImageNBands (src); d = dim/2; len = dim * dim; vec = gsl_vector_calloc(len); dest = VCopyImage(src,dest,VAllBands); for (b=0; b<nbands; b++) { for (r=d; r<nrows-d; r++) { for (c=d; c<ncols-d; c++) { gsl_vector_set_zero(vec); u = VGetPixel(src,b,r,c); if ( !ignore || ABS(u) > tiny) { i = 0; for (rr=r-d; rr<=r+d; rr++) { for (cc=c-d; cc<=c+d; cc++) { u = VGetPixel(src,b,rr,cc); if (ABS(u) > 0) { gsl_vector_set(vec,i,u); i++; } } } gsl_sort_vector(vec); u = gsl_stats_median_from_sorted_data(vec->data,vec->stride,i); VSetPixel(dest,b,r,c,u); } } } } return dest; }
/*! \fn VImage VMapImageRange(VImage src,VImage dest,VRepnKind repn) \brief The minimum and maximum grey values of the input images are computed, and a linear mapping is performed mapping the input minimum(maximum) of the input image to the min(max) value of the output pixel repn. E.g. if the input image min is -17 and its max is +2376, and the output repn is VUByteRepn, then the linear mapping function maps -17 to 0 and +2376 to 255. \param src input image (any repn) \param dest output image \param repn the output pixel repn (e.g. VUByteRepn) */ VImage VMapImageRange(VImage src,VImage dest,VRepnKind repn) { int i,nbands,nrows,ncols,npixels; float u,ymin,ymax,dmin,dmax,slope; if (repn == VDoubleRepn || repn == VLongRepn || repn == VSByteRepn) VError(" VMapImageRange: double, long and sbyte are not supported"); nbands = VImageNBands(src); nrows = VImageNRows(src); ncols = VImageNColumns(src); npixels = VImageNPixels(src); dest = VSelectDestImage("VMapImageRange",dest,nbands,nrows,ncols,repn); if (! dest) VError(" err creating dest image"); VFillImage(dest,VAllBands,0); ymin = VPixelMaxValue(src); ymax = VPixelMinValue(src); for (i=0; i<npixels; i++) { u = VGetPixelValue (src,i); if (u < ymin) ymin = u; if (u > ymax) ymax = u; } dmax = VPixelMaxValue(dest); dmin = VPixelMinValue(dest); slope = (dmax - dmin) / (ymax - ymin); for (i=0; i<npixels; i++) { u = VGetPixelValue (src,i); u = slope * (u - ymin); if (u < dmin) u = dmin; if (u > dmax) u = dmax; VSetPixelValue(dest,i,(VFloat) u); } VCopyImageAttrs (src, dest); 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 VCopyImagePixels (VImage src, VImage dest, VBand band) { int npixels; VPointer src_pixels; VImage result; /* Locate the source and destination of the copy: */ if (! VSelectBand ("VCopyImagePixels", src, band, & npixels, & src_pixels)) return NULL; result = VSelectDestImage ("VCopyImagePixels", dest, band == VAllBands ? VImageNBands (src) : 1, VImageNRows (src), VImageNColumns (src), VPixelRepn (src)); if (! result) return NULL; /* Copy pixel values from src to dest: */ memcpy (VImageData (result), src_pixels, npixels * VPixelSize (src)); return result; }
VImage VSConvolveRow (VImage src,VImage dest,VImage kernel) { int b,r,c,nbands,nrows,ncols; int r0,r1,rr; float sum,x; VFloat *float_pp; int d,dim; dim = VImageNColumns(kernel); d = dim/2; nrows = VImageNRows (src); ncols = VImageNColumns (src); nbands = VImageNBands (src); dest = VSelectDestImage("VConvolveRow",dest,nbands,nrows,ncols,VFloatRepn); for (b=0; b<nbands; b++) { for (r=d; r<nrows-d; r++) { for (c=0; c<ncols; c++) { float_pp = (VFloat *) VImageData(kernel); sum = 0; r0 = r-d; r1 = r+d; if (r0 < 0) r0 = 0; if (r1 >= nrows) r1 = nrows-1; for (rr=r0; rr<=r1; rr++) { x = VPixel(src,b,rr,c,VFloat); sum += x * (*float_pp++); } VPixel(dest,b,r,c,VFloat) = sum; } } } return dest; }
VImage VSConvolveCol (VImage src,VImage dest,VImage kernel) { int b,r,c,nbands,nrows,ncols; int c0,c1,cc; float sum,x; VFloat *float_pp; int dim,d; nrows = VImageNRows (src); ncols = VImageNColumns (src); nbands = VImageNBands (src); dest = VSelectDestImage("VConvolveCol",dest,nbands,nrows,ncols,VFloatRepn); VFillImage(dest,VAllBands,0); dim = VImageNColumns(kernel); d = dim/2; for (b=0; b<nbands; b++) { for (r=0; r<nrows; r++) { for (c=d; c<ncols-d; c++) { float_pp = (VFloat *) VImageData(kernel); sum = 0; c0 = c-d; c1 = c+d; if (c0 < 0) c0 = 0; if (c1 >= ncols) c1 = ncols-1; for (cc=c0; cc<=c1; cc++) { x = VPixel(src,b,r,cc,VFloat); sum += x * (*float_pp++); } VPixel(dest,b,r,c,VFloat) = sum; } } } return dest; }
VImage VSConvolveBand (VImage src,VImage dest,VImage kernel) { int b,r,c,nbands,nrows,ncols; int b0,b1,bb; float sum,x; VFloat *float_pp; int d,dim; dim = VImageNColumns(kernel); d = dim/2; nrows = VImageNRows (src); ncols = VImageNColumns (src); nbands = VImageNBands (src); dest = VSelectDestImage("VConvolveBand",dest,nbands,nrows,ncols,VFloatRepn); for (b=d; b<nbands-d; b++) { for (r=0; r<nrows; r++) { for (c=0; c<ncols; c++) { float_pp = (VFloat *) VImageData(kernel); sum = 0; b0 = b-d; b1 = b+d; if (b0 < 0) b0 = 0; if (b1 >= nbands) b1 = nbands-1; for (bb=b0; bb<=b1; bb++) { x = VPixel(src,bb,r,c,VFloat); sum += x * (*float_pp++); } VPixel(dest,b,r,c,VFloat) = sum; } } } return dest; }
/* * Flip3dImage * */ VImage Flip3dImage(VImage src, VImage dest, VBand band, VBoolean x_axis, VBoolean y_axis, VBoolean z_axis) { int nx, ny, nz; int i, j, k; nx = VImageNColumns(src); ny = VImageNRows(src); nz = VImageNBands(src); /* Check the destination image. If it is NULL, then create one of the appropriate size and type. */ dest = VSelectDestImage("Flip3dImage", dest, nz, ny, nx, VPixelRepn(src)); if(! dest) return NULL; for(i = 0; i < nx; i++) for(j = 0; j < ny; j++) for(k = 0; k < nz; k++) { if(! x_axis && ! y_axis && ! z_axis) VSetPixel(dest, k, j, i, VGetPixel(src, k, j, i)); if(x_axis && ! y_axis && ! z_axis) VSetPixel(dest, k, j, i, VGetPixel(src, k, j, nx - i - 1)); if(! x_axis && y_axis && ! z_axis) VSetPixel(dest, k, j, i, VGetPixel(src, k, ny - j - 1, i)); if(! x_axis && ! y_axis && z_axis) VSetPixel(dest, k, j, i, VGetPixel(src, nz - k - 1, j, i)); if(x_axis && y_axis && ! z_axis) VSetPixel(dest, k, j, i, VGetPixel(src, k, ny - j - 1, nx - i - 1)); if(x_axis && ! y_axis && z_axis) VSetPixel(dest, k, j, i, VGetPixel(src, nz - k - 1, j, nx - i - 1)); if(! x_axis && y_axis && z_axis) VSetPixel(dest, k, j, i, VGetPixel(src, nz - k - 1, ny - j - 1, i)); if(x_axis && y_axis && z_axis) VSetPixel(dest, k, j, i, VGetPixel(src, nz - k - 1, ny - j - 1, nx - i - 1)); }; /* Let the destination inherit any attributes of the source image: */ VCopyImageAttrs(src, dest); return dest; };
static VAttrList VImageEncodeAttrMethod (VPointer value, size_t *lengthp) { VImage image = value; VAttrList list; size_t length; #define OptionallyPrepend(value, name) \ if (value != 1) \ VPrependAttr (list, name, NULL, VLongRepn, (VLong) value) /* Temporarily prepend several attributes to the image's attribute list: */ if ((list = VImageAttrList (image)) == NULL) list = VImageAttrList (image) = VCreateAttrList (); VPrependAttr (list, VRepnAttr, VNumericRepnDict, VLongRepn, (VLong) VPixelRepn (image)); VPrependAttr (list, VNColumnsAttr, NULL, VLongRepn, (VLong) VImageNColumns (image)); VPrependAttr (list, VNRowsAttr, NULL, VLongRepn, (VLong) VImageNRows (image)); OptionallyPrepend (VImageNComponents (image), VNComponentsAttr); OptionallyPrepend (VImageNColors (image), VNColorsAttr); OptionallyPrepend (VImageNViewpoints (image), VNViewpointsAttr); OptionallyPrepend (VImageNFrames (image), VNFramesAttr); OptionallyPrepend (VImageNBands (image), VNBandsAttr); /* Compute the file space needed for the image's binary data: */ length = VImageNPixels (image); if (VPixelRepn (image) == VBitRepn) length = (length + 7) / 8; else length *= VPixelPrecision (image) / 8; *lengthp = length; return list; #undef OptionallyPrepend }
int main (int argc,char *argv[]) { static VString filename = ""; static VString filename1 = ""; static VString filename2 = ""; static VShort first = 2; static VShort length = 0; static VShort type = 0; static VShort minval = 0; static VShort nproc = 4; static VOptionDescRec options[] = { {"in1",VStringRepn,1,(VPointer) &filename1,VRequiredOpt,NULL,"first input file"}, {"in2",VStringRepn,1,(VPointer) &filename2,VRequiredOpt,NULL,"second input file"}, {"mask",VStringRepn,1,(VPointer) &filename,VRequiredOpt,NULL,"mask"}, {"type",VShortRepn,1,(VPointer) &type,VOptionalOpt,TYPDict,"type of concordance measure"}, {"minval",VShortRepn,1,(VPointer) &minval,VOptionalOpt,NULL,"signal threshold"}, {"first",VShortRepn,1,(VPointer) &first,VOptionalOpt,NULL,"first timestep to use"}, {"length",VShortRepn,1,(VPointer) &length,VOptionalOpt,NULL, "length of time series to use, '0' to use full length"}, {"j",VShortRepn,1,(VPointer) &nproc,VOptionalOpt,NULL,"number of processors to use, '0' to use all"} }; FILE *out_file,*fp; VAttrList list=NULL,list1=NULL,list2=NULL,out_list=NULL; VAttrListPosn posn; VImage mask=NULL,map=NULL,dest=NULL,disc=NULL; float *A1=NULL,*A2=NULL,u=0,tiny=1.0e-6; int b,r,c; char *prg = "vccm2"; VParseFilterCmd (VNumber (options),options,argc,argv,NULL,&out_file); if (type > 3) VError("illegal type"); /* ** read mask */ fp = VOpenInputFile (filename, TRUE); list = VReadFile (fp, NULL); if (! list) VError("Error reading mask file"); fclose(fp); for (VFirstAttr (list, & posn); VAttrExists (& posn); VNextAttr (& posn)) { if (VGetAttrRepn (& posn) != VImageRepn) continue; VGetAttrValue (& posn, NULL,VImageRepn, & mask); if (VPixelRepn(mask) == VFloatRepn || VPixelRepn(mask) == VDoubleRepn) { mask = NULL; continue; } } if (mask == NULL) VError(" no mask found"); /* read files */ fp = VOpenInputFile (filename1, TRUE); list1 = VReadFile (fp, NULL); if (! list1) VError("Error reading 1st input file"); fclose(fp); fp = VOpenInputFile (filename2, TRUE); list2 = VReadFile (fp, NULL); if (! list2) VError("Error reading 2nd input file"); fclose(fp); /* get voxel map */ map = GetMap(list1,list2,mask,minval); /* omp-stuff */ #ifdef _OPENMP int num_procs=omp_get_num_procs(); if (nproc > 0 && nproc < num_procs) num_procs = nproc; printf("using %d cores\n",(int)num_procs); omp_set_num_threads(num_procs); #endif /* _OPENMP */ /* compute corr matrices */ A1 = VCorrMatrix(list1,map,first,length); A2 = VCorrMatrix(list2,map,first,length); /* get concordance between two corr matrices */ dest = VCCM2(A1,A2,map,(int)type); /* invert to get discordant map */ disc = VCreateImageLike(dest); VFillImage(disc,VAllBands,0); if (type < 2) { for (b=0; b<VImageNBands(dest); b++) { for (r=0; r<VImageNRows(dest); r++) { for (c=0; c<VImageNColumns(dest); c++) { if (VGetPixel(mask,b,r,c) < 1) continue; u = VPixel(dest,b,r,c,VFloat); if (u < tiny) continue; VPixel(disc,b,r,c,VFloat) = 1-u; } } } } /* output */ out_list = VCreateAttrList(); VHistory(VNumber(options),options,prg,&list,&out_list); VAppendAttr(out_list,"concordant",NULL,VImageRepn,dest); if (type < 2) VAppendAttr(out_list,"discordant",NULL,VImageRepn,disc); if (! VWriteFile (out_file, out_list)) exit (1); fprintf (stderr, "%s: done.\n", argv[0]); return 0; }
float * VCorrMatrix(VAttrList list,VImage map,VShort first,VShort length) { VAttrListPosn posn; VImage src[NSLICES]; size_t b,r,c,i,j,i1,n,m,nt,last,ntimesteps,nrows,ncols,nslices; gsl_matrix_float *mat=NULL; float *A=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); /* number of voxels */ n = VImageNColumns(map); fprintf(stderr," ntimesteps: %d, first= %d, last= %d, nt= %d, nvoxels: %ld\n", (int)ntimesteps,(int)first,(int)last,(int)nt,(long)n); /* ** avoid casting to float, copy data to matrix */ mat = gsl_matrix_float_calloc(n,nt); if (!mat) VError(" err allocating mat"); for (i=0; i<n; i++) { b = VPixel(map,0,0,i,VShort); r = VPixel(map,0,1,i,VShort); c = VPixel(map,0,2,i,VShort); 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," compute correlation matrix...\n"); A = (float *) VCalloc(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] = v; } } fprintf(stderr," matrix done.\n"); gsl_matrix_float_free(mat); return A; }