JunkBox_Lib++ (for Windows) 1.10.1
Loading...
Searching...
No Matches
Thinning.h
Go to the documentation of this file.
1#ifndef __JBXL_CPP_THINNING_H_
2#define __JBXL_CPP_THINNING_H_
3
12#include "Gmt.h"
13#include "tlist.h"
14
15//
16namespace jbxl {
17
18
19template <typename T> MSGraph<T> CenterLine(MSGraph<T> gx, int mode);
20template <typename T> int nonZeroBoxel(MSGraph<T> vp, int n);
21template <typename T> bool deletable(MSGraph<T> vp, int n, int c, int d);
22
23int connectNumber(int* w, int c, int d);
24bool deletable_s(int* v);
25bool deletable_4(int* v);
26bool deletable_5(int* v);
27
28
41template <typename T> MSGraph<T> centerLine(MSGraph<T> gx, int mode)
42{
43 int i, j, k, l, m, n, w, b, nn, mm;
44 int rr, dd, xs, ps;
45
46 bool dt;
47
48 MSGraph<int> gd;
49 MSGraph<T> vp;
50 tList *pp, *px;
51 tList_data ld;
52
53 if (mode!=26) mode = 6;
54 xs = gx.xs;
55 ps = gx.xs*gx.ys;
56 ld = init_tList_data();
57
58 // STEP 1
59 //DEBUG_Warning("center_line: start step1");
60 gd = euclidDistance(gx, gd.zero+1, rr);
61
62 dd = SINTMAX;
63 rr = 0;
64 for (i=0; i<gd.xs*gd.ys*gd.zs; i++) {
65 if (gd.gp[i]!=0) {
66 gd.gp[i] += 20;
67 dd = Min(dd, gd.gp[i]);
68 rr = Max(rr, gd.gp[i]);
69 }
70 }
71
72 // STEP 2
73 //DEBUG_Warning("center_line: start step2");
74 pp = px = new_tList_node();
75
76 for (k=1; k<gd.zs-1; k++) {
77 l = k*ps;
78 for (j=1; j<gd.ys-1; j++) {
79 m = l + j*xs;
80 for (i=1; i<gd.xs-1; i++) {
81 n = m + i;
82 if (gd.gp[n]>20) {
83 w = gd.gp[n+1]*gd.gp[n-1]*gd.gp[n+xs]*gd.gp[n-xs]
84 *gd.gp[n+ps]*gd.gp[n-ps];
85 if(w==0) {
86 ld.id = n;
87 ld.lv = (int)gd.gp[n];
88 px = add_tList_node_bydata(px, ld);
89 gd.gp[n] = 1;
90 }
91 }
92 }
93 }
94 }
95
96 //DEBUG_Warning("center_line: start step3, step4 and step5");
97 do {
98 // STEP 3
99 //DEBUG_Warning("center_line: start step3");
100 px = pp->next;
101 while(px!=NULL) {
102 if (px->ldat.lv<=dd) {
103 dt = deletable(gd, px->ldat.id, mode, 3);
104 if (dt) {
105 m = nonZeroBoxel(gd, px->ldat.id);
106 if (m==1) {
107 tList* pv = px->prev;
108 del_tList_node(&px);
109 px = pv;
110 }
111 else px->ldat.lv = m/3 + 7;
112 }
113 else {
114 px->ldat.lv = 16;
115 }
116 }
117 px = px->next;
118 }
119
120 // STEP 4
121 //DEBUG_Warning("center_line: start step4");
122 for (b=7; b<=15; b++) {
123 px = pp->next;
124 while(px!=NULL) {
125 if (px->ldat.lv==b) {
126 dt = deletable(gd, px->ldat.id, mode, 3);
127 if (dt) {
128 m = nonZeroBoxel(gd, px->ldat.id);
129 if (m==1) {
130 tList* pv = px->prev;
131 del_tList_node(&px);
132 px = pv;
133 }
134 else {
135 i = px->ldat.id;
136 gd.gp[i] = 0;
137
138 tList* pv = px->prev;
139 del_tList_node(&px);
140 px = pv;
141
142 if (gd.gp[i+1]>20) {
143 ld.id = i+1;
144 ld.lv = (int)gd.gp[ld.id];
145 px = add_tList_node_bydata(px, ld);
146 gd.gp[ld.id] = 1;
147 }
148 if (gd.gp[i-1]>20) {
149 ld.id = i-1;
150 ld.lv = (int)gd.gp[ld.id];
151 px = add_tList_node_bydata(px, ld);
152 gd.gp[ld.id] = 1;
153 }
154 if (gd.gp[i+xs]>20) {
155 ld.id = i+xs;
156 ld.lv = (int)gd.gp[ld.id];
157 px = add_tList_node_bydata(px, ld);
158 gd.gp[ld.id] = 1;
159 }
160 if (gd.gp[i-xs]>20) {
161 ld.id = i-xs;
162 ld.lv = (int)gd.gp[ld.id];
163 px = add_tList_node_bydata(px, ld);
164 gd.gp[ld.id] = 1;
165 }
166 if (gd.gp[i+ps]>20) {
167 ld.id = i+ps;
168 ld.lv = (int)gd.gp[ld.id];
169 px = add_tList_node_bydata(px, ld);
170 gd.gp[ld.id] = 1;
171 }
172 if (gd.gp[i-ps]>20) {
173 ld.id = i-ps;
174 ld.lv = (int)gd.gp[ld.id];
175 px = add_tList_node_bydata(px, ld);
176 gd.gp[ld.id] = 1;
177 }
178 }
179 }
180 else {
181 px->ldat.lv = 16;
182 }
183 }
184 px = px->next;
185 }
186 }
187
188 // STEP 5
189 //DEBUG_Warning("center_line: start step5");
190 dd = rr;
191 px = pp->next;
192 while(px!=NULL) {
193 if (px->ldat.lv>20) {
194 dd = Min(dd, px->ldat.lv);
195 }
196 px = px->next;
197 }
198 mm = nn = 0;
199 px = pp->next;
200 while(px!=NULL) {
201 nn++;
202 if (px->ldat.lv==16) mm++;
203 px = px->next;
204 }
205
206 } while (dd<rr || mm!=nn);
207
208 vp.setup(gd.xs, gd.ys, gd.zs);
209 for (i=0; i<gd.xs*gd.ys*gd.zs; i++) vp.gp[i] = (T)gd.gp[i];
210 gd.free();
211
212 return vp;
213}
214
215
216template <typename T> int nonZeroBoxel(MSGraph<T> vp, int n)
217{
218 int m, xs, ps;
219
220 ps = vp.xs*vp.ys;
221 xs = vp.xs;
222
223 m = 0;
224 if (vp.gp[n+1] !=0) m++;
225 if (vp.gp[n-1] !=0) m++;
226 if (vp.gp[n+xs] !=0) m++;
227 if (vp.gp[n-xs] !=0) m++;
228 if (vp.gp[n+ps] !=0) m++;
229 if (vp.gp[n-ps] !=0) m++;
230 if (vp.gp[n+1+xs] !=0) m++;
231 if (vp.gp[n+1-xs] !=0) m++;
232 if (vp.gp[n-1+xs] !=0) m++;
233 if (vp.gp[n-1-xs] !=0) m++;
234 if (vp.gp[n+1+ps] !=0) m++;
235 if (vp.gp[n+1-ps] !=0) m++;
236 if (vp.gp[n-1+ps] !=0) m++;
237 if (vp.gp[n-1-ps] !=0) m++;
238 if (vp.gp[n+xs+ps] !=0) m++;
239 if (vp.gp[n+xs-ps] !=0) m++;
240 if (vp.gp[n-xs+ps] !=0) m++;
241 if (vp.gp[n-xs-ps] !=0) m++;
242 if (vp.gp[n+1+xs+ps]!=0) m++;
243 if (vp.gp[n+1+xs-ps]!=0) m++;
244 if (vp.gp[n+1-xs+ps]!=0) m++;
245 if (vp.gp[n+1-xs-ps]!=0) m++;
246 if (vp.gp[n-1+xs+ps]!=0) m++;
247 if (vp.gp[n-1+xs-ps]!=0) m++;
248 if (vp.gp[n-1-xs+ps]!=0) m++;
249 if (vp.gp[n-1-xs-ps]!=0) m++;
250
251 return m;
252}
253
254
268template <typename T> bool deletable(MSGraph<T> vp, int n, int c, int d)
269{
270 int i, j, k, l, m, lz, ly, mz, my;
271 int cn, mm, nh;
272 int v[27];
273 bool ret;
274
275 if (d<3) { // 2D- YET NO IMPLIMENT
276 mm = 9;
277 for (j=-1; j<=1; j++) {
278 ly = (j+1)*3;
279 my = n + j*vp.xs;
280 for (i=-1; i<=1; i++) {
281 l = ly + (i+1);
282 m = my + i;
283 if (vp.gp[m]!=0) v[l] = 1;
284 else v[l] = 0;
285 }
286 }
287 DEBUG_MODE PRINT_MESG("DELETABLE: 2D mode is not supported.\n");
288 return false;
289 }
290 else { // for 3D
291 mm = 27;
292 for (k=-1; k<=1; k++) {
293 lz = (k+1)*9;
294 mz = n + k*vp.xs*vp.ys;
295 for (j=-1; j<=1; j++) {
296 ly = lz + (j+1)*3;
297 my = mz + j*vp.xs;
298 for (i=-1; i<=1; i++) {
299 l = ly + (i+1);
300 m = my + i;
301 if (vp.gp[m]>0) v[l] = 1;
302 else v[l] = 0;
303 }
304 }
305 }
306 }
307
308 cn = connectNumber(v, c, d);
309 if (cn==-1 || cn!=1) return false;
310
311 if (c==26 || c==8) {
312 v[c/2] = 1 - v[c/2];
313 for(i=0; i<mm; i++) v[i] = 1 - v[i];
314 }
315
316 nh = v[10] + v[12] + v[14] + v[16] + v[4] + v[22];
317 if (nh<=3) ret = true;
318 else if (nh==4) ret = deletable_s(v);
319 else if (nh==5) ret = deletable_4(v);
320 else if (nh==6) ret = deletable_5(v);
321
322 return ret;
323}
324
325
326} // namespace
327
328
329#endif
330
MSGraph用 数学ライブラリ ヘッダ in Graph Library.
T * gp
グラフィックデータへのポインタ.
Definition Gdata.h:81
int zs
zサイズ. 4Byte. 2Dの場合は 1.
Definition Gdata.h:80
int xs
xサイズ. 4Byte.
Definition Gdata.h:78
T zero
画素値のゼロ位.
Definition Gdata.h:82
void free(void)
グラフィックデータを開放する
Definition Gdata.h:378
int ys
yサイズ. 4Byte.
Definition Gdata.h:79
#define Min(x, y)
Definition common.h:250
#define Max(x, y)
Definition common.h:247
#define SINTMAX
Definition common.h:204
Definition Brep.h:29
int connectNumber(int *w, int c, int d)
Definition Thinning.cpp:26
MSGraph< int > euclidDistance(MSGraph< T > vp, int bc, int &rr)
Definition Gmt.h:864
int nonZeroBoxel(MSGraph< T > vp, int n)
Definition Thinning.h:216
bool deletable_4(int *v)
Definition Thinning.cpp:104
MSGraph< T > centerLine(MSGraph< T > gx, int mode)
Definition Thinning.h:41
bool deletable(MSGraph< T > vp, int n, int c, int d)
Definition Thinning.h:268
bool deletable_5(int *v)
Definition Thinning.cpp:140
MSGraph< T > CenterLine(MSGraph< T > gx, int mode)
bool deletable_s(int *v)
Definition Thinning.cpp:86
tList * add_tList_node_bydata(tList *pp, tList_data ldat)
データ(ldat)からリスト用ノードを生成し(new),それを指定したリストの後ろに追加.
Definition tlist.cpp:417
tList * del_tList_node(tList **node)
リスト用のノードを削除.
Definition tlist.cpp:270
tList_data init_tList_data(void)
空のノードデータを静的に作成.データを初期化するのに使用する.
Definition tlist.cpp:26
tList * new_tList_node(void)
リスト用の空ノードを動的に生成する.
Definition tlist.cpp:198
Tiny List 構造ライブラリヘッダ
#define PRINT_MESG(...)
環境依存用の出力関数.MS Windows用は未実装
Definition tools.h:469
#define DEBUG_MODE
Definition tools.h:502