00001
00002 #include "gevd_contour.h"
00003
00004
00005 #include <vcl_iostream.h>
00006 #include <vcl_cstdlib.h>
00007 #include <vcl_vector.h>
00008 #include <vcl_algorithm.h>
00009 #include <vxl_config.h>
00010 #include <vnl/vnl_math.h>
00011 #include <vdgl/vdgl_digital_curve.h>
00012 #include <vdgl/vdgl_edgel_chain.h>
00013 #include <vdgl/vdgl_interpolator.h>
00014 #include <vdgl/vdgl_interpolator_linear.h>
00015 #include <vtol/vtol_vertex_2d.h>
00016 #include <vtol/vtol_edge_2d.h>
00017 #include <gevd/gevd_pixel.h>
00018 #ifdef DEBUG
00019 # include <vul/vul_timer.h>
00020 #endif
00021
00022 const int INVALID = -1;
00023
00024
00025
00026 const vxl_byte TWOPI = 8, HALFPI = 2 ;
00027
00028 const int DIS[] = { 1, 1, 0,-1,-1,-1, 0, 1,
00029 1, 1, 0,-1,-1,-1, 0, 1,
00030 1, 1, 0,-1,-1,-1, 0, 1};
00031 const int DJS[] = { 0, 1, 1, 1, 0,-1,-1,-1,
00032 0, 1, 1, 1, 0,-1,-1,-1,
00033 0, 1, 1, 1, 0,-1,-1,-1};
00034
00035
00036 const int RIS[] = { 1, 0,-1, 0,
00037 1,-1,-1, 1,
00038 2, 0,-2, 0,
00039 2, 1,-1,-2,-2,-1, 1, 2,
00040 2,-2,-2, 2,
00041 3, 0,-3, 0,
00042 3, 1,-1,-3,-3,-1, 1, 3,
00043 3, 2,-2,-3,-3,-2, 2, 3,
00044 4, 0,-4, 0};
00045 const int RJS[] = { 0, 1, 0,-1,
00046 1, 1,-1,-1,
00047 0, 2, 0,-2,
00048 1, 2, 2, 1,-1,-2,-2,-1,
00049 2, 2,-2,-2,
00050 0, 3, 0,-3,
00051 1, 3, 3, 1,-1,-3,-3,-1,
00052 2, 3, 3, 2,-2,-3,-3,-2,
00053 0, 4, 0,-4};
00054 const int RNS[] = { 4, 8, 12, 20, 24, 28, 36, 44, 48};
00055 const float RGS[] = { 1.f, 1.414213f, 2.f, 2.236067f, 2.828427f,
00056 3.f, 3.162277f, 3.605551f, 4.f};
00057
00058
00059 const int MINLENGTH = 3;
00060 const int FRAME = 4;
00061
00062 bool gevd_contour::talkative = true;
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 gevd_contour::gevd_contour(float min_strength, int min_length,
00074 float min_jump, float max_gap)
00075 : minStrength(min_strength), minLength(min_length),
00076 minJump(min_jump), maxSpiral(0),
00077 edgeMap(), vertexMap()
00078 {
00079 if (minStrength < 0) {
00080 vcl_cerr << "gevd_contour::gevd_contour -- negative min_strength: "
00081 << minStrength << ". Reset to 0.\n";
00082 minStrength = 0;
00083 }
00084 if (minLength < MINLENGTH) {
00085 vcl_cerr << "gevd_contour::gevd_contour -- too small min_length: "
00086 << minLength << ". Reset to " << MINLENGTH << ".\n";
00087 minLength = MINLENGTH;
00088 }
00089 if (minJump < 0) {
00090 vcl_cerr << "gevd_contour::gevd_contour -- negative min_jump: "
00091 << minJump << ". Reset to 0.\n";
00092 minJump = 0;
00093 }
00094 if (minJump > minStrength) {
00095 vcl_cerr << "gevd_contour::gevd_contour -- too large min_jump: "
00096 << min_jump << ". Reset to " << minStrength << ".\n";
00097 minJump = minStrength;
00098 }
00099 if (max_gap < 1) {
00100 vcl_cerr << "gevd_contour::gevd_contour -- too small max_gap: "
00101 << max_gap << ". Reset to 1.\n";
00102 max_gap = 1;
00103 }
00104 if (max_gap > FRAME) {
00105 vcl_cerr << "gevd_contour::gevd_contour -- too large max_gap: "
00106 << max_gap << ". Reset to " << FRAME << vcl_endl;
00107 max_gap = FRAME;
00108 }
00109 for (int i = 0; i < 9; i++)
00110 if (max_gap <= RGS[i])
00111 maxSpiral= i+1;
00112 }
00113
00114
00115
00116 gevd_contour::~gevd_contour()
00117 {
00118 delete edgeMap;
00119 delete vertexMap;
00120 }
00121
00122
00123
00124
00125
00126
00127 bool
00128 gevd_contour::FindNetwork(gevd_bufferxy& edgels,
00129 const int njunction,
00130 const int* junctionx, const int* junctiony,
00131 vcl_vector<vtol_edge_2d_sptr>*& edges,
00132 vcl_vector<vtol_vertex_2d_sptr >*& vertices)
00133 {
00134
00135
00136 if (!edges)
00137 edges = new vcl_vector<vtol_edge_2d_sptr>;
00138 else
00139 edges->clear();
00140 if (!vertices)
00141 vertices = new vcl_vector<vtol_vertex_2d_sptr >;
00142 else
00143 vertices->clear();
00144
00145
00146 if (talkative)
00147 vcl_cout << "*** Link edge elements into connected edges/vertices.\n";
00148
00149
00150 vertexMap = new vbl_array_2d<vtol_vertex_2d_sptr>(edgels.GetSizeX(), edgels.GetSizeY());
00151 vertexMap->fill(NULL);
00152 edgeMap = new vbl_array_2d<vtol_edge_2d_sptr>(edgels.GetSizeX(), edgels.GetSizeY());
00153 edgeMap->fill(NULL);
00154
00155
00156 int n;
00157
00158 vcl_vector<vtol_edge_2d_sptr> *edges2 = new vcl_vector<vtol_edge_2d_sptr>;
00159 n = this->FindChains(edgels,
00160 njunction,
00161 junctionx, junctiony,
00162 *edges2);
00163 if (!n)
00164 return false;
00165
00166
00167
00168 if (edges2->size() < 1000)
00169 vcl_sort (edges2->begin(), edges2->end());
00170
00171
00172
00173 for (unsigned int i= 0; i< edges2->size(); i++)
00174 (*edges2)[i]->set_id(i);
00175
00176
00177 vcl_vector<vtol_vertex_2d_sptr > vertices2;
00178 this->FindJunctions(edgels,
00179 *edges2, vertices2);
00180
00181
00182 for (unsigned int i= 0; i< edges2->size(); i++)
00183 edges->push_back( (*edges2)[i]);
00184
00185 for (unsigned int i=0; i< vertices2.size(); i++)
00186 vertices->push_back( vertices2[i]);
00187
00188 return true;
00189 }
00190
00191
00192
00193 static bool
00194 on_contour(const gevd_bufferxy& edgels, const int i, const int j)
00195 {
00196 double pix = (1 + vnl_math::sqrt2) * floatPixel(edgels, i, j);
00197 for (vxl_byte dir = 0; dir < TWOPI; dir += HALFPI)
00198 if (floatPixel(edgels, i+DIS[dir], j+DJS[dir]) > pix)
00199 return false;
00200 return true;
00201 }
00202
00203
00204
00205 static void
00206 RecordPixel(int i, int j, gevd_bufferxy& edgels,
00207 vcl_vector<int>& iloc, vcl_vector<int>& jloc)
00208 {
00209 floatPixel(edgels, i, j) = -floatPixel(edgels, i, j);
00210 iloc.push_back(i), jloc.push_back(j);
00211 }
00212
00213
00214
00215
00216
00217
00218 static int
00219 NextPixel(int& i, int& j, const gevd_bufferxy& edgels)
00220 {
00221 float maxpix = 0, npix;
00222 int maxdir = 0, dir;
00223 for (dir = 0; dir < TWOPI; dir += HALFPI)
00224 if ((npix = floatPixel(edgels, i+DIS[dir], j+DJS[dir])) > maxpix) {
00225 maxpix = npix;
00226 maxdir = dir+TWOPI;
00227 }
00228 if (!maxdir) {
00229 for (dir = 1; dir < TWOPI; dir += HALFPI)
00230 if ((npix = floatPixel(edgels, i+DIS[dir], j+DJS[dir])) > maxpix) {
00231 maxpix = npix;
00232 maxdir = dir+TWOPI;
00233 }
00234 }
00235 if (maxdir)
00236 i += DIS[maxdir], j += DJS[maxdir];
00237 return maxdir;
00238 }
00239
00240
00241
00242
00243
00244
00245 static int
00246 next_pixel(int& i, int& j, const vbl_array_2d<vtol_vertex_2d_sptr>& vertexMap)
00247 {
00248 int maxdir = 0, dir;
00249 for (dir = 0; dir < TWOPI; dir += HALFPI)
00250 if (vertexMap.get(i+DIS[dir], j+DJS[dir])) {
00251 maxdir = dir+TWOPI;
00252 break;
00253 }
00254 if (!maxdir) {
00255 for (dir = 1; dir < TWOPI; dir += HALFPI)
00256 if (vertexMap.get(i+DIS[dir], j+DJS[dir])) {
00257 maxdir = dir+TWOPI;
00258 break;
00259 }
00260 }
00261 if (maxdir)
00262 i += DIS[maxdir], j += DJS[maxdir];
00263 return maxdir;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 int
00277 gevd_contour::FindChains(gevd_bufferxy& edgels, const int njunction,
00278 const int* junctionx, const int* junctiony,
00279 vcl_vector<vtol_edge_2d_sptr>& edges)
00280 {
00281 #ifdef DEBUG
00282 vul_timer t;
00283 #endif
00284
00285
00286
00287
00288 vtol_vertex_2d_sptr mark = new vtol_vertex_2d;
00289 for (int k = 0; k < njunction; k++) {
00290 vertexMap->put(junctionx[k], junctiony[k], mark);
00291 }
00292
00293
00294
00295 const int rmax = FRAME;
00296 const int xmax = edgels.GetSizeX()-rmax-1;
00297 const int ymax = edgels.GetSizeY()-rmax-1;
00298 vcl_vector<int> xloc(xmax+ymax), yloc(xmax+ymax);
00299
00300 for (int j = rmax; j <= ymax; j++)
00301 for (int i = rmax; i <= xmax; i++)
00302 {
00303
00304 if (floatPixel(edgels, i, j) > minStrength &&
00305 on_contour(edgels, i, j)) {
00306 int x = i, y = j;
00307
00308
00309 if (!NextPixel(x, y, edgels)) {
00310 floatPixel(edgels, i, j) = 0;
00311 continue;
00312 }
00313
00314
00315 xloc.clear(), yloc.clear();
00316 RecordPixel(i, j, edgels, xloc, yloc);
00317 int ii = x, jj = y;
00318 RecordPixel(ii, jj, edgels, xloc, yloc);
00319 if (NextPixel(x, y, edgels))
00320 RecordPixel(x, y, edgels, xloc, yloc);
00321 else {
00322 x = i, y = j;
00323 if (NextPixel(x, y, edgels)) {
00324 xloc.clear(), yloc.clear();
00325 RecordPixel(ii, jj, edgels, xloc, yloc);
00326 RecordPixel(i, j, edgels, xloc, yloc);
00327 RecordPixel(x, y, edgels, xloc, yloc);
00328 ii = i, jj = j;
00329 } else {
00330 floatPixel(edgels, i, j) = 0;
00331 floatPixel(edgels, ii, jj) = 0;
00332 continue;
00333 }
00334 }
00335
00336
00337 if ((x - ii)*(ii - xloc[0]) +
00338 (y - jj)*(jj - yloc[0]) < 0) {
00339 xloc[1] = xloc[0], yloc[1] = yloc[0];
00340 xloc[0] = ii, yloc[0] = jj;
00341 }
00342
00343
00344 while (NextPixel(x, y, edgels))
00345 RecordPixel(x, y, edgels, xloc, yloc);
00346
00347 if (vcl_abs(xloc[0]-x) > 1 ||
00348 vcl_abs(yloc[0]-y) > 1) {
00349 if (next_pixel(x, y, *vertexMap))
00350 xloc.push_back(x), yloc.push_back(y);
00351 x = xloc[0], y = yloc[0];
00352
00353 vcl_vector<int> xloctemp( xloc.size()), yloctemp( yloc.size());
00354 for (unsigned int iii=0; iii< xloc.size(); iii++)
00355 xloctemp[iii]= xloc[xloc.size()-1-iii];
00356 for (unsigned int jjj=0; jjj< yloc.size(); jjj++)
00357 yloctemp[jjj]= yloc[yloc.size()-1-jjj];
00358
00359 while (NextPixel(x, y, edgels))
00360 RecordPixel(x, y, edgels, xloc, yloc);
00361 if (next_pixel(x, y, *vertexMap))
00362 xloc.push_back(x), yloc.push_back(y);
00363 }
00364 int len = xloc.size();
00365
00366
00367 if (len < minLength) {
00368 for (int k = 0; k < len; k++)
00369 floatPixel(edgels, xloc[k], yloc[k]) = 0;
00370 continue;
00371 }
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 vtol_edge_2d_sptr edge = new vtol_edge_2d();
00383 vdgl_edgel_chain * ec = new vdgl_edgel_chain;
00384 vdgl_interpolator * it = new vdgl_interpolator_linear(ec);
00385 vdgl_digital_curve * dc = new vdgl_digital_curve(it);
00386
00387 for (int k=0; k< len; k++)
00388 {
00389 x= xloc[k];
00390 y= yloc[k];
00391 ec->add_edgel( vdgl_edgel( x, y));
00392 edgeMap->put(x, y, edge);
00393 }
00394 edge->set_curve(*dc);
00395 LookupTableInsert(edges, edge);
00396 }
00397 }
00398
00399
00400 for (int k = 0; k < njunction; k++)
00401 vertexMap->put(junctionx[k], junctiony[k],NULL);
00402 for (int j = rmax; j <= ymax; j++)
00403 for (int i = rmax; i <= xmax; i++)
00404 if (floatPixel(edgels, i, j) < 0)
00405 floatPixel(edgels, i, j) = - floatPixel(edgels, i, j);
00406
00407 if (talkative)
00408 vcl_cout << "Find " << edges.size()
00409 << " chains/cycles, with pixels > " << minLength
00410 << " and strength > " << minStrength
00411 #ifdef DEBUG
00412 << ", in " << t.real() << " msecs."
00413 #endif
00414 << vcl_endl;
00415 return edges.size();
00416 }
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 bool
00427 DetectJunction(vtol_vertex_2d& end, int& index,
00428 vtol_edge_2d_sptr& weaker, vtol_edge_2d_sptr& stronger,
00429 const int maxSpiral,
00430 const gevd_bufferxy& edgels, vbl_array_2d<vtol_edge_2d_sptr>& edgeMap)
00431 {
00432
00433 if (end.numsup() > 1)
00434 return false;
00435 vcl_vector<vtol_edge_sptr> edges; end.edges(edges);
00436 weaker = edges[0]->cast_to_edge_2d();
00437 vdgl_digital_curve_sptr dc = weaker->curve()->cast_to_vdgl_digital_curve();
00438
00439 const int len = dc->get_interpolator()->get_edgel_chain()->size();
00440
00441
00442
00443 const int rfuzz = vcl_min(len, 3*MINLENGTH);
00444 vtol_edge_2d_sptr* labels = new vtol_edge_2d_sptr[rfuzz];
00445 if (&end == weaker->v1()->cast_to_vertex_2d())
00446 for (int r = 0; r < rfuzz; r++) {
00447 vdgl_edgel edgel= dc->get_interpolator()->get_edgel_chain()->edgel( r);
00448 labels[r] = edgeMap.get( int(edgel.get_x()), int(edgel.get_y()));
00449 edgeMap.put(int(edgel.get_x()), int(edgel.get_y()), NULL);
00450 }
00451 else
00452 for (int r = 0; r < rfuzz; r++) {
00453 vdgl_edgel edgel= dc->get_interpolator()->get_edgel_chain()->edgel(len-1-r);
00454 labels[r] = edgeMap.get( int( edgel.get_x()), int( edgel.get_y()));
00455 edgeMap.put(int(edgel.get_x()), int(edgel.get_y()), NULL);
00456 }
00457
00458
00459 stronger = NULL;
00460 int jx = int(end.x()), jy = int(end.y());
00461 for (int l = 0, n = 0; l < maxSpiral; l++) {
00462 float maxpix = 0; int maxn = 0;
00463 for (; n < RNS[l]; n++) {
00464 int x = jx+RIS[n], y = jy+RJS[n];
00465 if (edgeMap.get(x, y) &&
00466 floatPixel(edgels, x, y) > maxpix) {
00467 maxpix = floatPixel(edgels, x, y);
00468 maxn = n;
00469 }
00470 }
00471 if (maxpix) {
00472 stronger = edgeMap.get(jx+RIS[maxn], jy+RJS[maxn]);
00473 jx += RIS[maxn], jy += RJS[maxn];
00474 break;
00475 }
00476 }
00477
00478 if (&end == weaker->v1()->cast_to_vertex_2d())
00479 for (int r=0; r< rfuzz; r++) {
00480 vdgl_edgel edge= dc->get_interpolator()->get_edgel_chain()->edgel(r);
00481 edgeMap.put(int( edge.get_x()), int( edge.get_y()), labels[r]);
00482 }
00483 else
00484 for (int r=0; r< rfuzz; r++) {
00485 vdgl_edgel edgel= dc->get_interpolator()->get_edgel_chain()->edgel(len-1-r);
00486 edgeMap.put(int( edgel.get_x()), int( edgel.get_y()),labels[r]);
00487 }
00488 delete[] labels;
00489
00490 if (!stronger)
00491 return false;
00492
00493
00494 index = int(INVALID);
00495
00496 vdgl_digital_curve_sptr dc2 =(stronger->curve()->cast_to_vdgl_digital_curve());
00497
00498
00499 for (unsigned int n = 0; n < dc2->get_interpolator()->get_edgel_chain()->size(); ++n)
00500 {
00501 vdgl_edgel edgel= dc2->get_interpolator()->get_edgel_chain()->edgel(n);
00502
00503 if ( int( edgel.get_x())== jx && int( edgel.get_y())== jy)
00504 {
00505 index = n;
00506 break;
00507 }
00508 }
00509 return true;
00510 }
00511
00512
00513
00514
00515
00516 static bool
00517 ConfirmJunctionOnCycle(int index, float threshold,
00518 vtol_edge_2d& cycle, const gevd_bufferxy& edgels)
00519 {
00520 vdgl_digital_curve_sptr dc =(cycle.curve()->cast_to_vdgl_digital_curve());
00521 const int len = dc->get_interpolator()->get_edgel_chain()->size();
00522 const int wrap = 10*len;
00523 const int radius = 3;
00524
00525 for (int n = index-radius; n <= index+radius; n++)
00526 {
00527 int nm = (n-1+wrap)%len;
00528 int np = (n+1+wrap)%len;
00529
00530 vdgl_edgel edgel_m= dc->get_interpolator()->get_edgel_chain()->edgel( nm);
00531 vdgl_edgel edgel_p= dc->get_interpolator()->get_edgel_chain()->edgel( np);
00532
00533 if (vcl_fabs(floatPixel(edgels, int( edgel_p.x()), int( edgel_p.y())) -
00534 floatPixel(edgels, int( edgel_m.x()), int( edgel_m.y())))
00535 > threshold)
00536 return true;
00537 }
00538 return false;
00539 }
00540
00541
00542
00543
00544
00545 void
00546 BreakCycle(vtol_vertex_2d& junction, const int index,
00547 vtol_edge_2d& stronger, vtol_edge_2d_sptr& split,
00548 vbl_array_2d<vtol_edge_2d_sptr>& edgeMap, vbl_array_2d<vtol_vertex_2d_sptr>& vertexMap)
00549 {
00550 vdgl_digital_curve_sptr dc = (stronger.curve()->cast_to_vdgl_digital_curve());
00551 const int len = dc->get_interpolator()->get_edgel_chain()->size();
00552
00553
00554 int jx = int(junction.x()), jy = int(junction.y());
00555 vertexMap.put(jx, jy, NULL);
00556
00557 vdgl_edgel tempedgel= dc->get_interpolator()->get_edgel_chain()->edgel( index);
00558 jx = int( tempedgel.x()), jy = int( tempedgel.y());
00559 junction.set_x(jx), junction.set_y(jy);
00560 vertexMap.put(jx, jy, &junction);
00561 edgeMap.put(jx, jy, NULL);
00562
00563
00564 split = new vtol_edge_2d();
00565
00566 vdgl_edgel_chain *es= new vdgl_edgel_chain;
00567 vdgl_interpolator *it= new vdgl_interpolator_linear( vdgl_edgel_chain_sptr( es));
00568 vdgl_digital_curve *ds = new vdgl_digital_curve( vdgl_interpolator_sptr( it));
00569
00570 split->set_curve(*ds->cast_to_curve());
00571
00572 int i=0;
00573 for (int k = index; k < len; i++,k++) {
00574 vdgl_edgel e= dc->get_interpolator()->get_edgel_chain()->edgel( k);
00575 es->add_edgel( e);
00576 edgeMap.put(int(e.x()), int(e.y()), split);
00577 }
00578 for (int k = 0; i < len; i++,k++) {
00579 vdgl_edgel c= dc->get_interpolator()->get_edgel_chain()->edgel( k);
00580 es->add_edgel( c);
00581 edgeMap.put(int(c.x()), int(c.y()), split);
00582 }
00583
00584 split->set_v1(&junction);
00585 split->set_v2(&junction);
00586 }
00587
00588
00589
00590
00591
00592 static bool
00593 ConfirmJunctionOnChain(int index, float threshold,
00594 vtol_edge_2d& chain, const gevd_bufferxy& edgels)
00595 {
00596 vdgl_digital_curve_sptr dc = chain.curve()->cast_to_vdgl_digital_curve();
00597 const int len = dc->get_interpolator()->get_edgel_chain()->size()-1;
00598
00599 if (len < 2*MINLENGTH-1)
00600 return false;
00601
00602 const int fuzz = MINLENGTH-1;
00603 const int radius = 3;
00604
00605 for (int n = vcl_max(index-radius, fuzz); n <= vcl_min(index+radius,len-1-fuzz); n++)
00606 {
00607 vdgl_edgel cp1= dc->get_interpolator()->get_edgel_chain()->edgel(n+1);
00608 vdgl_edgel cm1= dc->get_interpolator()->get_edgel_chain()->edgel(n-1);
00609
00610 if (vcl_fabs(floatPixel(edgels, int(cp1.x()), int(cp1.y())) -
00611 floatPixel(edgels, int(cp1.x()), int(cm1.y())))
00612 > threshold)
00613 {
00614 return true;
00615 }
00616 }
00617 return false;
00618 }
00619
00620
00621
00622
00623 void
00624 BreakChain(vtol_vertex_2d& junction, const int index,
00625 vtol_edge_2d& stronger,
00626 vtol_edge_2d_sptr& longer, vtol_edge_2d_sptr& shorter,
00627 vbl_array_2d<vtol_edge_2d_sptr>& edgeMap, vbl_array_2d<vtol_vertex_2d_sptr>& vertexMap)
00628 {
00629 vdgl_digital_curve_sptr dc = stronger.curve()->cast_to_vdgl_digital_curve();
00630 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
00631
00632 const int l0 = dc->get_interpolator()->get_edgel_chain()->size();
00633 const int l1 = index+1, l2 = l0-index;
00634
00635
00636 int jx = int(junction.x()), jy = int(junction.y());
00637 vertexMap.put(jx, jy, NULL);
00638 vdgl_edgel c= dc->get_interpolator()->get_edgel_chain()->edgel( index);
00639 jx = int(c.x()), jy = int(c.y());
00640 junction.set_x(jx), junction.set_y(jy);
00641 vertexMap.put(jx, jy, &junction);
00642 edgeMap.put( jx, jy, NULL);
00643
00644
00645 vtol_edge_2d_sptr edge1 = new vtol_edge_2d();
00646
00647 vdgl_edgel_chain *ec= new vdgl_edgel_chain;
00648 vdgl_interpolator *it= new vdgl_interpolator_linear( ec);
00649 vdgl_digital_curve *dc1 = new vdgl_digital_curve( it);
00650
00651 edge1->set_curve(*dc1);
00652
00653 vdgl_edgel_chain *cxy1= ec;
00654
00655 for (int k = 0; k < l1; k++)
00656 {
00657 cxy1->add_edgel ( (*cxy)[k] );
00658 (*cxy1)[k] = (*cxy)[k];
00659 edgeMap.put( int((*cxy1)[k].x()), int((*cxy1)[k].y()), edge1);
00660 }
00661
00662
00663 vtol_vertex_sptr v1 = stronger.v1();
00664
00665 if (v1->numsup() == 1)
00666 edgeMap.put( int((*cxy1)[0].x()), int((*cxy1)[0].y()), NULL);
00667 edge1->set_v1(v1.ptr());
00668 edge1->set_v2(&junction);
00669
00670
00671 vtol_edge_2d_sptr edge2 = new vtol_edge_2d();
00672
00673 vdgl_edgel_chain *ec2= new vdgl_edgel_chain;
00674 vdgl_interpolator *it2= new vdgl_interpolator_linear( ec2);
00675 vdgl_digital_curve *dc2= new vdgl_digital_curve( it2);
00676
00677 edge2->set_curve(*dc2);
00678
00679 vdgl_edgel_chain *cxy2= ec2;
00680
00681
00682 for (int k = 0; k < l2; k++)
00683 {
00684 cxy2->add_edgel( cxy->edgel( k+index));
00685 edgeMap.put( int((*cxy2)[k].x()), int((*cxy2)[k].y()), edge2);
00686 }
00687
00688
00689 vtol_vertex_sptr v2 = stronger.v2();
00690
00691 if (v2->numsup() == 1)
00692 edgeMap.put( int((*cxy2)[l2-1].x()), int((*cxy2)[l2-1].y()), NULL);
00693
00694 edge2->set_v1(&junction);
00695 edge2->set_v2(v2.ptr());
00696
00697 if (l1 >= l2)
00698 longer = edge1, shorter = edge2;
00699 else
00700 longer = edge2, shorter = edge1;
00701 }
00702
00703
00704
00705
00706 void
00707 LoopChain(vtol_vertex_2d& junction, const int index,
00708 vtol_edge_2d& chain,
00709 vtol_edge_2d_sptr& straight, vtol_edge_2d_sptr& curled,
00710 vbl_array_2d<vtol_edge_2d_sptr>& edgeMap, vbl_array_2d<vtol_vertex_2d_sptr>& vertexMap)
00711 {
00712 vdgl_digital_curve_sptr dc = chain.curve()->cast_to_vdgl_digital_curve();
00713
00714 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
00715 const int l0 = cxy->size();
00716
00717
00718 int jx = int(junction.x()), jy = int(junction.y());
00719 vertexMap.put(jx, jy, NULL);
00720 jx = int((*cxy)[index].x()), jy = int((*cxy)[index].y());
00721 junction.set_x(jx), junction.set_y(jy);
00722 vertexMap.put(jx, jy, &junction);
00723 edgeMap.put( jx, jy, NULL);
00724
00725
00726 straight = new vtol_edge_2d(), curled = new vtol_edge_2d();
00727 const int l1 = index+1, l2 = l0-index;
00728
00729 if (&junction == chain.v1()->cast_to_vertex_2d())
00730 {
00731 vdgl_edgel_chain *ec= new vdgl_edgel_chain;
00732 vdgl_interpolator *it= new vdgl_interpolator_linear( ec);
00733 vdgl_digital_curve *c= new vdgl_digital_curve( it);
00734
00735 curled->set_curve(*c);
00736
00737 vdgl_edgel_chain *xy= ec;
00738 for (int k = 0; k < l1; k++)
00739 {
00740 xy->add_edgel ( (*cxy)[k] );
00741 (*xy)[k] = (*cxy)[k];
00742 edgeMap.put( int((*xy)[k].x()), int((*xy)[k].y()), curled);
00743 }
00744
00745 curled->set_v1(&junction);
00746 curled->set_v2(&junction);
00747
00748
00749 ec= new vdgl_edgel_chain;
00750 it= new vdgl_interpolator_linear( ec);
00751 c = new vdgl_digital_curve( it);
00752
00753 straight->set_curve(*c);
00754
00755 xy= ec;
00756
00757 for (int k = 0; k < l2; k++)
00758 {
00759 xy->add_edgel ( (*cxy)[k+index] );
00760 (*xy)[k] = (*cxy)[k+index];
00761 edgeMap.put( int((*xy)[k].x()), int((*xy)[k].y()), straight);
00762 }
00763
00764 if (chain.v2()->numsup()==1)
00765 {
00766 edgeMap.put( int((*xy)[l2-1].x()), int((*xy)[l2-1].y()), NULL);
00767 }
00768
00769 straight->set_v1(&junction);
00770 straight->set_v2(chain.v2().ptr());
00771 }
00772 else
00773 {
00774 vdgl_edgel_chain *ec= new vdgl_edgel_chain;
00775 vdgl_interpolator *it= new vdgl_interpolator_linear( ec);
00776 vdgl_digital_curve *c= new vdgl_digital_curve( it);
00777
00778 straight->set_curve(*c);
00779
00780
00781 vdgl_edgel_chain *xy= ec;
00782
00783 for (int k = 0; k < l1; k++)
00784 {
00785 xy->add_edgel ( (*cxy)[k] );
00786 (*xy)[k] = (*cxy)[k];
00787 edgeMap.put( int((*xy)[k].x()), int((*xy)[k].y()), straight);
00788 }
00789
00790 if (chain.v1()->numsup()==1)
00791 {
00792 edgeMap.put( int((*xy)[0].x()), int((*xy)[0].y()), NULL);
00793 }
00794
00795 straight->set_v1(chain.v1().ptr());
00796 straight->set_v2(&junction);
00797
00798
00799 ec= new vdgl_edgel_chain;
00800 it= new vdgl_interpolator_linear( ec);
00801 c = new vdgl_digital_curve( it);
00802
00803 curled->set_curve(*c);
00804
00805 xy = ec;
00806 for (int k = 0; k < l2; k++)
00807 {
00808 xy->add_edgel ( (*cxy)[k+index] );
00809 (*xy)[k] = (*cxy)[k+index];
00810 edgeMap.put( int((*xy)[k].x()), int((*xy)[k].y()), curled);
00811 }
00812
00813 curled->set_v1(&junction);
00814 curled->set_v2(&junction);
00815 }
00816 }
00817
00818
00819 int
00820 NumConnectedRays(vtol_vertex_2d& v)
00821 {
00822 int nray = 0;
00823 vcl_vector<vtol_edge_sptr> segs; v.edges(segs);
00824 for (unsigned int i=0; i< segs.size(); i++)
00825 {
00826 if (segs[i]->v1()->cast_to_vertex_2d() == &v) nray++;
00827 if (segs[i]->v2()->cast_to_vertex_2d() == &v) nray++;
00828 }
00829 return nray;
00830 }
00831
00832
00833
00834 vtol_vertex_2d_sptr
00835 DetectTouch(const vtol_vertex_2d& end, const int maxSpiral,
00836 vbl_array_2d<vtol_vertex_2d_sptr>& vertexMap)
00837 {
00838 const int jx = int(end.x()), jy = int(end.y());
00839 for (int l = 0, n = 0; l < maxSpiral; l++) {
00840 vtol_vertex_2d_sptr other = NULL;
00841 int maxray = 0;
00842 for (; n < RNS[l]; n++) {
00843 vtol_vertex_2d_sptr nbr = vertexMap.get(jx+RIS[n], jy+RJS[n]);
00844 int nray = (nbr ? NumConnectedRays(*nbr) : 0);
00845 if (nray > maxray) {
00846 maxray = nray;
00847 other = nbr;
00848 }
00849 }
00850 if (maxray)
00851 return other;
00852 }
00853 return NULL;
00854 }
00855
00856
00857
00858 vtol_edge_2d_sptr
00859 DanglingEdge(vtol_vertex_2d& v)
00860 {
00861 vcl_vector<vtol_edge_sptr> segs; v.edges(segs);
00862
00863 if (segs.size()==1)
00864 return segs[0]->cast_to_edge_2d();
00865 else
00866 return 0;
00867 }
00868
00869
00870
00871
00872 void
00873 MergeEndPtsOfChain(vtol_vertex_2d& endpt, vtol_vertex_2d& other, vtol_edge_2d& common,
00874 vbl_array_2d<vtol_edge_2d_sptr>& edgeMap, vbl_array_2d<vtol_vertex_2d_sptr>&vertexMap)
00875 {
00876 int px = int(other.x()), py = int(other.y());
00877 vertexMap.put(px, py, NULL);
00878 edgeMap.put( px, py, &common);
00879 if (common.v1() == &other)
00880 common.set_v1(&endpt);
00881 else
00882 common.set_v2(&endpt);
00883 }
00884
00885
00886
00887
00888 void
00889 MergeEndPtTouchingEndPt(vtol_vertex_2d& end1, vtol_vertex_2d& end2,
00890 vtol_edge_2d_sptr& merge, vtol_edge_2d_sptr& longer, vtol_edge_2d_sptr& shorter,
00891 vbl_array_2d<vtol_edge_2d_sptr>& edgeMap, vbl_array_2d<vtol_vertex_2d_sptr>& vertexMap)
00892 {
00893
00894 vcl_vector<vtol_edge_sptr> edges;
00895 end1.edges(edges); vtol_edge_2d_sptr edge1 = edges[0]->cast_to_edge_2d();
00896 end2.edges(edges); vtol_edge_2d_sptr edge2 = edges[0]->cast_to_edge_2d();
00897
00898
00899 vdgl_digital_curve_sptr dc1 = edge1->curve()->cast_to_vdgl_digital_curve();
00900 const int l1 = dc1->get_interpolator()->get_edgel_chain()->size();
00901 vdgl_digital_curve_sptr dc2 = edge2->curve()->cast_to_vdgl_digital_curve();
00902 const int l2 = dc2->get_interpolator()->get_edgel_chain()->size();
00903 const int len = l1+l2;
00904
00905 merge = new vtol_edge_2d();
00906
00907 vdgl_edgel_chain *ec = new vdgl_edgel_chain;
00908 vdgl_interpolator *it = new vdgl_interpolator_linear( ec);
00909 vdgl_digital_curve *dc = new vdgl_digital_curve(it);
00910
00911 merge->set_curve(*dc);
00912
00913 vdgl_edgel_chain *cxy= ec;
00914 vtol_vertex_sptr v1, v2;
00915 int k = 0;
00916
00917 vdgl_edgel_chain_sptr cxy1= dc1->get_interpolator()->get_edgel_chain();
00918 if (edge1->v2() == &end1) {
00919 for (int i = 0; i < l1; i++, k++)
00920 {
00921 cxy->add_edgel ( (*cxy1)[i] );
00922 (*cxy)[k] = (*cxy1)[i];
00923 }
00924 v1 = edge1->v1();
00925 } else {
00926 for (int i = l1-1; i >= 0; i--, k++)
00927 {
00928 cxy->add_edgel ( (*cxy1)[i] );
00929 (*cxy)[k] = (*cxy1)[i];
00930 }
00931 v1 = edge1->v2();
00932 }
00933 merge->set_v1(v1.ptr());
00934
00935 vdgl_edgel_chain_sptr cxy2= dc2->get_interpolator()->get_edgel_chain();
00936
00937 if (edge2->v1() == &end2)
00938 {
00939 for (int i = 0; i < l2; i++, k++)
00940 {
00941 cxy->add_edgel ( (*cxy2)[i] );
00942 (*cxy)[k] = (*cxy2)[i];
00943 }
00944
00945 v2 = edge2->v2()->cast_to_vertex_2d();
00946 } else {
00947
00948 for (int i = l2-1; i >= 0; i--, k++)
00949 {
00950 cxy->add_edgel ( (*cxy2)[i] );
00951 (*cxy)[k] = (*cxy2)[i];
00952 }
00953 v2 = edge2->v1()->cast_to_vertex_2d();
00954 }
00955 merge->set_v2(v2.ptr());
00956
00957
00958 vertexMap.put(int(end1.x()), int(end1.y()), NULL);
00959 vertexMap.put(int(end2.x()), int(end2.y()), NULL);
00960 const int last = len-1;
00961 for (k = 1; k < last; k++)
00962 edgeMap.put( int((*cxy)[k].x()), int((*cxy)[k].y()), merge);
00963 if (edgeMap.get( int((*cxy)[0].x()), int((*cxy)[0].y())))
00964 edgeMap.put( int((*cxy)[0].x()), int((*cxy)[0].y()), merge);
00965 if (edgeMap.get( int((*cxy)[last].x()), int((*cxy)[last].y())))
00966 edgeMap.put( int((*cxy)[last].x()), int((*cxy)[last].y()), merge);
00967
00968 if (l1 >= l2)
00969 longer = edge1, shorter = edge2;
00970 else
00971 longer = edge2, shorter = edge1;
00972 }
00973
00974
00975
00976
00977 void
00978 MergeEndPtTouchingJunction(vtol_vertex_2d &endpt, vtol_vertex_2d& junction,
00979 vbl_array_2d<vtol_edge_2d_sptr>& edgeMap, vbl_array_2d<vtol_vertex_2d_sptr>&vertexMap)
00980 {
00981 vcl_vector<vtol_edge_sptr> edges; endpt.edges(edges);
00982 vtol_edge_2d_sptr edge = edges[0]->cast_to_edge_2d();
00983 int px = int(endpt.x()), py = int(endpt.y());
00984 vertexMap.put(px, py, NULL);
00985 edgeMap.put( px, py, edge);
00986 if (edge->v1() == &endpt)
00987 edge->set_v1(&junction);
00988 else
00989 edge->set_v2(&junction);
00990 }
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 int
01004 gevd_contour::FindJunctions(gevd_bufferxy& edgels,
01005 vcl_vector<vtol_edge_2d_sptr>& edges,
01006 vcl_vector<vtol_vertex_2d_sptr >& vertices)
01007 {
01008 #ifdef DEBUG
01009 vul_timer t;
01010 #endif
01011 if (!edges.size())
01012 {
01013 vcl_cerr << "gevd_contour::FindChains must precede gevd_contour::FindJunctions.\n";
01014 return 0;
01015 }
01016 vcl_vector<vtol_edge_2d_sptr>::iterator eit;
01017
01018 for (eit= edges.begin(); eit!=edges.end(); eit++) {
01019 (*eit)->describe(vcl_cout, 2);
01020 }
01021 vcl_vector<vtol_vertex_2d_sptr>::iterator vit;
01022
01023 for (vit= vertices.begin(); vit!=vertices.end(); vit++) {
01024 (*vit)->describe(vcl_cout, 2);
01025 }
01026
01027
01028
01029 const float connect_fuzz = 2;
01030
01031 for (unsigned int i=0; i< edges.size(); i++)
01032 {
01033 vtol_edge_2d_sptr edge = edges[i];
01034 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
01035 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01036
01037 const int last = cxy->size()-1;
01038 if (vcl_fabs((*cxy)[0].x()-(*cxy)[last].x()) > connect_fuzz ||
01039 vcl_fabs((*cxy)[0].y()-(*cxy)[last].y()) > connect_fuzz)
01040 {
01041 int x = int((*cxy)[0].x()), y = int((*cxy)[0].y());
01042
01043 vtol_vertex_2d_sptr v1 = vertexMap->get(x, y);
01044 if (!v1)
01045 {
01046 v1 = new vtol_vertex_2d((*cxy)[0].x(), (*cxy)[0].y());
01047 vertexMap->put(x, y, v1);
01048 LookupTableInsert(vertices, v1);
01049 }
01050 else
01051 {
01052 edgeMap->put( x, y, NULL);
01053 }
01054
01055 edge->set_v1(v1->cast_to_vertex());
01056 x = int((*cxy)[last].x()), y = int((*cxy)[last].y());
01057
01058 vtol_vertex_2d_sptr v2 = vertexMap->get(x, y);
01059
01060 if (!v2)
01061 {
01062 v2 = new vtol_vertex_2d((*cxy)[last].x(), (*cxy)[last].y());
01063 vertexMap->put(x, y, v2);
01064 LookupTableInsert(vertices, v2);
01065 }
01066 else
01067 {
01068 edgeMap->put( x, y, NULL);
01069 }
01070
01071 edge->set_v2(v2->cast_to_vertex());
01072 }
01073 }
01074
01075
01076
01077
01078 int jcycle = 0, jchain = 0;
01079
01080 for (unsigned int i=0; i< vertices.size(); i++)
01081 {
01082 vtol_vertex_2d_sptr end = vertices[i];
01083 vtol_edge_2d_sptr weaker = NULL, stronger = NULL;
01084 int index;
01085 if (DetectJunction(*end, index,
01086 weaker, stronger, maxSpiral,
01087 edgels, *edgeMap)) {
01088 if (!stronger->v1()) {
01089 if (ConfirmJunctionOnCycle(index, minJump,
01090 *stronger, edgels)) {
01091 vtol_edge_2d_sptr split = NULL;
01092 BreakCycle(*end, index,
01093 *stronger,
01094 split,
01095 *edgeMap, *vertexMap);
01096 LookupTableReplace(edges, stronger, split);
01097 jcycle++;
01098 }
01099 } else {
01100 if (ConfirmJunctionOnChain(index, minJump,
01101 *stronger, edgels)) {
01102 if (weaker == stronger) {
01103 vtol_edge_2d_sptr straight = NULL, curled = NULL;
01104 LoopChain(*end, index,
01105 *stronger,
01106 straight, curled,
01107 *edgeMap, *vertexMap);
01108 LookupTableReplace(edges, stronger, straight);
01109 LookupTableInsert(edges, curled);
01110 jchain++;
01111 } else {
01112 vtol_edge_2d_sptr longer = NULL, shorter = NULL;
01113 BreakChain(*end, index,
01114 *stronger,
01115 longer, shorter,
01116 *edgeMap, *vertexMap);
01117 LookupTableReplace(edges, stronger, longer);
01118 LookupTableInsert(edges, shorter);
01119 jchain++;
01120 }
01121 }
01122 }
01123 }
01124 }
01125 #if 0
01126 vcl_cout << "Find junctions with "
01127 << jcycle << " cycles and " << jchain << " chains, with jump > "
01128 << minJump << vcl_endl;
01129 #endif
01130
01131
01132 int dendpt = 0, dchain = 0;
01133
01134 for (unsigned int i=0; i< vertices.size(); i++)
01135 {
01136 vtol_vertex_2d_sptr end1 = vertices[i];
01137 if (end1 &&
01138 NumConnectedRays(*end1) == 1) {
01139 vtol_vertex_2d_sptr end2 = DetectTouch(*end1, maxSpiral, *vertexMap);
01140 if (end2) {
01141 if (NumConnectedRays(*end2) == 1) {
01142 vtol_edge_2d_sptr seg = DanglingEdge(*end1);
01143 if (seg == DanglingEdge(*end2)) {
01144 MergeEndPtsOfChain(*end1, *end2, *seg,
01145 *edgeMap, *vertexMap);
01146 LookupTableRemove(vertices, end2);
01147 dendpt++;
01148 } else {
01149 #if 0
01150 vcl_cout << "endpt1=" << *end1 << vcl_endl
01151 << "endpt2=" << *end2 << vcl_endl;
01152 #endif
01153 vtol_edge_2d_sptr merge=NULL, longer=NULL, shorter=NULL;
01154 MergeEndPtTouchingEndPt(*end1, *end2,
01155 merge, longer, shorter,
01156 *edgeMap, *vertexMap);
01157 #if 0
01158 vcl_cout << "merge=" << *merge << vcl_endl
01159 << "longer=" << *longer << vcl_endl
01160 << "shorter=" << *shorter << vcl_endl
01161 << "merge.v1=" << *merge->v1() << vcl_endl
01162 << "merge.v2=" << *merge->v2() << vcl_endl;
01163 #endif
01164 LookupTableReplace(edges, longer, merge);
01165 LookupTableRemove(edges, shorter);
01166 LookupTableRemove(vertices, end1);
01167 LookupTableRemove(vertices, end2);
01168 dendpt += 2, dchain += 1;
01169 }
01170 } else {
01171 #if 0
01172 vcl_cout << "endpt1=" << *end1 << vcl_endl
01173 << "junction2=" << *end2 << vcl_endl;
01174 #endif
01175 MergeEndPtTouchingJunction(*end1, *end2,
01176 *edgeMap, *vertexMap);
01177 LookupTableRemove(vertices, end1);
01178 dendpt++;
01179 }
01180 }
01181 }
01182 }
01183 #if 0
01184 vcl_cout << "Merge and delete " << dendpt << " end points and " << dchain << " edges\n";
01185 #endif
01186 if (dchain)
01187 LookupTableCompress(edges);
01188 if (dendpt)
01189 LookupTableCompress(vertices);
01190
01191
01192 int ncycle = 0;
01193 for (unsigned int i=0; i< edges.size(); ++i)
01194 {
01195 vtol_edge_2d_sptr edge = edges[i];
01196 if (!edge->v1()) {
01197 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
01198 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01199
01200 const int last = cxy->size()-1;
01201 vtol_vertex_2d_sptr v = new vtol_vertex_2d(((*cxy)[0].x()+(*cxy)[last].x())/2, ((*cxy)[0].y()+(*cxy)[last].y())/2);
01202 edge->set_v1(v->cast_to_vertex()); edge->set_v2(v->cast_to_vertex());
01203 vertexMap->put(int(v->x()), int(v->y()), v);
01204 LookupTableInsert(vertices, v);
01205 ncycle++;
01206 }
01207 }
01208 #if 0
01209 vcl_cout << "Create " << ncycle << " virtual end points for isolated cycles.\n";
01210 #endif
01211 #ifdef DEBUG
01212 if (talkative)
01213 vcl_cout << "All junctions found in " << t.real() << " msecs.\n";
01214 #endif
01215 return vertices.size();
01216 }
01217
01218
01219
01220
01221
01222
01223
01224 void
01225 gevd_contour::SubPixelAccuracy(vcl_vector<vtol_edge_2d_sptr>& edges,
01226 vcl_vector<vtol_vertex_2d_sptr >& vertices,
01227 const gevd_bufferxy& locationx,
01228 const gevd_bufferxy& locationy)
01229 {
01230 #ifdef DEBUG
01231 vul_timer t;
01232 #endif
01233 if (talkative)
01234 vcl_cout << "Insert subpixel accuracy into edges/vertices";
01235
01236
01237 for (unsigned int i=0; i< vertices.size(); ++i)
01238 {
01239 vtol_vertex_2d_sptr vert = vertices[i];
01240 int x = int(vert->x()), y = int(vert->y());
01241 vert->set_x(x + floatPixel(locationx, x, y));
01242 vert->set_y(y + floatPixel(locationy, x, y));
01243 }
01244
01245
01246 for (unsigned int i=0; i< edges.size(); ++i)
01247 {
01248 vtol_edge_2d_sptr edge = edges[i];
01249 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
01250 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01251
01252 for (unsigned int k = 0; k < cxy->size(); ++k)
01253 {
01254 int x = int((*cxy)[k].x()), y = int((*cxy)[k].y());
01255
01256 double tempx= (*cxy)[k].x()+ floatPixel( locationx, x, y);
01257 double tempy= (*cxy)[k].y()+ floatPixel( locationy, x, y);
01258 (*cxy)[k].set_x( tempx);
01259 (*cxy)[k].set_y( tempy);
01260 }
01261 }
01262
01263
01264
01265
01266
01267
01268
01269 #ifdef DEBUG
01270 if (talkative)
01271 vcl_cout << ", in " << t.real() << " msecs.\n";
01272 #endif
01273 }
01274
01275
01276
01277
01278
01279 static vtol_edge_2d_sptr DigitalEdge(vtol_vertex_2d_sptr vs, vtol_vertex_2d_sptr ve)
01280 {
01281 double xs= vs->x();
01282 double ys= vs->y();
01283 double xe= ve->x();
01284 double ye= ve->y();
01285
01286 vdgl_edgel_chain *es= new vdgl_edgel_chain;
01287 vdgl_interpolator *it= new vdgl_interpolator_linear( es);
01288 vdgl_digital_curve *dc= new vdgl_digital_curve( it);
01289
01290 es->add_edgel( vdgl_edgel( xs, ys));
01291 es->add_edgel( vdgl_edgel( xe, ye));
01292
01293 vtol_edge_2d_sptr e = new vtol_edge_2d(vs, ve, vsol_curve_2d_sptr(dc));
01294 return e;
01295 }
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310 void
01311 gevd_contour::InsertBorder(vcl_vector<vtol_edge_2d_sptr>& edges,
01312 vcl_vector<vtol_vertex_2d_sptr >& vertices)
01313 {
01314 #ifdef DEBUG
01315 vul_timer t;
01316 #endif
01317
01318 vcl_vector<vtol_vertex_2d_sptr > xmin_verts;
01319 vcl_vector<vtol_vertex_2d_sptr > xmax_verts;
01320 vcl_vector<vtol_vertex_2d_sptr > ymin_verts;
01321 vcl_vector<vtol_vertex_2d_sptr > ymax_verts;
01322
01323 if (talkative)
01324 vcl_cout << "Insert virtual border to enforce closure";
01325
01326
01327 const int rmax = FRAME;
01328 const int xmax = vertexMap->rows()-rmax-1;
01329 const int ymax = vertexMap->columns()-rmax-1;
01330 int cx[] = {rmax, xmax, rmax, xmax};
01331 int cy[] = {rmax, ymax, ymax, rmax};
01332
01333
01334
01335 vtol_vertex_2d_sptr V00 = new vtol_vertex_2d(rmax, rmax);
01336 vtol_vertex_2d_sptr V01 = new vtol_vertex_2d(rmax, ymax);
01337 vtol_vertex_2d_sptr V10 = new vtol_vertex_2d(xmax, rmax);
01338 vtol_vertex_2d_sptr V11 = new vtol_vertex_2d(xmax, ymax);
01339 xmin_verts.push_back(V00);
01340 xmax_verts.push_back(V10);
01341 ymin_verts.push_back(V00);
01342 ymax_verts.push_back(V01);
01343
01344 for (int d = 0; d < 2; d++)
01345 {
01346 int y = cy[d];
01347 for (int x = rmax; x<=xmax; ++x)
01348 {
01349 vtol_vertex_2d_sptr v = vertexMap->get(x, y);
01350 if (v)
01351 vertexMap->put(x, y, NULL);
01352 else continue;
01353 if (d)
01354 ymax_verts.push_back(v);
01355 else
01356 ymin_verts.push_back(v);
01357 }
01358 }
01359
01360 for (int d = 0; d < 2; d++)
01361 {
01362 int x = cx[d];
01363 for (int y = rmax; y<=ymax; y++)
01364 {
01365 vtol_vertex_2d_sptr v = vertexMap->get(x, y);
01366 if (v)
01367 vertexMap->put(x, y, NULL);
01368 else continue;
01369 if (d)
01370 xmax_verts.push_back(v);
01371 else
01372 xmin_verts.push_back(v);
01373 }
01374 }
01375
01376 xmin_verts.push_back(V01);
01377 xmax_verts.push_back(V11);
01378 ymin_verts.push_back(V10);
01379 ymax_verts.push_back(V11);
01380
01381
01382
01383 for (int d = 0; d < 2; d++)
01384 {
01385 vcl_vector<vtol_vertex_2d_sptr >* verts = &ymin_verts;
01386 if (d)
01387 verts = &ymax_verts;
01388 int len = (*verts).size();
01389 if (len<3) continue;
01390
01391 vtol_vertex_2d_sptr pre_v = (*verts)[0];
01392 vtol_vertex_2d_sptr v = (*verts)[1];
01393 int x = int(v->x());
01394 int pre_x = int(pre_v->x());
01395 if ((x-pre_x)<3)
01396 {
01397 #if 0 //GEOFF
01398 merge_references(pre_v,v);
01399 #endif
01400 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= verts->begin(); it!= verts->end(); ++it)
01401 {
01402 if (*it == v)
01403 {
01404 verts->erase(it);
01405 break;
01406 }
01407 }
01408 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= vertices.begin(); it!= vertices.end(); ++it)
01409 {
01410 if (*it == v)
01411 {
01412 vertices.erase(it);
01413 break;
01414 }
01415 }
01416 len--;
01417 }
01418
01419 pre_v = (*verts)[len-2];
01420 v = (*verts)[len-1];
01421 pre_x = int(pre_v->x());
01422 if ((xmax+rmax-pre_x)<3)
01423 {
01424 #if 0 //GEOFF
01425 merge_references(v,pre_v);
01426 #endif
01427 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= verts->begin(); it!= verts->end(); ++it)
01428 {
01429 if (*it == pre_v)
01430 {
01431 verts->erase(it);
01432 break;
01433 }
01434 }
01435 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= vertices.begin(); it!= vertices.end(); ++it)
01436 {
01437 if (*it == pre_v)
01438 {
01439 vertices.erase(it);
01440 break;
01441 }
01442 }
01443 len--;
01444 }
01445 }
01446
01447
01448 for (int d = 0; d < 2; d++)
01449 {
01450 vcl_vector<vtol_vertex_2d_sptr >* verts = &xmin_verts;
01451 if (d)
01452 verts = &xmax_verts;
01453 int len = (*verts).size();
01454 if (len<3) continue;
01455
01456 vtol_vertex_2d_sptr pre_v = (*verts)[0];
01457 vtol_vertex_2d_sptr v = (*verts)[1];
01458
01459
01460 int y = int(v->y()), pre_y = int(pre_v->y());
01461 if ((y-pre_y)<3)
01462 {
01463 #if 0 //GEOFF
01464 merge_references(pre_v,v);
01465 #endif
01466 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= verts->begin(); it!= verts->end(); ++it)
01467 {
01468 if (*it == v)
01469 {
01470 verts->erase( it);
01471 break;
01472 }
01473 }
01474 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= vertices.begin(); it!= vertices.end(); ++it)
01475 {
01476 if (*it == v)
01477 {
01478 vertices.erase( it);
01479 break;
01480 }
01481 }
01482 len--;
01483 }
01484
01485 pre_v = (*verts)[len-2];
01486 v = (*verts)[len-1];
01487 pre_y = int(pre_v->y());
01488 if ((ymax+rmax-pre_y)<3)
01489 {
01490 #if 0 //GEOFF
01491 merge_references(v,pre_v);
01492 #endif
01493 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= verts->begin(); it!= verts->end(); ++it)
01494 {
01495 if (*it == pre_v)
01496 {
01497 verts->erase( it);
01498 break;
01499 }
01500 }
01501 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= vertices.begin(); it!= vertices.end(); ++it)
01502 {
01503 if (*it == pre_v)
01504 {
01505 vertices.erase( it);
01506 break;
01507 }
01508 }
01509 len--;
01510 }
01511 }
01512
01513 int iv, len = xmin_verts.size();
01514 float xmi = 0, xmx = float(xmax + rmax);
01515 float ymi = 0, ymx = float(ymax + rmax);
01516 for (iv=1; iv<len-1; iv++)
01517 {
01518 vtol_vertex_2d_sptr v = xmin_verts[iv];
01519 vtol_vertex_2d_sptr vp = new vtol_vertex_2d(xmi, v->y());
01520 vertices.push_back(vp);
01521 xmin_verts[iv] = vp;
01522
01523
01524 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
01525 edges.push_back(e);
01526 }
01527
01528 len = xmax_verts.size();
01529 for (iv=0; iv<len; iv++)
01530 {
01531 vtol_vertex_2d_sptr v = xmax_verts[iv];
01532 if (iv!=0&&iv!=(len-1))
01533 {
01534 vtol_vertex_2d_sptr vp = new vtol_vertex_2d( xmx, v->y());
01535 vertices.push_back(vp);
01536 xmax_verts[iv] = vp;
01537 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
01538 edges.push_back(e);
01539 }
01540 }
01541 len = ymin_verts.size();
01542 for (iv=0; iv<len; iv++)
01543 {
01544 vtol_vertex_2d_sptr v = ymin_verts[iv];
01545 if (iv!=0&&iv!=(len-1))
01546 {
01547 vtol_vertex_2d_sptr vp = new vtol_vertex_2d(v->x(), ymi);
01548 vertices.push_back(vp);
01549 ymin_verts[iv] = vp;
01550 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
01551 edges.push_back(e);
01552 }
01553 }
01554 len = ymax_verts.size();
01555 for (iv=0; iv<len; iv++)
01556 {
01557 vtol_vertex_2d_sptr v = ymax_verts[iv];
01558 if (iv!=0&&iv!=(len-1))
01559 {
01560 vtol_vertex_2d_sptr vp = new vtol_vertex_2d( v->x(), ymx);
01561 vertices.push_back(vp);
01562 ymax_verts[iv] = vp;
01563 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
01564 edges.push_back(e);
01565 }
01566 }
01567 V00->set_x(0); V00->set_y(0); vertices.push_back(V00);
01568 V01->set_x(0); V01->set_y(ymax+rmax); vertices.push_back(V01);
01569 V10->set_x(xmax+rmax); V10->set_y(0); vertices.push_back(V10);
01570 V11->set_x(xmax+rmax); V11->set_y(ymax+rmax); vertices.push_back(V11);
01571
01572
01573
01574
01575 for (int d = 0; d < 2; d++)
01576 {
01577 vcl_vector<vtol_vertex_2d_sptr >* verts = &ymin_verts;
01578 if (d)
01579 verts = &ymax_verts;
01580 int len = (*verts).size();
01581 if (len<2)
01582 {
01583 vcl_cout <<"In gevd_contour::InsertBorder() - too few vertices\n";
01584 return;
01585 }
01586 for (int i = 0; i<len-1; i++)
01587 {
01588 vtol_vertex_2d_sptr v = (*verts)[i];
01589 vtol_vertex_2d_sptr vp = (*verts)[i+1];
01590 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
01591 edges.push_back(e);
01592 }
01593 }
01594
01595 for (int d = 0; d < 2; d++)
01596 {
01597 vcl_vector<vtol_vertex_2d_sptr >* verts = &xmin_verts;
01598 if (d)
01599 verts = &xmax_verts;
01600 int len = (*verts).size();
01601 if (len<2)
01602 {
01603 vcl_cout <<"In gevd_contour::InsertBorder() - too few vertices\n";
01604 return;
01605 }
01606 for (int i = 0; i<len-1; i++)
01607 {
01608 vtol_vertex_2d_sptr v = (*verts)[i];
01609 vtol_vertex_2d_sptr vp = (*verts)[i+1];
01610 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
01611 edges.push_back(e);
01612 }
01613 }
01614 #ifdef DEBUG
01615 if (talkative)
01616 vcl_cout << ", in " << t.real() << " msecs.\n";
01617 #endif
01618 }
01619
01620
01621
01622
01623
01624
01625
01626 static void
01627 EqualizeElements(double* elmts, int n, double v1, double v2)
01628 {
01629 double p0 = elmts[0], p1 = elmts[1], p2 = elmts[2];
01630 elmts[0] = (v1 + p1) / 2;
01631 for (int i = 1; i < n-2; i++) {
01632 elmts[i] = (p0 + p2)/2;
01633 p0 = p1; p1 = p2; p2 = elmts[i+2];
01634 }
01635 if (n>1) elmts[n-2] = (p0 + p2)/2;
01636 if (n>0) elmts[n-1] = (p1 + v2)/2;
01637 }
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 void
01651 gevd_contour::EqualizeSpacing(vcl_vector<vtol_edge_2d_sptr>& chains)
01652 {
01653 #ifdef DEBUG
01654 vul_timer t;
01655 #endif
01656 if (talkative)
01657 vcl_cout << "Equalize the spacing between pixels in chains";
01658
01659 for (unsigned int i= 0; i< chains.size(); i++)
01660 {
01661 vtol_edge_2d_sptr e = chains[i];
01662 vdgl_digital_curve_sptr dc = e->curve()->cast_to_vdgl_digital_curve();
01663 const int len = dc->get_interpolator()->get_edgel_chain()->size();
01664 if (len > 2*MINLENGTH)
01665 {
01666 vtol_vertex_sptr v1 = e->v1(), v2 = e->v2();
01667
01668 vcl_vector<double> cx(len);
01669 vcl_vector<double> cy(len);
01670
01671 for (int qq=0; qq<len; qq++)
01672 {
01673 vdgl_edgel e= dc->get_interpolator()->get_edgel_chain()->edgel( qq);
01674 cx[qq]= e.x();
01675 cy[qq]= e.y();
01676 }
01677
01678 EqualizeElements(&cx[0], len, v1->cast_to_vertex_2d()->x(), v2->cast_to_vertex_2d()->x());
01679 EqualizeElements(&cy[0], len, v1->cast_to_vertex_2d()->y(), v2->cast_to_vertex_2d()->y());
01680
01681 for (int qq=0; qq<len; qq++)
01682 {
01683 vdgl_edgel e( cx[qq], cy[qq]);
01684 dc->get_interpolator()->get_edgel_chain()->set_edgel( qq, e);
01685 }
01686 }
01687 }
01688 #ifdef DEBUG
01689 if (talkative)
01690 vcl_cout << ", in " << t.real() << " msecs.\n";
01691 #endif
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701 void
01702 gevd_contour::Translate(vcl_vector<vtol_edge_2d_sptr>& edges,
01703 vcl_vector<vtol_vertex_2d_sptr >& vertices,
01704 const float tx, const float ty)
01705 {
01706 #ifdef DEBUG
01707 vul_timer t;
01708 #endif
01709 if (talkative)
01710 vcl_cout << "Translate edges/vertices";
01711 for (unsigned int i=0; i< vertices.size(); i++) {
01712 vtol_vertex_2d_sptr vert = vertices[i];
01713 vert->set_x(vert->x() + tx);
01714 vert->set_y(vert->y() + ty);
01715 }
01716 for (unsigned int i=0; i< edges.size(); i++) {
01717 vtol_edge_2d_sptr edge = edges[i];
01718 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
01719
01720 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01721 for (unsigned int k = 0; k < cxy->size(); ++k) {
01722 vdgl_edgel e= (*cxy)[k];
01723
01724 e.set_x( e.x()+tx);
01725 e.set_y( e.y()+ty);
01726
01727 cxy->set_edgel( k, e);
01728 }
01729 }
01730 #ifdef DEBUG
01731 if (talkative)
01732 vcl_cout << ", in " << t.real() << " msecs.\n";
01733 #endif
01734 }
01735
01736
01737
01738
01739
01740
01741 void
01742 gevd_contour::ClearNetwork(vcl_vector<vtol_edge_2d_sptr>*& edges,
01743 vcl_vector<vtol_vertex_2d_sptr >*& vertices)
01744 {
01745 if (edges) {
01746 for (unsigned int i=0; i< edges->size(); ++i) {
01747 #if 0 // not (yet) converted
01748 vtol_edge_2d_sptr edge = (*edges)[i];
01749 Curve* dc = NULL;
01750 vsol_curve_2d *dc= 0;
01751 #if 0 //GEOFF
01752 edge->set_curve(0);
01753 #endif
01754 edge->UnProtect();
01755 delete (vdgl_digital_curve *) dc;
01756 #endif
01757 }
01758 delete edges; edges = NULL;
01759 }
01760 if (vertices) {
01761 #if 0
01762 for (vertices->reset(); vertices->next(); )
01763 for (unsigned int i=0; i< vertices->size(); ++i)
01764 vertices[i]->UnProtect();
01765 #endif
01766 delete vertices; vertices = NULL;
01767 }
01768 }
01769
01770
01771
01772
01773 void
01774 gevd_contour::MaskEdgels(const gevd_bufferxy& mask,
01775 gevd_bufferxy& edgels,
01776 int& njunction,
01777 int* junctionx, int* junctiony)
01778 {
01779 int x, y;
01780 for (y = 0; y < edgels.GetSizeY(); y++)
01781 for (x = 0; x < edgels.GetSizeX(); x++)
01782 if (floatPixel(edgels, x, y) &&
01783 !bytePixel(mask, x, y))
01784 floatPixel(edgels, x, y) = 0;
01785 int j = 0;
01786 for (int i = 0; i < njunction; i++) {
01787 x = junctionx[i], y = junctiony[i];
01788 if (bytePixel(mask, x, y)) {
01789 junctionx[j] = x, junctiony[j] = y, j++;
01790 }
01791 }
01792 njunction = j;
01793 }
01794
01795
01796
01797
01798
01799
01800
01801 void
01802 gevd_contour::SetEdgelData(gevd_bufferxy& grad_mag, gevd_bufferxy& angle, vcl_vector<vtol_edge_2d_sptr>& edges)
01803 {
01804 for (unsigned int i=0; i< edges.size(); i++)
01805 {
01806 vtol_edge_2d_sptr e = edges[i];
01807 vdgl_digital_curve_sptr dc= e->curve()->cast_to_vdgl_digital_curve();
01808
01809 if (dc)
01810 {
01811 vdgl_edgel_chain_sptr xypos= dc->get_interpolator()->get_edgel_chain();
01812
01813 int len = xypos->size();
01814
01815 for (int i = 0; i < len; i++)
01816 {
01817 int ix = int((*xypos)[i].x());
01818 int iy = int((*xypos)[i].y());
01819
01820
01821
01822 if (iy < 0 || ix < 0 ||
01823 ix >= grad_mag.GetSizeX() ||
01824 iy >= grad_mag.GetSizeY())
01825 {
01826 vcl_cerr << "*********** ERROR : (ix, iy) = ("
01827 << ix << ", " << iy << ")\n";
01828 if (ix < 0) ix = 0;
01829 if (iy < 0) iy = 0;
01830 if (ix >= grad_mag.GetSizeX()) ix = grad_mag.GetSizeX()-1;
01831 if (iy >= grad_mag.GetSizeY()) iy = grad_mag.GetSizeY()-1;
01832 }
01833
01834 vdgl_edgel edgel= xypos->edgel(i);
01835 edgel.set_grad( floatPixel( grad_mag, ix, iy));
01836 edgel.set_theta( floatPixel( angle, ix, iy));
01837
01838 #if 0
01839 gr[i] = floatPixel(grad_mag, ix, iy);
01840 th[i] = floatPixel(angle, ix, iy);
01841 #endif
01842 }
01843 }
01844 }
01845 }
01846
01847
01848
01849 int
01850 gevd_contour::LengthCmp(vtol_edge_2d_sptr const& dc1, vtol_edge_2d_sptr const& dc2)
01851 {
01852 vdgl_digital_curve_sptr c1 = ((vtol_edge_2d_sptr)dc1)->curve()->cast_to_vdgl_digital_curve();
01853 vdgl_digital_curve_sptr c2 = ((vtol_edge_2d_sptr)dc2)->curve()->cast_to_vdgl_digital_curve();
01854 return c2->get_interpolator()->get_edgel_chain()->size() - c1->get_interpolator()->get_edgel_chain()->size();
01855 }
01856
01857
01858
01859 vcl_vector<vtol_edge_2d_sptr>*
01860 gevd_contour::CreateLookupTable(vcl_vector<vtol_edge_2d_sptr>& set)
01861 {
01862 vcl_vector<vtol_edge_2d_sptr>* set2 =
01863 new vcl_vector<vtol_edge_2d_sptr>(2*set.size());
01864 for (unsigned int i=0; i< set.size(); i++)
01865 gevd_contour::LookupTableInsert(*set2, set[i]);
01866 return set2;
01867 }
01868
01869
01870 vcl_vector<vtol_vertex_2d_sptr >*
01871 gevd_contour::CreateLookupTable(vcl_vector<vtol_vertex_2d_sptr >& set)
01872 {
01873 vcl_vector<vtol_vertex_2d_sptr >* set2 =
01874 new vcl_vector<vtol_vertex_2d_sptr >(2*set.size());
01875 for (unsigned int i=0; i< set.size(); i++)
01876 gevd_contour::LookupTableInsert(*set2, set[i]);
01877 return set2;
01878 }
01879
01880
01881
01882
01883
01884 void
01885 gevd_contour::LookupTableInsert(vcl_vector<vtol_edge_2d_sptr>& set,
01886 vtol_edge_2d_sptr elmt)
01887 {
01888 elmt->set_id(set.size());
01889 set.push_back(elmt);
01890 }
01891
01892
01893
01894 void
01895 gevd_contour::LookupTableInsert(vcl_vector<vtol_vertex_2d_sptr >& set,
01896 vtol_vertex_2d_sptr elmt)
01897 {
01898 elmt->set_id(set.size());
01899 set.push_back(elmt);
01900 }
01901
01902
01903
01904
01905 void
01906 gevd_contour::LookupTableReplace(vcl_vector<vtol_edge_2d_sptr>& set,
01907 vtol_edge_2d_sptr deleted, vtol_edge_2d_sptr inserted)
01908 {
01909 const int i = deleted->get_id();
01910 inserted->set_id(i);
01911 set[i] = inserted;
01912 #if 0 //GEOFF
01913 deleted->unlink_all_inferiors_twoway(deleted);
01914 #endif
01915 }
01916
01917
01918
01919 void
01920 gevd_contour::LookupTableReplace(vcl_vector<vtol_vertex_2d_sptr >& set,
01921 vtol_vertex_2d_sptr deleted, vtol_vertex_2d_sptr inserted)
01922 {
01923 const int i = deleted->get_id();
01924 inserted->set_id(i);
01925 set[i] = inserted;
01926 }
01927
01928
01929
01930
01931 void
01932 gevd_contour::LookupTableRemove(vcl_vector<vtol_edge_2d_sptr>& set,
01933 vtol_edge_2d_sptr elmt)
01934 {
01935 set[elmt->get_id()] = NULL;
01936 }
01937
01938
01939
01940 void
01941 gevd_contour::LookupTableRemove(vcl_vector<vtol_vertex_2d_sptr >& set,
01942 vtol_vertex_2d_sptr elmt)
01943 {
01944 set[elmt->get_id()] = NULL;
01945 }
01946
01947
01948
01949 void
01950 gevd_contour::LookupTableCompress(vcl_vector<vtol_edge_2d_sptr>& set)
01951 {
01952 int i = 0;
01953 for (int j = set.size()-1; i <= j; i++)
01954 if (!set[i]) {
01955 vtol_edge_2d_sptr last = NULL;
01956 for (; i < j; j--)
01957 if (set[j]) {
01958 last = set[j]; j--;
01959 break;
01960 }
01961 if (last) {
01962 last->set_id(i);
01963 set[i] = last;
01964 } else
01965 break;
01966 }
01967 set.resize(i - 1);
01968 }
01969
01970
01971
01972 void
01973 gevd_contour::LookupTableCompress(vcl_vector<vtol_vertex_2d_sptr >& set)
01974 {
01975 int i = 0;
01976 for (int j = set.size()-1; i <= j; i++)
01977 if (!set[i]) {
01978 vtol_vertex_2d_sptr last = NULL;
01979 for (; i < j; j--)
01980 if (set[j]) {
01981 last = set[j]; j--;
01982 break;
01983 }
01984 if (last) {
01985 last->set_id(i);
01986 set[i] = last;
01987 } else
01988 break;
01989 }
01990 set.resize(i - 1);
01991 }
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004 int
02005 gevd_contour::CheckInvariants(vcl_vector<vtol_edge_2d_sptr>& edges,
02006 vcl_vector<vtol_vertex_2d_sptr >& vertices)
02007 {
02008 int nerror = 0;
02009
02010
02011 const int unmark = -1;
02012 for (unsigned int i=0; i< edges.size(); i++)
02013 edges[i]->set_id(unmark);
02014 for (unsigned int i=0; i< vertices.size(); i++)
02015 vertices[i]->set_id(unmark);
02016 for (unsigned int i=0; i< edges.size(); i++) {
02017 vtol_edge_2d_sptr e = edges[i];
02018 vtol_vertex_sptr v1 = e->v1();
02019 if (v1->get_id() != unmark) {
02020 vcl_cout << *v1 << ": v1 is not in vertex list\n";
02021 nerror++;
02022 }
02023 vtol_vertex_sptr v2 = e->v2();
02024 if (v2->get_id() != unmark) {
02025 vcl_cout << *v2 << ": v2 is not in vertex list\n";
02026 nerror++;
02027 }
02028 }
02029 for (unsigned int i=0; i< vertices.size(); i++) {
02030 vcl_vector<vtol_edge_sptr> es; vertices[i]->edges(es);
02031 for (unsigned int j=0; j< es.size(); j++)
02032 if (es[j]->get_id() != unmark) {
02033 vcl_cout << es[j] << ": e is not in edge list\n";
02034 nerror++;
02035 }
02036 }
02037
02038 for (unsigned int id=0; id< edges.size(); id++)
02039 edges[id]->set_id(id);
02040 for (unsigned int id=0; id< vertices.size(); id++)
02041 vertices[id]->set_id(id);
02042
02043 return nerror;
02044 }
02045