home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 293_02 / gx.c < prev    next >
C/C++ Source or Header  |  1989-08-25  |  6KB  |  185 lines

  1. /**********************  gx.c  ******************************
  2.  
  3.  
  4.     Three Dimensional Reconstruction Of Medical
  5.     Images from Serial Slices - CT, MRI, Ultrasound
  6.  
  7.  
  8.    This program processess a set of slices images (scans) for one
  9.    patient. It outputs two sets of files containing nine predefined 
  10.    views of bony surfaces. One set contains distance values and 
  11.    the other gradient values.
  12.  
  13.    The distance values are used as 3-D spatial topographic surface
  14.    coordinate maps for geometrical analysis of the scanned object.
  15.  
  16.    The gradient values are used for rendering the surface maps on
  17.    CRT displays for subjective viewing where perception of small
  18.    surface details is important.
  19.  
  20.     Daniel Geist, B.S.
  21.     Michael W. Vannier, M.D.
  22.  
  23.     Mallinckrodt Institute of Radiology
  24.     Washington University School of Medicine
  25.     510 S. Kingshighway Blvd.
  26.     St. Louis, Mo. 63110
  27.  
  28.     This program may be copied and used freely for any
  29.     non-commercial purpose with acknowledgement of the
  30.     developers and inclusion of this notice.
  31.  
  32.    
  33. *********************************************************/
  34.  
  35. #include <stdio.h>
  36. #include <math.h>
  37. #define DZ    3.0
  38. #define DX    1.0
  39. #define DY    1.0
  40. #define PI    3.141592653
  41.  
  42. int outfile,ZMAX,FIRSTSLICE,LASTSLICE,THRESHOLD,
  43. RIGHTMID,LEFTMID,TOPINT,midslice,midline;
  44. int short buffer[3][3][256];
  45.  
  46. /*            standard 18 output files ( 9 views x 2) */
  47. char *fnamein="ctbild.000",*fgll="gll.out",*fdll="dll.out";
  48. succ(i)
  49. int i;
  50. {
  51.     return(i==2?0:i+1);
  52. }
  53. prev(i)
  54. int i;
  55. {
  56.     return(i==0?2:i-1);
  57. }
  58. setfilename(filenum)
  59. int filenum;
  60. {
  61.     fnamein[7]=filenum/100+'0';
  62.     fnamein[8]=(filenum%100)/10+'0';
  63.     fnamein[9]='0'+filenum%10;
  64. }
  65. readline(filenum,line,bufslice,bufline)
  66. int filenum,line,bufslice,bufline;
  67. {
  68.     FILE *fn;
  69.     setfilename(filenum);
  70.     fn=fopen(fnamein,"rb");
  71.     fseek(fn,(long)512*(line+1),SEEK_SET);
  72.     fread(buffer[bufslice][bufline],1,512,fn);
  73.     fclose(fn);
  74. }
  75. readsection(firstfile,bufslice,bufline,line)
  76. int firstfile,bufslice,bufline,line;
  77. {
  78.     int file;
  79.     for(file=firstfile;file<firstfile+3;file++){
  80.         readline(file,line,bufslice,bufline);
  81.         bufslice=(bufslice==2)?0:bufslice+1;
  82.     }
  83. }
  84. readblock(firstfile)
  85. int firstfile;
  86. {
  87.     int file,i;
  88.     FILE *fn;
  89.     for(file=firstfile,i=0;i<3;i++,file++){
  90.         setfilename(file);
  91.         fn=fopen(fnamein,"rb");
  92.         fseek(fn,(long)512,SEEK_SET);
  93.         fread(buffer[i],1,1536,fn);
  94.         fclose(fn);
  95.     }
  96. }
  97. /******************* VAR1X ****************************/
  98. /*place of change on x axis reference to point (positive search) */
  99. double var1x(x,y,z,zero)
  100. int x,y,z,zero;
  101. {
  102.     int i;
  103.     double delta1,delta;
  104.     i=x;
  105.     while((buffer[z][y][i]>=THRESHOLD)&&(i>0))i--;
  106.     if(buffer[z][y][i]>=THRESHOLD)return(DX*(i-x));
  107.     while((buffer[z][y][i]<THRESHOLD)&&(i<255))i++;
  108.     if(buffer[z][y][i]<THRESHOLD)return(DX*(i-x));
  109.     else {
  110.         delta1=THRESHOLD-buffer[z][y][i];
  111.         delta=buffer[z][y][i]-buffer[z][y][i-1];
  112.         return((delta1/delta+i-x)*DX);
  113.     }
  114. }
  115. /**************** GETGRADX ***************************************/
  116. /* grad=  2048*(normalized @F/@x of surface func F)              */
  117. /*****************************************************************/
  118. unsigned char getgradx(func,x,y,slice,limit)
  119. int func,x,y,slice,limit;
  120. {
  121.     double sy[2],sz[2],gx,gy,gz;
  122.     unsigned char gxint;
  123.     /* get x and y components of gradient */
  124.     sz[0]=var1x(x,y,prev(slice),limit);
  125.     sz[1]=var1x(x,y,succ(slice),limit);
  126.     gz=(sz[1]-sz[0])/(2*DZ);
  127.     sy[0]=var1x(x,prev(y),slice,limit);
  128.     sy[1]=var1x(x,succ(y),slice,limit);
  129.     gy=(sy[1]-sy[0])/(2*DY);
  130.     /*compute gx - normalized x component of gradient */
  131.     gx=1/sqrt(1+gz*gz+gy*gy);
  132.     gxint=256*gx+0.5;      /*scale gx by 256 */
  133.     return(gxint);
  134. }
  135.  
  136. /**********************************************************/
  137. /**** MAIN ***** MAIN ***** MAIN ***** MAIN ***** MAIN ****/
  138. /**********************************************************/
  139. main()
  140. {
  141.     int x,y,z,i,j,k,r;
  142.     FILE *fg,*fd;
  143.     unsigned char lined[256],lineg[256];
  144.     midslice=1;   
  145.     /* first get some parameters from user */
  146.     printf("Enter Starting scan number: ");
  147.     scanf("%d",&FIRSTSLICE);
  148.     printf("Enter ending scan number: ");
  149.     scanf("%d",&LASTSLICE);
  150.     ZMAX=LASTSLICE-FIRSTSLICE+1;
  151.     printf("Enter threshold number: ");
  152.     scanf("%d",&THRESHOLD);
  153.     THRESHOLD+=1024;
  154.     /*creat files for first pass */
  155.     fd=fopen(fdll,"wb");
  156.     fg=fopen(fgll,"wb");
  157.     printf(" opened %d %d \n",fg,fd);
  158.     /* read first 3 scans */
  159.     readblock(FIRSTSLICE);
  160.  
  161.     /* first pass on scan data (forward) */
  162.     printf("Begining computation of REAR,LEFT,REAR,and LEFT-MID views\n");
  163.     for(z=FIRSTSLICE+1;z<LASTSLICE;z++){                 /*for each slice */
  164.         for(i=0;i<256;i++){
  165.             lineg[i]=0;
  166.             lined[i]=0;
  167.         }
  168.         midline=1;
  169.         for(y=1;y<255;y++){ /*for each line*/
  170.             for(x=1;(x<255)&&(buffer[midslice][midline][x]<THRESHOLD);x++);
  171.             if(x<255){
  172.                 lineg[y]=getgradx(0,x,midline,midslice,0);
  173.                 lined[y]=255-x;
  174.             }
  175.             if(y<254) readsection(z-1,0,prev(midline),y+2);
  176.             midline=succ(midline);
  177.         }
  178.         fwrite(lineg,1,256,fg);
  179.         fwrite(lined,1,256,fd);
  180.         printf("did slice %d\n",z);
  181.         if(z<LASTSLICE-1) readblock(z);
  182.     }
  183.     fclose(fg);
  184.     fclose(fd);
  185.