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