00001 
00002 #ifndef  __JBXL_CPP_THINNING_H_
00003 #define  __JBXL_CPP_THINNING_H_
00004 
00005 
00015 #include "Gmt.h"
00016 #include "tlist.h"
00017 
00018 
00019 
00020 namespace jbxl {
00021 
00022 
00023 template <typename T>  MSGraph<T>  CenterLine(MSGraph<T> gx, int mode);
00024 template <typename T>  int  nonZeroBoxel(MSGraph<T> vp, int n); 
00025 template <typename T>  bool deletable(MSGraph<T> vp, int n, int c, int d);
00026     
00027 int     connectNumber(int* w, int c, int d);
00028 bool    deletable_s(int* v);
00029 bool    deletable_4(int* v);
00030 bool    deletable_5(int* v);
00031 
00032 
00045 template <typename T>  MSGraph<T>  centerLine(MSGraph<T> gx, int mode)
00046 {
00047     int   i, j, k, l, m, n, w, b, nn, mm; 
00048     int   rr, dd, xs, ps;
00049     
00050     bool  dt;
00051 
00052     MSGraph<int>   gd;
00053     MSGraph<T>   vp;
00054     tList *pp, *px;
00055     tList_data ld;
00056 
00057     if (mode!=26)  mode = 6;
00058     xs = gx.xs;
00059     ps = gx.xs*gx.ys;
00060     ld = init_tList_data();
00061 
00062     
00063     
00064     gd = euclidDistance(gx, gd.zero+1, rr);
00065 
00066     dd = SINTMAX;
00067     rr = 0;
00068     for (i=0; i<gd.xs*gd.ys*gd.zs; i++) {
00069         if (gd.gp[i]!=0) {
00070             gd.gp[i] += 20;
00071             dd = Min(dd, gd.gp[i]);
00072             rr = Max(rr, gd.gp[i]);
00073         }
00074     }
00075 
00076     
00077     
00078     pp = px = new_tList_node();
00079 
00080     for (k=1; k<gd.zs-1; k++) {
00081         l = k*ps;
00082         for (j=1; j<gd.ys-1; j++) {
00083             m = l + j*xs;
00084             for (i=1; i<gd.xs-1; i++) {
00085                 n = m + i;
00086                 if (gd.gp[n]>20) {
00087                     w = gd.gp[n+1]*gd.gp[n-1]*gd.gp[n+xs]*gd.gp[n-xs]   
00088                                     *gd.gp[n+ps]*gd.gp[n-ps];
00089                     if(w==0) {
00090                         ld.id = n;
00091                         ld.lv = (int)gd.gp[n];
00092                         px = add_tList_node_bydata(px, ld);
00093                         gd.gp[n] = 1;
00094                     }
00095                 }
00096             }
00097         }
00098     }
00099 
00100     
00101     do {
00102         
00103         
00104         px = pp->next;
00105         while(px!=NULL) {
00106             if (px->ldat.lv<=dd) {
00107                 dt = deletable(gd, px->ldat.id, mode, 3);
00108                 if (dt) {
00109                     m = nonZeroBoxel(gd, px->ldat.id);
00110                     if (m==1) {
00111                         tList* pv = px->prev;
00112                         del_tList_node(&px);
00113                         px = pv;
00114                     }
00115                     else px->ldat.lv = m/3 + 7;
00116                 }
00117                 else {
00118                     px->ldat.lv = 16;
00119                 }
00120             }
00121             px = px->next;
00122         } 
00123 
00124         
00125         
00126         for (b=7; b<=15; b++) {
00127             px = pp->next;
00128             while(px!=NULL) {
00129                 if (px->ldat.lv==b) {
00130                     dt = deletable(gd, px->ldat.id, mode, 3);
00131                     if (dt) {
00132                         m = nonZeroBoxel(gd, px->ldat.id);
00133                         if (m==1) {
00134                             tList* pv = px->prev;
00135                             del_tList_node(&px);
00136                             px = pv;
00137                         }
00138                         else  {
00139                             i = px->ldat.id;
00140                             gd.gp[i] = 0;
00141 
00142                             tList* pv = px->prev;
00143                             del_tList_node(&px);
00144                             px = pv;
00145 
00146                             if (gd.gp[i+1]>20) {
00147                                 ld.id = i+1;
00148                                 ld.lv = (int)gd.gp[ld.id];
00149                                 px = add_tList_node_bydata(px, ld);
00150                                 gd.gp[ld.id] = 1;
00151                             }
00152                             if (gd.gp[i-1]>20) {
00153                                 ld.id = i-1;
00154                                 ld.lv = (int)gd.gp[ld.id];
00155                                 px = add_tList_node_bydata(px, ld);
00156                                 gd.gp[ld.id] = 1;
00157                             }
00158                             if (gd.gp[i+xs]>20) {
00159                                 ld.id = i+xs;
00160                                 ld.lv = (int)gd.gp[ld.id];
00161                                 px = add_tList_node_bydata(px, ld);
00162                                 gd.gp[ld.id] = 1;
00163                             }
00164                             if (gd.gp[i-xs]>20) {
00165                                 ld.id = i-xs;
00166                                 ld.lv = (int)gd.gp[ld.id];
00167                                 px = add_tList_node_bydata(px, ld);
00168                                 gd.gp[ld.id] = 1;
00169                             }
00170                             if (gd.gp[i+ps]>20) {
00171                                 ld.id = i+ps;
00172                                 ld.lv = (int)gd.gp[ld.id];
00173                                 px = add_tList_node_bydata(px, ld);
00174                                 gd.gp[ld.id] = 1;
00175                             }
00176                             if (gd.gp[i-ps]>20) {
00177                                 ld.id = i-ps;
00178                                 ld.lv = (int)gd.gp[ld.id];
00179                                 px = add_tList_node_bydata(px, ld);
00180                                 gd.gp[ld.id] = 1;
00181                             }
00182                         }
00183                     }
00184                     else {
00185                         px->ldat.lv = 16;
00186                     }
00187                 }
00188                 px = px->next;
00189             }
00190         } 
00191 
00192         
00193         
00194         dd = rr;
00195         px = pp->next;
00196         while(px!=NULL) {
00197             if (px->ldat.lv>20) {
00198                 dd = Min(dd, px->ldat.lv);
00199             }
00200             px = px->next;
00201         }
00202         mm = nn = 0;
00203         px = pp->next;
00204         while(px!=NULL) {
00205             nn++;
00206             if (px->ldat.lv==16) mm++;
00207             px = px->next;
00208         }
00209 
00210     } while (dd<rr || mm!=nn);
00211 
00212     vp.setup(gd.xs, gd.ys, gd.zs);
00213     for (i=0; i<gd.xs*gd.ys*gd.zs; i++) vp.gp[i] = (T)gd.gp[i];
00214     gd.free();
00215 
00216     return  vp;
00217 }
00218 
00219 
00220 template <typename T>  int  nonZeroBoxel(MSGraph<T> vp, int n) 
00221 {
00222     int  m, xs, ps;
00223 
00224     ps = vp.xs*vp.ys;
00225     xs = vp.xs;
00226 
00227     m = 0;
00228     if (vp.gp[n+1]      !=0) m++;
00229     if (vp.gp[n-1]      !=0) m++;
00230     if (vp.gp[n+xs]     !=0) m++;
00231     if (vp.gp[n-xs]     !=0) m++;
00232     if (vp.gp[n+ps]     !=0) m++;
00233     if (vp.gp[n-ps]     !=0) m++;
00234     if (vp.gp[n+1+xs]   !=0) m++;
00235     if (vp.gp[n+1-xs]   !=0) m++;
00236     if (vp.gp[n-1+xs]   !=0) m++;
00237     if (vp.gp[n-1-xs]   !=0) m++;
00238     if (vp.gp[n+1+ps]   !=0) m++;
00239     if (vp.gp[n+1-ps]   !=0) m++;
00240     if (vp.gp[n-1+ps]   !=0) m++;
00241     if (vp.gp[n-1-ps]   !=0) m++;
00242     if (vp.gp[n+xs+ps]  !=0) m++;
00243     if (vp.gp[n+xs-ps]  !=0) m++;
00244     if (vp.gp[n-xs+ps]  !=0) m++;
00245     if (vp.gp[n-xs-ps]  !=0) m++;
00246     if (vp.gp[n+1+xs+ps]!=0) m++;
00247     if (vp.gp[n+1+xs-ps]!=0) m++;
00248     if (vp.gp[n+1-xs+ps]!=0) m++;
00249     if (vp.gp[n+1-xs-ps]!=0) m++;
00250     if (vp.gp[n-1+xs+ps]!=0) m++;
00251     if (vp.gp[n-1+xs-ps]!=0) m++;
00252     if (vp.gp[n-1-xs+ps]!=0) m++;
00253     if (vp.gp[n-1-xs-ps]!=0) m++;
00254 
00255     return m;
00256 }
00257 
00258 
00272 template <typename T>  bool deletable(MSGraph<T> vp, int n, int c, int d)
00273 {
00274     int  i, j, k, l, m, lz, ly, mz, my;
00275     int  cn, mm, nh;
00276     int  v[27];
00277     bool ret;
00278 
00279     if (d<3) {                          
00280         mm = 9;
00281         for (j=-1; j<=1; j++) {
00282             ly = (j+1)*3;
00283             my = n + j*vp.xs;
00284             for (i=-1; i<=1; i++) {
00285                 l = ly + (i+1);
00286                 m = my + i;
00287                 if (vp.gp[m]!=0) v[l] = 1;
00288                 else             v[l] = 0;
00289             }
00290         }
00291         DEBUG_MODE PRINT_MESG("DELETABLE: 2D mode is not supported.\n");
00292         return false;
00293     }
00294     else {                              
00295         mm = 27;
00296         for (k=-1; k<=1; k++) {
00297             lz = (k+1)*9;
00298             mz = n + k*vp.xs*vp.ys;
00299             for (j=-1; j<=1; j++) {
00300                 ly = lz + (j+1)*3;
00301                 my = mz + j*vp.xs;
00302                 for (i=-1; i<=1; i++) {
00303                     l = ly + (i+1);
00304                     m = my + i;
00305                     if (vp.gp[m]>0) v[l] = 1;
00306                     else            v[l] = 0;
00307                 }
00308             }
00309         }
00310     }
00311 
00312     cn = connectNumber(v, c, d);
00313     if (cn==-1 || cn!=1) return false;
00314 
00315     if (c==26 || c==8) {
00316         v[c/2] = 1 - v[c/2];
00317         for(i=0; i<mm; i++) v[i] = 1 - v[i];
00318     }
00319 
00320     nh = v[10] + v[12] + v[14] + v[16] + v[4] + v[22];
00321     if    (nh<=3) ret = true;
00322     else if (nh==4) ret = deletable_s(v);
00323     else if (nh==5) ret = deletable_4(v);
00324     else if (nh==6) ret = deletable_5(v);
00325 
00326     return  ret;
00327 }
00328 
00329 
00330 
00331 }       
00332 
00333 
00334 #endif
00335