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