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; }
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; }