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

📄 ccfeatures.c

📁 Computing 2D Skeleton
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Program:  extracts features                 */ /*/* Assumes that image is piecewise constant                 *//* Assumes that the image boundary is at least (N-1)/2 pixels   away from the frame boundary                             *//*                                                          *//*                                                          *//* Inputs:  the image and the ABSOLUTE distance function    *//*                                                          *//*                                                          *//* Date:     June, 2003                                    *//*                                                          *//*                                                          */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <fcntl.h>#include <unistd.h>#include <sioux.h>#include <MacTypes.h>#include <Fonts.h>#include <math.h>/* imagesizes:   ccSchzSchz:  376H x 796W; sample count: 12+23=35   ccSchzNorms: 364H x 784W; sample count: 21+27=48   ccNorms: 324H x 780W; sample count: 10+10=20    ccKids : 400H x 896W; sample count: 15+15=30   ccDrugs: 324H x 708W; sample count: 7+7=14 */   /* ccSchzSchz *//*#define caseno 1 #define grp_1_count 12#define grp_2_count 23#define sample_count 35 #define ydim 376  #define xdim 796*/ /* ccSchzNorms *//*#define caseno 2#define grp_1_count 21#define grp_2_count 27#define sample_count 48 #define ydim 364  #define xdim 784 *//* ccNorms *//*#define caseno 3#define grp_1_count 10#define grp_2_count 10#define sample_count 20 #define ydim 324  #define xdim 780*//* ccKids *//*#define caseno 4#define grp_1_count 15#define grp_2_count 15#define sample_count 30 #define ydim 400  #define xdim 896 */ /* ccDrugs */#define caseno 5#define grp_1_count 7#define grp_2_count 7#define sample_count 14 #define ydim 324  #define xdim 708#define num_axis_samples 72#define num_spl_samples 6  /* splenium */#define num_hk_samples 34 /* genu hook */#define upper_threshold 70#define middle_threshold 45#define lower_threshold 10/* (1) upper threshold = degree angle between 0 and 90                   = minimum angle that a chord must make                     with the tangent to shape bdry (2) middle threshold is used to create points bridging gaps in the skeleton obtained by thresholding at upper_threshold. If middle threshold is too high, it will miss some of the gaps. If it is too low,then it finds too many points going beyond the gap  (3) lower_threshold is used to constuct fairly full skeleton  which is then used to find the endpts of the branches of the skeleon obtained after bridging short gaps created by thresholding. */#define beta 2.01#define L 20/* beta is the cost of each connected component of sk1 *//* eliminates branches with number of pixels<=L if their costis beyond the threshold */ #define N 15 /* max size for local nbhd in ridge_gr()   *//* N must be odd */#define NN 40 /* size of local nbhd for finding ctrs  */#define MAX(A,B) ((A)>(B) ? (A) : (B))#define MIN(A,B) ((A)>(B) ? (B) : (A))#define ABS(A) ((A)>=0 ? (A) : -(A))/* file names */FILE *infile,*outfile;char buf[64],buf1[64],buf2[64],inname[128];char d_name[128],outname[128];char dir_name[128];/* Program variables */unsigned char pic[ydim][xdim];unsigned char outpic[ydim][xdim];unsigned char outgr[ydim][xdim];unsigned char sk[ydim][xdim];unsigned char ctrs[ydim][xdim];unsigned char axis[ydim][xdim];unsigned char nbhd_size[ydim][xdim];unsigned char bdry[ydim][xdim];unsigned char endpts[ydim][xdim];unsigned char tmp[ydim][xdim];int mark[2][ydim][xdim],branchcnt[2];int Iarray[2][xdim*ydim],Jarray[2][xdim*ydim],arr_len[2];int length[2][xdim*ydim];float v[ydim][xdim];float gr[ydim][xdim],grd[ydim][xdim]; /*deriv.of v along skeleton*/float tol[(N-1)/2],tol_d[(N-1)/2]; /* margin of error in angles */float cost[2][xdim*ydim];float axis_distance[1000],spl_distance[100],hk_distance[250];int Iarr[100],Jarr[100];int sample_index;int num_axis_pts; /* for calculating  arc_distances along the axis */int num_spl_pts;int num_hk_pts;float axis_length[sample_count];float axis_rho[sample_count][num_axis_samples];float spl_rho[sample_count][num_spl_samples];float hk_rho[sample_count][num_hk_samples];float rel_rbn[sample_count],rel_gn[sample_count],rel_spl[sample_count];int Ictr_spl,Jctr_spl,Ictr_gn,Jctr_gn;int gn_i,gn_j; /* on the bdry of the disk in the genu */int spl_i,spl_j; /* on the bdry  of the disk in the splenium */int hk_i0, hk_j0; /* beginning of the axis of the genu hook  */ int hk_i,hk_j; /* the end of genu hook  */int initial_i,initial_j,final_i,final_j;  int ibb,inn,jbb,jnn;int debug_flag;void local_grad();void convert_gr();void ridge_gr();void construct_sk();void initialize_sk();void ave_cost(int,int);void confirm_endpts();void fill_gaps();void complete_sk();void prune();void calc_features();void find_axis();void clean_up();void extend_axis_spl();void extend_axis_gn();void calc_distance();void sample_rho();void calc_CCareas();void output_pics();void output_features();void run();       void local_grad()   /*     CALCULATES grad USING 4 DIFFERENT WAYS:     given coordinates and then rotating it by angle    whose tangent equals 0.5,1 and 2   */       {      int i,j,k,i1,j1,i2,j2,i3,j3;      int count,flag;      double x,y,q,q1;             for (i=0;i<ydim;i++) for (j=0;j<xdim;j++)      {        if (bdry[i][j]>0) gr[i][j]=1;        else if (i*j*(ydim-1-i)*(xdim-1-j)==0) gr[i][j]=1; /*frame bdry*/        else        {         ibb = i-1; inn = i+1; jbb = j-1; jnn = j+1;         flag=0;         k = pic[i][j];         i1=i;j1=jbb;         i2=ibb;j2=jbb;         i3=ibb;j3=j;         count=bdry[i1][j1]+bdry[i2][j2]+bdry[i3][j3];         if (count==3)         {           if (pic[i2][j2]==k) gr[i][j]=0.707107;           else gr[i][j]=1;           flag = 1;         }                  if (flag==0)         {           i1=i3;j1=j3;           i2=ibb;j2=jnn;           i3=i;j3=jnn;           count=bdry[i1][j1]+bdry[i2][j2]+bdry[i3][j3];           if (count==3)           {             if (pic[i2][j2]==k) gr[i][j]=0.707107;             else gr[i][j]=1;             flag = 1;           }         }                  if (flag==0)         {           i1=i3;j1=j3;           i2=inn;j2=jnn;           i3=inn;j3=j;           count=bdry[i1][j1]+bdry[i2][j2]+bdry[i3][j3];           if (count==3)           {             if (pic[i2][j2]==k) gr[i][j]=0.707107;             else gr[i][j]=1;             flag = 1;           }         }                  if (flag==0)         {           i1=i3;j1=j3;           i2=inn;j2=jbb;           i3=i;j3=jbb;           count=bdry[i1][j1]+bdry[i2][j2]+bdry[i3][j3];           if (count==3)           {             if (pic[i2][j2]==k) gr[i][j]=0.707107;             else gr[i][j]=1;             flag = 1;           }         }                          if (flag==0)         {           x = v[i][jnn]-v[i][jbb];           y = v[inn][j]-v[ibb][j];                    q = (x*x+y*y)/4;                   x = v[inn][jnn]-v[ibb][jbb];           y = v[inn][jbb]-v[ibb][jnn];           q1 = (x*x+y*y)/8;           if (q1<q) q = q1;                     x = (v[inn][jbb]+v[inn][j]-v[ibb][j]-v[ibb][jnn])/2;           y = (v[inn][jnn]+v[i][jnn]-v[i][jbb]-v[ibb][jbb])/2;           q1 = (x*x+y*y)/5;           if (q1<q) q = q1;                     x = (v[inn][jbb]+v[i][jbb]-v[i][jnn]-v[ibb][jnn])/2;           y = (v[inn][jnn]+v[inn][j]-v[ibb][j]-v[ibb][jbb])/2;           q1 = (x*x+y*y)/5;           if (q1<q) q = q1;                     if (q>1) q = 1;            if (q>0) gr[i][j] = sqrt(q);           else gr[i][j] = 0;         }         gr[i][j] = MIN(gr[i][j],1);        }      }   }               void ridge_gr() /* traveses the boundary pixels of NxN nbhds */ {    int i,j,m,n,k,kk,p,q;    int k0,k1,count;    int h,hh,H;    int flag,reset_flag,bdry_flag;    int ii[4*N-4],jj[4*N-4],check[4*N-4];    float v0,z,d[4*N-4];    float slope[4*N-4],last,now,next;    float grx,grmn,accept;        local_grad(); /* makes a rough estimate of ridge_gr */                       /* tends to be more accurate near jcns */         for (i=0;i<ydim;i++) for (j=0;j<xdim;j++) nbhd_size[i][j]=1;        h = (N-1)/2;    H = 8*h;    for (p=-h;p<h+1;p++) for (q=-h;q<h+1;q++)    if ((p+h)*(p-h)*(q+h)*(q-h)==0)    {      k = p+q+2*h;      if (p-q>0) k = H-k;      z = p*p+q*q;      d[k] = sqrt((double) z); /* distance from the origin */      ii[k] = p; jj[k] = q;     }            /* begin scanning */    for (i=h;i<ydim-h;i++) for (j=h;j<xdim-h;j++)    if (bdry[i][j]==0)  if (gr[i][j]<0.99)     {               /* adjust the nbhd size to avoid bdry */     reset_flag = 0;     do     {/* printf("h=%d\n",h);*/       bdry_flag = 0;       hh = h+1;       for (m=i-hh;m<i+hh+1;m++) for (n=j-hh;n<j+hh+1;n++)          if (bdry[m][n]>0) bdry_flag = 1;   /*  if (bdry[m][n]>0){printf("bdry pt at (%d %d), v=%f\n",m,n,v[m][n]);flag=1;} */       if (bdry_flag>0) {h--, reset_flag=1;}     }     while ((bdry_flag>0)&&(h>1));                    if (bdry_flag==0)      {        nbhd_size[i][j] = h;       if (reset_flag>0) /* recalculate nbhd geometry */       {         H = 8*h;         for (p=-h;p<h+1;p++) for (q=-h;q<h+1;q++)         if ((p+h)*(p-h)*(q+h)*(q-h)==0)         {           k = p+q+2*h;           if (p-q>0) k = H-k;           z = p*p+q*q;           d[k] = sqrt((double) z); /* distance from the origin */           ii[k] = p; jj[k] = q;          }       }              /* calculate directional gradients */      /* direction points from the  perimeter to the center (i,j) */        v0 = v[i][j];       for (m=i-h;m<i+h+1;m++) for (n=j-h;n<j+h+1;n++)       if ((m-i+h)*(m-i-h)*(n-j+h)*(n-j-h)==0)       /* scans only the perimeter of the nbhd */       {          p = m-i; q = n-j;          k = p+q+2*h;          if (p-q>0) k = H-k;          slope[k] = (v0-v[m][n])/d[k];       }              /* find local maxima of slopes around the nbhd perimeter */       for (k=0;k<H;k++) check[k]=0;       last = slope[H-1];       now = slope[0];       z = -2; /* z tracks value of global max */       for (k=0;k<H;k++)       {         next = slope[(k+1)%H];         if (now-last>0) if (now-next>0) /* local max */         {           check[k] = 1; /* mark the direction */           if (now>z) {z = now; kk = k;} /* current global max */         }         last = now; now = next;       } /*  if (i==442) if (j==369)  *//* if (i>286) if (i<289) if (j==103) *//* {  printf("\nat (%d %d), nbhd: %d\n",i,j,h);   for (k=0;k<H;k++) if (check[k]>0)printf("k:%d (%d %d),gr:%f,chk:%d\n",k,ii[k],jj[k],slope[k],check[k]);  }*/      /* calculate cosine of angles between successive maximal rays */        accept=(h-1)/sqrt((double) h*h+0.25); /* Maximal rays should have slope of 1; but due to inaccuarcy in slopes, arising because the maximal rays may be off the grid line contributing error factor of h/sqrt(h*h+.5*.5) and because the point (i,j) may be off the ridge contributing the factor (h-1)/h, accept if the slope > (h-1)/sqrt((double) h*h+0.25) */       count = 0; /* number of maximal rays */       grmn = 1;       /* grmn tracks minimum value; */             if (z>accept) /* first ray to shape bdry */       {        k0 = kk;        for (k=kk;k<kk+H;k++)        if ((k%H)==k0)        {          k0 = k%H;  /* current ray */          flag = 0;          /* find next ray to shape bdry */          for (q=1;q<H;q++)           {            if (check[(k+q)%H]>0) /* is local max */            if (slope[(k+q)%H]>accept)             {              flag = 1;              count++;              k1 = (k+q)%H; /* next ray */              break;            }            }                  if (flag>0) /* calc ridge gradient */          {            grx = (ii[k0]*ii[k1]+jj[k0]*jj[k1])/(d[k0]*d[k1]);            grx = ABS(1+grx)/2;            if (grx>0.0001) grx = sqrt((double) grx);            if (grx<grmn)  grmn=grx;            /* if (i==442) if (j==369)printf("(%d %d) k0 %d k1 %d, kk %d gr %f %f\n",i,j,k0,k1,count,grx,gr[i][j]); */            k0 = k1; /* new current ray */                               } /* else k0 remains unchanged */        }       }       if (count>=2) if (grmn<gr[i][j]) gr[i][j]=grmn;       /* if count<2; the point (i,j) is not on the ridge */      }     if (reset_flag>0)     {       h = (N-1)/2;       H = 8*h;       for (p=-h;p<h+1;p++) for (q=-h;q<h+1;q++)       if ((p+h)*(p-h)*(q+h)*(q-h)==0)       {         k = p+q+2*h;         if (p-q>0) k = H-k;         z = p*p+q*q;         d[k] = sqrt((double) z); /* distance from the origin */         ii[k] = p; jj[k] = q;       }     }   }     convert_gr();/*  p=364; q=294;  for (i=p-1;i<p+2;i++) for (j=q-1;j<q+2;j++)printf("grd(%d %d)=%f\n",i,j,grd[i][j]);  */   }   void convert_gr() /* converts gr to angle in degrees */ /* removes skeleton points too near the bdry and bear small angles */ {   int i,j,h;   float x;      h = (N-1)/2;   for (j=2;j<=h;j++)

⌨️ 快捷键说明

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