⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 angpp.c

📁 3DMEDLIB - 三维医学图像开发源程序库及范例
💻 C
字号:
/********************  angpp.c  ******************************

   Three dimensional surface reconstruction program

   This program assumes that the views from the main axis
   directions were done thus an angle view between two main
   axis views can be created from the depth_code viewa(floating
   point). 

 Daniel Geist
 Michael W. Vannier

 Mallinckrodt Institute of Radiology
 Washington University School of Medicine
 510 S. Kingshighway Blvd.
 St. Louis, Mo. 63110

 Note:  This program is intended for the private non-commercial
 use of interested individuals to provide a fuller explanation of
 the algorithms described in "Three dimensional reconstruction in
 Medical Imaging" by D. Geist and M. Vannier.

 1988
 *************************************************************/

#include <stdio.h>
#include <math.h>
#define FLOAT_LINE 1024
#define PI 3.141592653

/* the structure below is the data for a point on the surface projected
   on the view plane                        */
typedef struct DIS_REC {
    float dist;            /*distance from view plane */
    int indXY;             /* index of data on main axis view */
    char XY;               /* Which main axis view obtained from (X or Y)*/
};

struct DIS_REC distances[256]; /* one projected line */

int NLINES,IXmax,IYmax,xinc,yinc;
int (*xdir)(),(*ydir)();
float THETA,cosTheta,sinTheta,tgnTheta;
float fxbuf[3][256],fybuf[3][256];/* input buffers */

/*  output files  */
char fng[13],fnd[13],xfile[13],yfile[13],DR;

succ(i)
int i;
{
    return(i==2?0:i+1);
}

prev(i)
int i;
{
    return(i==0?2:i-1);
}

forward(i)
int i;
{ 
    return(i); 
}

backward(i,start)
int i;
{
    return(start-i); 
}

/* PUTD - fill a DIS_REC with values */
putd(pdis,D,i,xy_sym)
struct DIS_REC *pdis;
float D;
int i,xy_sym;

{ 
    pdis->dist=D;
    pdis->indXY=i;
    pdis->XY=xy_sym;
}

/* take one line from X and Y views and create a projrcted line */
getdistances(linex,liney)
float linex[],liney[];

{ 
    int i,IND,X,Y;
    float D;
    for(i=0;i<256;i++) distances[i].XY=0;
    /* project Y-data onto image line */
    for(i=0;i<256;i++) if(liney[i]!=256.0){
        X=(*ydir)(i,255);
        IND=IXmax -(X*sinTheta-liney[i]*cosTheta)+0.5;
        D=liney[i]/sinTheta+(X-liney[i]/tgnTheta)*cosTheta;
        if((IND>=0) && (IND<256)){
            if(distances[IND].XY==0)putd(&distances[IND],D,i,1);
            else if(distances[IND].dist>D)putd(&distances[IND],D,i,1);
        }
    }

    /*project X-data onto image plane */
    for(i=0;i<256;i++) if(linex[i]!=256.0){
        Y=(*xdir)(i,255);
        IND=IXmax-(linex[i]*sinTheta-Y*cosTheta)+0.5;
        D=Y/sinTheta+(linex[i]-Y/tgnTheta)*cosTheta;
        if((IND>=0) && (IND<256)){
            if(distances[IND].XY==0)putd(&distances[IND],D,i,2);
            else if(distances[IND].dist>D)putd(&distances[IND],D,i,2);
        }
    }

    /* fill holes due to low resolution */
    for(i=1;i<255;i++)if( (distances[i].XY==0) && (distances[i+1].XY!=0) &&
        (distances[i-1].XY!=0))
        putd(&distances[i],distances[i-1].dist,
        distances[i-1].indXY,(int)distances[i-1].XY);
}

/* returns gradient shade in point given the variations of the surface */
unsigned char grad(x1,x2,y1,y2,z1,z2,x_fac,y_fac,z_fac)
float x1,x2,y1,y2,z1,z2;
int x_fac,y_fac,z_fac;
{
    float gx,gy,gz,G,nx,ny;
    unsigned char gxint;
    /* components of gradient */
    gx=(x2-x1)/x_fac;
    gy=(y2-y1)/y_fac;
    gz=(z1-z2)/z_fac;
    G=sqrt(gx*gx+gy*gy+gz*gz);
    /*compute nx,ny normalized x,y component of gradient */
    nx=gx/G;
    ny=gy/G;
    gxint=255*(nx*cosTheta+ny*sinTheta)+0.5; /*scale gradient shade by 256 */
    return(gxint);
}

doline(linex,linex1,linex2,liney,liney1,liney2,z_fac,fg,fd)
float linex[],linex1[],linex2[],liney[],liney1[],liney2[];
int z_fac;
FILE *fg,*fd;

{ 
    int i;
    unsigned char lined[256],lineg[256];
    /* empty bit on image line */
    for(i=0;i<256;i++)if(distances[i].XY==0)lineg[i]=lined[i]=0;
    else{
        lined[i]=(distances[i].dist<256)?255-distances[i].dist+0.5:0;
        /* bit on image line projected from Y view */
        if(distances[i].XY==1) switch(distances[i].indXY){
        case 0:
            lineg[i]=
                grad(liney[1]*yinc,liney[0]*yinc,(float)0,(float)2,
            liney1[0],liney2[0],1,2,z_fac);
            break;
        case 255:
            lineg[i]=
                grad(liney[255]*yinc,liney[254]*yinc,(float)0,(float)2,
            liney1[255],liney2[255],1,2,z_fac);
            break;
        default:
            lineg[i]=
                grad(liney[distances[i].indXY+yinc],
            liney[distances[i].indXY-yinc],(float)0,(float)2,
            liney1[distances[i].indXY],
            liney2[distances[i].indXY],2,2,z_fac); 
            break;
        }
        /* bit on image line projected from X view */
        else switch(distances[i].indXY){
        case 0:
            lineg[i]=
                grad((float)0,(float)2,linex[1]*xinc,linex[0]*xinc,
            linex1[0],linex2[0],2,1,z_fac);
            break;
        case 255:
            lineg[i]=
                grad((float)0,(float)2,linex[255]*xinc,linex[254]*xinc,
            linex1[255],linex2[255],2,1,z_fac);
            break;
        default:
            lineg[i]=
                grad((float)0,(float)2,linex[distances[i].indXY+xinc],
            linex[distances[i].indXY-xinc],
            linex1[distances[i].indXY],
            linex2[distances[i].indXY],2,2,z_fac);
            break;
        }
    }

    fwrite(lineg,1,256,fg);
    fwrite(lined,1,256,fd);
}

doviews()
{
    FILE *fg,*fd,*fx,*fy;
    int z,i,j,k,mid;
    mid=1;
    fd=fopen(fnd,"wb");
    fg=fopen(fng,"wb");
    fx=fopen(xfile,"rb");
    fy=fopen(yfile,"rb");

    /*read first three lines */
    for(i=0;i<3;i++){
        fseek(fx,(long)FLOAT_LINE*(*ydir)(i,NLINES-1),SEEK_SET);
        fread(fxbuf[i],1,FLOAT_LINE,fx);
        fseek(fy,(long)FLOAT_LINE*(*xdir)(i,NLINES-1),SEEK_SET);
        fread(fybuf[i],1,FLOAT_LINE,fy);
    }

    /* do first line (forward differene)*/
    getdistances(fxbuf[0],fybuf[0]);
    doline(fxbuf[0],fxbuf[0],fxbuf[1],fybuf[0],fybuf[0],fybuf[1],1,fg,fd);

    /* do middle lines (central diffrence) */
    printf("Begining computation of  views\n");
    for(z=0;z<(NLINES-2);z++){      /*for each slice */
        getdistances(fxbuf[mid],fybuf[mid]);
        doline(fxbuf[mid],fxbuf[prev(mid)],fxbuf[succ(mid)],
        fybuf[mid],fybuf[prev(mid)],fybuf[succ(mid)],2,fg,fd);
        fseek(fx,(long)FLOAT_LINE*(*ydir)(i,NLINES-1),SEEK_SET);
        fseek(fy,(long)FLOAT_LINE*(*xdir)(i,NLINES-1),SEEK_SET);
        i++;
        fread(fxbuf[prev(mid)],1,FLOAT_LINE,fx);
        fread(fybuf[prev(mid)],1,FLOAT_LINE,fy);
        mid=succ(mid);
        printf(" did %d \n",z);
    }

    /* do last line (backward difference)*/
    getdistances(fxbuf[mid],fybuf[mid]);
    doline(fxbuf[mid],fxbuf[prev(mid)],fxbuf[mid],
    fybuf[mid],fybuf[prev(mid)],fybuf[mid],1,fg,fd);

    fclose(fg);
    fclose(fd);
    fclose(fx);
    fclose(fy);
}

getang(ang)
int *ang;
{ 
    scanf("%d",ang);
    sprintf(fng,"gang%d.out",*ang);
    sprintf(fnd,"dang%d.out",*ang);
    if( ( *ang > 0) && ( *ang < 90) ){
        xdir=forward;
        ydir=forward;
        sprintf(xfile,"%c:xdis1.dat",DR);
        sprintf(yfile,"%c:ydis1.dat",DR);
        xinc=1;
        yinc=1;
    }
    else if( ( *ang > 90) && ( *ang < 180) ){
        xdir=backward;
        ydir=forward;
        sprintf(xfile,"%c:ydis1.dat",DR);
        sprintf(yfile,"%c:xdis2.dat",DR);
        xinc=-1;
        yinc=1;
        *ang-=90;
    }
    else if( ( *ang > 180) && ( *ang < 270) ){
        xdir=backward;
        ydir=backward;
        sprintf(xfile,"%c:xdis2.dat",DR);
        sprintf(yfile,"%c:ydis2.dat",DR);
        xinc=-1;
        yinc=-1;
        *ang-=180;
    }
    else if( ( *ang > 270) && ( *ang < 360) ){
        xdir=forward;
        ydir=backward;
        sprintf(xfile,"%c:ydis2.dat",DR);
        sprintf(yfile,"%c:xdis1.dat",DR);
        xinc=1;
        yinc=-1;
        *ang-=270;
    }
    else {
        printf(" Bad angle\n");
        exit(1);
    }
}

/**********************************************************/
/**** MAIN ***** MAIN ***** MAIN ***** MAIN ***** MAIN ****/
/**********************************************************/

main()

{ 
    char filname[13];
    FILE *par;
    int ANG;

    /* first get some parameters */
    par=fopen("param.dat","rb");
    fscanf(par,"%c %d",&DR,&NLINES);
    fclose(par);
    printf("Enter angle: ");
    getang(&ANG);

    IXmax=(255*ANG)/90;
    THETA=(float)ANG*PI/180;
    sinTheta=sin(THETA);
    cosTheta=cos(THETA);
    tgnTheta=sinTheta/cosTheta;

    doviews();
    exit(0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -