Example #1
0
/*-------------------------------------------------------------------
* CTWriteCTF - write a CTF file
*-------------------------------------------------------------------
*/
static int CTWriteCTF(char *path, CTSlice slice)
{
	FILE *fp;
	unsigned short delta[512];
	int i, j, x, left, right, offsetx, offsety;
	
	if ((fp=fopen(path, "w")) == NULL)
		return(0);
	
	/* write header */
	for (i=0; i<2048; i++)
		fputc(255, fp);
	
	if (CTSliceWidth(slice) < 512)
		offsetx = (512-CTSliceWidth(slice))/2;
	else
		offsetx = 512;

	if (CTSliceHeight(slice) < 512)
		offsety = (512-CTSliceHeight(slice))/2;
	else
		offsety = 512;
	
	/* write the delta's */
	memset(delta, '\0', sizeof(short)*512);
	for (x=CTSliceMinX(slice); x<=CTSliceMaxX(slice)&&x-CTSliceMinX(slice)<512;	x++) 
	{
		for (left=CTSliceMinY(slice); left<CTSliceYSize(slice)/2; left++)
		{
			if (CTSliceData(slice, x, left) != 0)
				break;
		}
		
		for (right=CTSliceMaxY(slice); right>CTSliceYSize(slice)/2; right--)
		{
			if (CTSliceData(slice, x, right) != 0)
				break;
		}
		
		if (CTSliceYSize(slice)/2-left > right-CTSliceYSize(slice)/2)
			delta[x] = (CTSliceYSize(slice)/2-left);
		else
			delta[x] = (right-CTSliceYSize(slice)/2);
	}
	fwrite(delta, 2, 512, fp);
	
	/* write out the slice */
	for (i=0; i<offsetx/2; i++)
	{
		for (i=CTSliceMinX(slice); i<=CTSliceMaxX(slice); i++) 
		{
			for (j=CTSliceYSize(slice)/2-delta[i]; j<CTSliceYSize(slice)/2+delta[i];
			j++)
				fwrite(&CTSliceShortData(slice, i, j), sizeof(short), 1, fp);
		}
	}
	fclose(fp);
	return(1);
}
Example #2
0
/*-------------------------------------------------------------------
* CTReadCTF - read a slice from a ctf file
*-------------------------------------------------------------------
*/
static int CTReadCTF(FILE *fp, CTSlice slice, int x1, int y1, int x2, int y2)
{
	unsigned short delta[512], row[512];
	int i, del, left, right;
	long off;
	
	/*
	CTSliceXSize(slice) = 512;
	CTSliceYSize(slice) = 512;
	*/
	
	if (x1==-1) 
	{
		slice->x1=slice->y1=x1=y1=0;
		slice->x2=slice->y2=x2=y2=511;
		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) = CTSliceHeight(slice) = 512;
	}
	
	/* skip past the 2048 byte header */
	fskip(fp, 2048);
	
	/* read the number of data values for each line */
	fread(delta, 2, 512, fp);
	
	/* compute offset for rows up to y1 */
	for (off=0, i=0; i<x1; i++)
		off+=delta[i]*2*2;
	
#ifdef DEBUG
	printf("skipping %ld values\n", off);
#endif
	
	/* skip to the x1'th row of data */
	if (off != 0)
		fskip(fp, off);

	for (; x1<=x2; x1++) 
	{
		/* skip to y1'th column of data in this row */
		del=delta[x1];
		
		/* compute how much data is present */
		left = (512)/2 - del;
		right = (512)/2 + del- 1;
		
		memset(row, '\0', 512*sizeof(short));
		fread(&row[left], 2, 2*del, fp);
		memcpy(&CTSliceShortData(slice, x1, y1), &row[y1],
            sizeof(short)*(y2-y1+1));
	}
	
	CTSliceCompMinMaxD(slice);
	return(0);
}
Example #3
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);
}
Example #4
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;
}
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);
}
Example #6
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));
}
Example #7
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);
}
Example #8
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;
			}
		}
	}
}