Beispiel #1
0
/*-------------------------------------------------------------------
* CTSliceSetVal - set a value in a CT image
*-------------------------------------------------------------------
*/
void CTSliceSetVal(CTSlice slice, int x, int y, float val)
{
	if (CTSliceShorts(slice))
		CTSliceShortData(slice, x, y) = (unsigned short) val;
	else if (CTSliceChars(slice))
		CTSliceCharData(slice, x, y) = (unsigned char) val;
	else if (CTSliceFloats(slice))
		CTSliceFloatData(slice, x, y) = val;
}
Beispiel #2
0
/*-------------------------------------------------------------------
* CTWritePGM - write a slice in portable greymap format
*-------------------------------------------------------------------
*/
static int CTWritePGM(char *path, CTSlice slice)
{
	FILE *fp;
	int i, j;
//	int c, width, height, max;
//	unsigned char *line;
	
	if ((fp=fopen(path, "w")) == NULL)
		return(0);
	
	if (CTSliceMaxD(slice) <= 255) 
	{
		fprintf(fp, "P5\n%d %d\n%d\n", CTSliceXSize(slice), CTSliceYSize(slice),
			CTSliceMaxD(slice));
		if (CTSliceChars(slice)) 
		{
			for (i=CTSliceYSize(slice)-1; i>=0; i--)
			{
				for (j=0; j<CTSliceXSize(slice); j++)
					fputc(CTSliceCharData(slice, j, i), fp);
			}
		}
		else if (CTSliceShorts(slice)) 
		{
			for (i=CTSliceYSize(slice)-1; i>=0; i--)
			{
				for (j=0; j<CTSliceXSize(slice); j++)
					fputc(CTSliceShortData(slice, j, i), fp);
			}
		}
	}
	else
	{
		fprintf(fp, "P2\n%d %d\n%d\n", CTSliceXSize(slice), CTSliceYSize(slice),
			CTSliceMaxD(slice));
		for (i=CTSliceYSize(slice)-1; i>=0; i--)
		{
			for (j=0; j<CTSliceXSize(slice); j++)
				fputc(CTSliceShortData(slice, j, i), fp);
		}
	}
	
	fclose(fp);
	return(1);
}
CTVolume
CTVolumeHartley3D(CTVolume vol)
{
	CTVolume vol2;
	CTSlice slice;
	int l,m,n,L,M,N,i,j,k;
	
	#ifdef USE_PTIME
		int t1,t2;
	#endif
	
	float *d1,*d2,*X,*D,Z,*w,*w1,*w2;
	float *Mcas, *Lcos, *Lsin, *Ncos, *Nsin, max, min;
	double dL, dM, dN, s, c;
	
	/* Get source volume info. */
	L = CTVolXSize(vol);
	M = CTVolYSize(vol);
	N = CTVolNumSlices(vol);
	dL = (double)L;
	dM = (double)M;
	dN = (double)N;
	
	/* Initialize the new volume. */
	vol2 = CTVolumeCreate(CTH3D,CTVolPrefix(vol),".h3d",CTVolXSize(vol),
		CTVolYSize(vol),CTVolZSize(vol),CTVolXSep(vol),
		CTVolYSep(vol),CTVolZSep(vol),CTVolFirstSlice(vol),
		CTVolLastSlice(vol),1.0e10,CT_MSBF,CT_FLOAT);
	
	/* Open the new volume for writing. */
	CTVolumeOpen(vol2,CTH3D,CTVolPrefix(vol2),".h3d");
	
	/* Read in the volume data. */
	D = (float *)malloc(L*M*N*sizeof(float));

	switch (CTVolVoxelBits(vol)) 
	{
		
		/* Read in and convert CT_8BIT values to CT_FLOAT. */
		case CT_8BIT:
			for (n=0;n<N;n++) 
			{
				slice = CTSliceRead(vol,n+CTVolFirstSlice(vol),-1,-1,-1,-1);
				for (l=0;l<L;l++) 
				{
					for (m=0;m<M;m++) 
					{
						D[n+N*(l+L*m)] = (float)CTSliceCharData(slice,l,m);
					}
				}
				CTSliceFree(slice);
			}
			break;
			
			/* Read in and convert CT_16BIT values to CT_FLOAT. */
		case CT_16BIT:
			for (n=0;n<N;n++) 
			{
				slice = CTSliceRead(vol,n+CTVolFirstSlice(vol),-1,-1,-1,-1);
				for (l=0;l<L;l++) 
				{
					for (m=0;m<M;m++) 
					{
						D[n+N*(l+L*m)] = (float)CTSliceShortData(slice,l,m);
					}
				}
				CTSliceFree(slice);
			}
			break;
			
			/* Read in CT_FLOAT values. */
		case CT_FLOAT:
			for (n=0;n<N;n++) 
			{
				slice = CTSliceRead(vol,n+CTVolFirstSlice(vol),-1,-1,-1,-1);
				for (l=0;l<L;l++) 
				{
					for (m=0;m<M;m++) 
					{
						D[n+N*(l+L*m)] = CTSliceFloatData(slice,l,m);
					}
				}
				CTSliceFree(slice);
			}
			break;
	}
	
	/* Precompute necessary sin, cos, and cas function values. */
	Lcos = (float *)malloc(sizeof(float)*L*L);
	Lsin = (float *)malloc(sizeof(float)*L*L);
	Ncos = (float *)malloc(sizeof(float)*N*N);
	Nsin = (float *)malloc(sizeof(float)*N*N);
	Mcas = (float *)malloc(sizeof(float)*M*M);

	for (i=0;i<L*L;i++) 
	{
		s = sin(2.0*M_PI*(double)i/dL);
		c = cos(2.0*M_PI*(double)i/dL);
		Lcos[i] = (float)c;
		Lsin[i] = (float)s;
	}
	
	for (i=0;i<N*N;i++) 
	{
		s = sin(2.0*M_PI*(double)i/dN);
		c = cos(2.0*M_PI*(double)i/dN);
		Ncos[i] = (float)c;
		Nsin[i] = (float)s;
	}
	
	for (i=0;i<M*M;i++) 
	{
		s = sin(2.0*M_PI*(double)i/dM);
		c = cos(2.0*M_PI*(double)i/dM);
		Mcas[i] = (float)(s+c);
	}
	
	/* Algorithm is O(LLMN+LMMN+LMNN). */
	X = (float *)malloc(L*M*sizeof(float));
	w1 = (float *)malloc(L*M*sizeof(float));
	w2 = (float *)malloc(M*sizeof(float));
	
#ifdef USE_PTIME
	t1 = t2 = time(NULL);
#endif
	
	/*
    Transfrom the original volume and write the new volume one slice at
    a time, in order.
	*/
	for (k=0;k<N;k++) 
	{
		
		/* Initialize max and min values for each slice. */
		min = 1.0e10;
		max = -1.0e10;
		
		/* Compute w1(i,m,n) */
		d1 = D;
		w = w1;
		for (m=0;m<M;m++) 
		{
			for (l=0;l<L;l++) 
			{
				d2 = &D[N*((L-l)%L+L*((M-m)%M))];
				*w = 0.0;
				
				for (n=0;n<N;n++) 
				{
					*w += (*d1++)*Ncos[k*n]+(*d2++)*Nsin[k*n];
				}
				
				w++;
			}
		}
		
		/* Compute w2(i,j,n) */
		for (i=0;i<L;i++) 
		{
			w = w2;
			d1 = w1;
			for (m=0;m<M;m++) 
			{
				*w = 0.0;
				d2 = &w1[L*((M-m)%M)];
				
				for (l=0;l<L;l++) 
				{
					*w += (*d1++)*Lcos[i*l]+(*d2++)*Lsin[i*l];
				}
				
				w++;
			}
			
			/* Compute X(i,j,k) */
			for (j=0;j<M;j++) 
			{
				Z = 0.0;
				w = w2;
				
				for (m=0;m<M;m++) 
				{
					Z += (*w++)*Mcas[j*m];
				}
				
				if (Z>max) max = Z;
				if (Z<min) min = Z;
				X[i+L*j] = Z;
			}
		}
		
		/* Write the transformed slice. */
		slice = CTSliceCreate(L,M,min,max,vol2,k);

		for (i=0;i<L;i++) 
		{
			for (j=0;j<M;j++) 
			{
				CTSliceSetVal(slice,i,j,X[i+L*j]);
			}
		}
		CTSliceWrite(NULL,slice);
		CTSliceFree(slice);
		
#ifdef USE_PTIME
		printf("Slice %d/%d, ",k+1,N);
		ptime((int)((float)(time(NULL)-t1)/(float)(k+1)*(float)(N-k-1)));
		printf("\n");
#endif
		
	}
	
	/* Done writing to the new volume. */
	CTVolumeClose(vol2);
	
#ifdef USE_PTIME
	t2 = time(NULL);
	printf("(3D)Total time: ");
	ptime(t2-t1);
	printf("\n");
#endif
	
	/* Return the transformed volume. */
	return(vol2);
}
Beispiel #4
0
/*------------------------------------------------------------------------
* CTSliceCompMinMaxD - compute min and max densities for a slice
*------------------------------------------------------------------------
*/
void CTSliceCompMinMaxD(CTSlice slice)
{
	double val;
	int i, j;
	unsigned long nnonzero;
	
	CTSliceMaxD(slice) = -1e100;
	CTSliceMinD(slice) = 1e100;
	nnonzero=0;
	
	if (CTSliceShorts(slice)) 
	{
		for (i=CTSliceMinX(slice); i<=CTSliceMaxX(slice); i++)
		{
			for (j=CTSliceMinY(slice); j<=CTSliceMaxY(slice); j++) 
			{
				if ((val=CTSliceShortData(slice, i, j)) > CTVolNoise(slice->vol))
					continue;
				if (val > CTSliceMaxD(slice))
					CTSliceMaxD(slice) = val;
				if (val < CTSliceMinD(slice))
					CTSliceMinD(slice) = val;
				if (val != 0)
					nnonzero++;
			}
		}
	}
	else if (CTSliceChars(slice)) 
	{
		for (i=CTSliceMinX(slice); i<=CTSliceMaxX(slice); i++)
		{
			for (j=CTSliceMinY(slice); j<=CTSliceMaxY(slice); j++) 
			{
				if ((val=CTSliceCharData(slice, i, j)) > CTVolNoise(slice->vol))
					continue;
				if (val > CTSliceMaxD(slice))
					CTSliceMaxD(slice) = val;
				if (val < CTSliceMinD(slice))
					CTSliceMinD(slice) = val;
				if (val != 0)
					nnonzero++;
			}
		}
	}
	else if (CTSliceFloats(slice)) 
	{
		for (i=CTSliceMinX(slice); i<=CTSliceMaxX(slice); i++)
		{
			for (j=CTSliceMinY(slice); j<=CTSliceMaxY(slice); j++) 
			{
				if ((val=CTSliceFloatData(slice, i, j)) > CTVolNoise(slice->vol))
					continue;
				if (val > CTSliceMaxD(slice))
					CTSliceMaxD(slice) = val;
				if (val < CTSliceMinD(slice))
					CTSliceMinD(slice) = val;
				if (val != 0)
					nnonzero++;
			}
		}
	}
	CTSliceRatio(slice) = nnonzero/
		(double)(CTSliceWidth(slice)*CTSliceHeight(slice));
}
Beispiel #5
0
/*-------------------------------------------------------------------
* CTReadPGM - read a slice from a portable greymap file
*-------------------------------------------------------------------
*/
static int CTReadPGM(FILE *fp, CTSlice slice, int x1, int y1, int x2, int y2)
{
	int c, i, j, width, height, max;
	unsigned char *line;
	char buf[1024];
	
	/* read for the magic number, skipping comments */
	while ((c=fgetc(fp)) == '#')
		fgets(buf, 1024, fp);

	ungetc(c, fp);
	if (fscanf(fp, "P%d\n", &c) != 1)
		return(-1);
	
	if (c != 2 && c != 5) 
	{
		/* file is not PGM, fail */
		return(-1);
	}
	
	if (c==2) 
	{
		
		while ((c=fgetc(fp)) == '#')
			fgets(buf, 1024, fp);
		ungetc(c, fp);
		
		if (fscanf(fp, "%d%d%d", &width, &height, &max) != 3)
			return(-1);
		
		if (x1==-1) 
		{
			slice->x1=slice->y1=x1=y1=0;
			slice->x2=x2=width-1;
			slice->y2=y2=height-1;
			slice->data = (unsigned short *)malloc(sizeof(unsigned short)*
				(x2-x1+1)*(y2-y1+1));
			memset(slice->data, 0, sizeof(short)*(x2-x1+1)*(y2-y1+1));
			CTSliceWidth(slice) = width;
			CTSliceHeight(slice) = height;
		}
		
		/* eat extra character */
		getc(fp);
		for (i=height-1; i>=0; i--)
		{
			for (j=0; j<width; j++) 
			{
				int val;
				
				fscanf(fp, "%d", &val);
				CTSliceShortData(slice, j, i) = val;
			}
		}

			CTSliceCompMinMaxD(slice);
			return(0);
	}
	else if (c==5) 
	{
		while ((c=fgetc(fp)) == '#')
			fgets(buf, 1024, fp);
		ungetc(c, fp);
		if (fscanf(fp, "%d%d%d", &width, &height, &max) != 3) 
		{
			printf("failed to read width/height/max\n");
			return(-1);
		}
		
		if (x1==-1) 
		{
			slice->x1=slice->y1=x1=y1=0;
			slice->x2=x2=width-1;
			slice->y2=y2=height-1;
			slice->cdata = (unsigned char *)malloc(sizeof(unsigned char)*
				(x2-x1+1)*(y2-y1+1));
			memset(slice->cdata, '\0', sizeof(char)*(x2-x1+1)*(y2-y1+1));
			CTSliceWidth(slice) = width;
			CTSliceHeight(slice) = height;
		}
		/* eat extra character */
		getc(fp);
		
		line = (unsigned char *)malloc(sizeof(char)*width);
		for (i=height-1; i>=0; i--) 
		{
			fread(line, 1, width, fp);
			if (y1 <= i && i <= y2)
			{
				for (j=0; j<width; j++)
				{
					if (x1 <= j && j <= x2)
						CTSliceCharData(slice, j, i) = line[j];
				}
			}
		}
		free(line);
		CTSliceCompMinMaxD(slice);
		return(0);
	}
	return(1);
}
Beispiel #6
0
/*-------------------------------------------------------------------
* CTReadRAS - read a slice from a sun raster file
*-------------------------------------------------------------------
*/
static int CTReadRAS(FILE *fp, CTSlice slice, int x1, int y1, int x2, int y2)
{
	int               linesize,lsize,csize,isize,flipit,i,j,w,h,d,rv;
	unsigned char     *line, r[256], g[256], b[256];
	struct rasterfile sunheader;
	
	rv = 0;
	
	/* read in the Sun Rasterfile picture */
	flipit = 0;
	fread(&sunheader, sizeof(struct rasterfile), 1, fp);
	
	if (sunheader.ras_magic != RAS_MAGIC) 
	{
		flipl( (unsigned char *) &sunheader.ras_magic);
		if (sunheader.ras_magic == RAS_MAGIC)
			flipit = 1;
		else
			flipl( (unsigned char *) &sunheader.ras_magic);
	}
	
	if (sunheader.ras_magic != RAS_MAGIC)
		return( SunRasError("not a Sun rasterfile") );
	
	if (flipit) {
		flipl((unsigned char *) &sunheader.ras_width);
		flipl((unsigned char *) &sunheader.ras_height);
		flipl((unsigned char *) &sunheader.ras_depth);
		flipl((unsigned char *) &sunheader.ras_length);
		flipl((unsigned char *) &sunheader.ras_type);
		flipl((unsigned char *) &sunheader.ras_maptype);
		flipl((unsigned char *) &sunheader.ras_maplength);
	}
	
	/* make sure that the input picture can be dealt with */
	if (sunheader.ras_depth != 8) 
	{
		fprintf (stderr, "Sun rasterfile image has depth %d\n",
			sunheader.ras_depth);
		fprintf (stderr, "Depths supported are 8\n");
		return 1;
	}
	
	if (sunheader.ras_type != RT_OLD && sunheader.ras_type != RT_STANDARD &&
		sunheader.ras_type != RT_BYTE_ENCODED &&
		sunheader.ras_type != RT_FORMAT_RGB) 
	{
		fprintf (stderr, "Sun rasterfile of unsupported type %d\n",
			sunheader.ras_type);
		return 1;
	}
	
	if (sunheader.ras_maptype != RMT_RAW && sunheader.ras_maptype != RMT_NONE &&
		sunheader.ras_maptype != RMT_EQUAL_RGB) 
	{
		fprintf (stderr, "Sun rasterfile colormap of unsupported type %d\n",
			sunheader.ras_maptype);
		return 1;
	}
	
	w = sunheader.ras_width;
	h = sunheader.ras_height;
	d = sunheader.ras_depth;
	isize = sunheader.ras_length ?
		sunheader.ras_length :
	(w * h * d) / 8;
	csize = (sunheader.ras_maptype == RMT_NONE) ? 0 : sunheader.ras_maplength;
	lsize = w * h * ( d == 1 ? d : d/8);
	linesize = w * d;
	/* if ((linesize % 48) && d == 24) linesize += (48 - (linesize % 48)); */
	if (linesize % 16) linesize += (16 - (linesize % 16));
	linesize /= 8;
	
#ifdef DEBUG
	fprintf(stderr,"%s: LoadSunRas() - loading a %dx%d pic, %d planes\n",
		cmd, w, h, d);
	fprintf(stderr,
		"type %d, maptype %d, isize %d, csize %d, lsize %d, linesize %d\n",
		sunheader.ras_type, sunheader.ras_maptype,
		isize, csize, lsize, linesize);
#endif
	
	
	/* read in the colormap, if any */
	if (sunheader.ras_maptype == RMT_EQUAL_RGB && csize) 
	{
		fread (r, sizeof(unsigned char), sunheader.ras_maplength/3, fp);
		fread (g, sizeof(unsigned char), sunheader.ras_maplength/3, fp);
		fread (b, sizeof(unsigned char), sunheader.ras_maplength/3, fp);
	}
	else if (sunheader.ras_maptype == RMT_RAW && csize) 
	{
		/* we don't know how to handle raw colormap, ignore */
		fskip(fp, csize);
	}
	else
	{
		/* no colormap, make one up */
		if (sunheader.ras_depth == 1) 
		{
			r[0] = g[0] = b[0] = 0;
			r[1] = g[1] = b[1] = 255;
		}
		else if (sunheader.ras_depth == 8) 
		{
			for (i = 0; i < 256; i++)
				r[i] = g[i]  = b[i] = i;
		}
	}
	
	/*
	CTSliceXSize(slice) = w;
	CTSliceYSize(slice) = h;
	*/
	
	if (x1==-1) 
	{
		slice->x1=slice->y1=x1=y1=0;
		slice->x2=x2=w-1;
		slice->y2=y2=h-1;
		slice->cdata = (unsigned char *)malloc(sizeof(unsigned char)*(x2-x1+1)*
			(y2-y1+1));
		memset(slice->cdata, '\0', sizeof(char)*(x2-x1+1)*(y2-y1+1));
		CTSliceWidth(slice) = w;
		CTSliceHeight(slice) = h;
	}
	
	/* allocate memory for picture and read it in */
	/* note we may slightly overallocate here (if image is padded) */
	line = (unsigned char *) malloc (linesize);
	if (line == NULL) 
	{
		fprintf(stderr, "Can't allocate memory for image\n");
		exit(1);
	}
	
	for (i = 0; i < h; i++) 
	{
		if (sunheader.ras_type == RT_BYTE_ENCODED) 
		{
			if (rle_read (line, 1, linesize, fp, (i==0)) != linesize) break;
		}
		else 
		{
			if (fread (line, 1, linesize, fp) != (unsigned int)linesize)
				return (SunRasError ("file read error"));
		}
		
		if (slice->y1 <= i && i <= slice->y2) 
		{
			for (j=slice->x1; j<=slice->x2; j++)
				CTSliceCharData(slice, i, j) = line[j];
		}
		/*
		switch (d) {
		case 1:  SunRas1to8 (image + w * i, line, w);       break;
		case 8:  memcpy (image + w * i, line, w);           break;
		case 24: memcpy (image + w * i * 3, line, w * 3); break;
		}
		*/
	}
	
#ifdef DEBUG
	fprintf(stderr,"Sun ras: image loaded!\n");
#endif
	
	/*
	if (d == 24) {
	if (sunheader.ras_type != RT_FORMAT_RGB) fixBGR(image,w,h);
	rv = Conv24to8 (image, w, h, nc);
	free (image);
	return (rv);
	}
	else {
	pic = image;
	pWIDE = w;
	pHIGH = h;
	return (0);
	}
	*/
	CTSliceCompMinMaxD(slice);
	return(0);
}
Beispiel #7
0
/*-------------------------------------------------------------------
* CTSliceSetVals - set a block of values in a CT image
*-------------------------------------------------------------------
*/
void CTSliceSetVals(CTSlice slice, int x1, int y1, int x2, int y2,
                    int val, int z)
{
	int x, y;
	
	if (x1 > x2) 
	{
		x = x1;
		x1 = x2;
		x2 = x;
	}
	
	if (y1 > y2) 
	{
		y = y1;
		y1 = y2;
		y2 = y;
	}
	
	x1 = MAX(x1, slice->x1);
	y1 = MAX(y1, slice->y1);
	x2 = MIN(x2, slice->x2);
	y2 = MIN(y2, slice->y2);
	
	if (z) 
	{
		if (x1 <= x2) 
		{
			/* set the first line */
			if (CTSliceShorts(slice)) 
			{
				for (y=y1; y<=y2; y++)
					CTSliceShortData(slice, x1, y) = val;
				for (x1++; x1<=x2; x1++)
					memcpy(&CTSliceShortData(slice, x1, y1),&CTSliceShortData(slice, x1-1, y1),
						sizeof(short)*(y2-y1+1));
			}
			else 
			{
				for (y=y1; y<=y2; y++)
					CTSliceCharData(slice, x1, y) = val;
				for (x1++; x1<=x2; x1++)
					memcpy(&CTSliceCharData(slice, x1, y1),&CTSliceCharData(slice, x1-1, y1),
						sizeof(char)*(y2-y1+1));
			}
		}
	}
	else 
	{
		if (CTSliceShorts(slice)) 
		{
			for (x=x1; x<=x2; x++)
			{
				for (y=y1; y<=y2; y++)
					if (CTSliceShortData(slice, x, y) > 1000)
						CTSliceShortData(slice, x, y) = val;
					else
					CTSliceShortData(slice, x, y) = 0;
			}
		}
		else 
		{
			for (x=x1; x<=x2; x++)
			{
				for (y=y1; y<=y2; y++)
					if (CTSliceCharData(slice, x, y) > 1000)
						CTSliceCharData(slice, x, y) = val;
					else
						CTSliceCharData(slice, x, y) = 0;
			}
		}
	}
}