00001
00002 #include "sdet_contour.h"
00003
00004
00005 #include <vcl_iostream.h>
00006 #include <vcl_cstdlib.h>
00007 #include <vcl_vector.h>
00008 #include <vcl_cmath.h>
00009 #include <vcl_algorithm.h>
00010 #include <vul/vul_timer.h>
00011 #include <vxl_config.h>
00012 #include <vnl/vnl_math.h>
00013 #include <vdgl/vdgl_digital_curve_sptr.h>
00014 #include <vdgl/vdgl_digital_curve.h>
00015 #include <vdgl/vdgl_edgel_chain_sptr.h>
00016 #include <vdgl/vdgl_edgel_chain.h>
00017 #include <vdgl/vdgl_interpolator.h>
00018 #include <vdgl/vdgl_interpolator_linear.h>
00019 #include <vtol/vtol_vertex_2d.h>
00020 #include <vtol/vtol_edge_2d.h>
00021 #include <btol/btol_vertex_algs.h>
00022 #include <btol/btol_edge_algs.h>
00023 #include <bdgl/bdgl_curve_algs.h>
00024 #include <gevd/gevd_bufferxy.h>
00025 #include <gevd/gevd_pixel.h>
00026
00027 #ifdef DEBUG
00028 bool sdet_contour::talkative_ = true;
00029 bool sdet_contour::debug_ = true;
00030 #else
00031 bool sdet_contour::talkative_ = false;
00032 bool sdet_contour::debug_ = false;
00033 #endif
00034
00035 const int INVALID = -1;
00036
00037
00038
00039 const vxl_byte TWOPI = 8, HALFPI = 2 ;
00040
00041 const int DIS[] = { 1, 1, 0,-1,-1,-1, 0, 1,
00042 1, 1, 0,-1,-1,-1, 0, 1,
00043 1, 1, 0,-1,-1,-1, 0, 1};
00044 const int DJS[] = { 0, 1, 1, 1, 0,-1,-1,-1,
00045 0, 1, 1, 1, 0,-1,-1,-1,
00046 0, 1, 1, 1, 0,-1,-1,-1};
00047
00048
00049 const int RIS[] = { 1, 0,-1, 0,
00050 1,-1,-1, 1,
00051 2, 0,-2, 0,
00052 2, 1,-1,-2,
00053 -2,-1, 1, 2,
00054 2,-2,-2, 2,
00055 3, 0,-3, 0,
00056 3, 1,-1,-3,
00057 -3,-1, 1, 3,
00058 3, 2,-2,-3,
00059 -3,-2, 2, 3,
00060 4, 0,-4, 0};
00061 const int RJS[] = { 0, 1, 0,-1,
00062 1, 1,-1,-1,
00063 0, 2, 0,-2,
00064 1, 2, 2, 1,
00065 -1,-2,-2,-1,
00066 2, 2,-2,-2,
00067 0, 3, 0,-3,
00068 1, 3, 3, 1,
00069 -1,-3,-3,-1,
00070 2, 3, 3, 2,
00071 -2,-3,-3,-2,
00072 0, 4, 0,-4};
00073 const int RNS[] = { 4, 8, 12, 20, 24, 28, 36, 44, 48};
00074 const float RGS[] = { 1.f, 1.414213f, 2.f, 2.236067f, 2.828427f,
00075 3.f, 3.162277f, 3.605551f, 4.f};
00076
00077
00078 const int MINLENGTH = 3;
00079 const int FRAME = 4;
00080
00081
00082
00083 struct sdet_contour_edge
00084 {
00085 sdet_contour_edge () {}
00086
00087 void set_edge(vtol_edge_2d_sptr const& e) {e_ = e;}
00088 vtol_edge_2d_sptr edge() {return e_;}
00089
00090 double length() {return e_->curve()->length();}
00091
00092 private:
00093 vtol_edge_2d_sptr e_;
00094 };
00095
00096
00097 static int compare(sdet_contour_edge* ea,
00098 sdet_contour_edge* eb)
00099 {
00100 if (ea->length() < eb->length())
00101 return +1;
00102 return -1;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 sdet_contour::sdet_contour(float min_strength, int min_length,
00114 float min_jump, float max_gap_in)
00115 : minStrength(min_strength), minLength(min_length),
00116 minJump(min_jump), maxSpiral(0),
00117 edgeMap(), vertexMap()
00118 {
00119 if (minStrength < 0)
00120 {
00121 vcl_cerr << "sdet_contour::sdet_contour -- negative min_strength: "
00122 << minStrength << ". Reset to 0.\n";
00123 minStrength = 0;
00124 }
00125 if (minLength < MINLENGTH)
00126 {
00127 vcl_cerr << "sdet_contour::sdet_contour -- too small min_length: "
00128 << minLength << ". Reset to " << MINLENGTH << ".\n";
00129 minLength = MINLENGTH;
00130 }
00131 if (minJump < 0)
00132 {
00133 vcl_cerr << "sdet_contour::sdet_contour -- negative min_jump: "
00134 << minJump << ". Reset to 0.\n";
00135 minJump = 0;
00136 }
00137 if (minJump > minStrength)
00138 {
00139 vcl_cerr << "sdet_contour::sdet_contour -- too large min_jump: "
00140 << min_jump << ". Reset to " << minStrength << ".\n";
00141 minJump = minStrength;
00142 }
00143 if (max_gap_in < 1)
00144 {
00145 vcl_cerr << "sdet_contour::sdet_contour -- too small max_gap: "
00146 << max_gap_in << ". Reset to 1.\n";
00147 max_gap_in = 1;
00148 }
00149 if (max_gap_in > FRAME)
00150 {
00151 vcl_cerr << "sdet_contour::sdet_contour -- too large max_gap: "
00152 << max_gap_in << ". Reset to " << FRAME << vcl_endl;
00153 max_gap_in = FRAME;
00154 }
00155 max_gap = max_gap_in;
00156 for (int i = 0; i < 9; i++)
00157 if (max_gap <= RGS[i])
00158 maxSpiral= i+1;
00159 }
00160
00161
00162
00163 sdet_contour::~sdet_contour()
00164 {
00165 delete edgeMap;
00166 delete vertexMap;
00167 }
00168
00169
00170
00171
00172
00173
00174 bool
00175 sdet_contour::FindNetwork(gevd_bufferxy& edgels, bool junctionp,
00176 const int njunction,
00177 const int* junctionx, const int* junctiony,
00178 vcl_vector<vtol_edge_2d_sptr>*& edges,
00179 vcl_vector<vtol_vertex_2d_sptr >*& vertices)
00180 {
00181
00182
00183 if (!edges)
00184 edges = new vcl_vector<vtol_edge_2d_sptr>;
00185 else
00186 edges->clear();
00187 if (!vertices)
00188 vertices = new vcl_vector<vtol_vertex_2d_sptr >;
00189 else
00190 vertices->clear();
00191
00192
00193 if (this->talkative_)
00194 vcl_cout << "*** Link edge elements into connected edges/vertices.\n";
00195
00196
00197 vertexMap = new vbl_array_2d<vtol_vertex_2d_sptr>(edgels.GetSizeX(), edgels.GetSizeY());
00198 vertexMap->fill(NULL);
00199 edgeMap = new vbl_array_2d<vtol_edge_2d_sptr>(edgels.GetSizeX(), edgels.GetSizeY());
00200 edgeMap->fill(NULL);
00201
00202
00203 int n;
00204
00205 vcl_vector<vtol_edge_2d_sptr> *edges2 = new vcl_vector<vtol_edge_2d_sptr>;
00206 n = this->FindChains(edgels,
00207 njunction,
00208 junctionx, junctiony,
00209 *edges2);
00210 if (!n)
00211 return false;
00212 if (junctionp) {
00213
00214 if (edges2->size() < 10000)
00215 {
00216 sdet_contour_edge* edge_array = new sdet_contour_edge[edges2->size()];
00217 int i =0;
00218 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges2->begin();
00219 eit != edges2->end(); eit++,i++)
00220 {
00221 edge_array[i].set_edge(*eit);
00222 }
00223 vcl_qsort(edge_array, i, sizeof(sdet_contour_edge) ,
00224 (int (*)(const void *, const void *))&compare);
00225 edges2->clear();
00226 for (int j = 0; j<i; j++)
00227 edges2->push_back(edge_array[j].edge());
00228 delete [] edge_array;
00229 }
00230
00231
00232 for (unsigned int i= 0; i< edges2->size(); i++)
00233 (*edges2)[i]->set_id(i);
00234
00235
00236
00237 vcl_vector<vtol_vertex_2d_sptr > vertices2;
00238
00239 this->FindJunctions(edgels,
00240 *edges2, vertices2);
00241 for (unsigned int i=0; i< vertices2.size(); i++)
00242 vertices->push_back( vertices2[i]);
00243 }
00244
00245
00246 for (unsigned int i= 0; i< edges2->size(); i++)
00247 edges->push_back( (*edges2)[i]);
00248
00249
00250 edges2->clear();
00251 delete edges2;
00252
00253 return true;
00254 }
00255
00256
00257
00258 static bool
00259 on_contour(const gevd_bufferxy& edgels, const int i, const int j)
00260 {
00261 double pix = (1 + vnl_math::sqrt2) * floatPixel(edgels, i, j);
00262 for (vxl_byte dir = 0; dir < TWOPI; dir += HALFPI)
00263 if (floatPixel(edgels, i+DIS[dir], j+DJS[dir]) > pix)
00264 return false;
00265 return true;
00266 }
00267
00268
00269
00270 static void
00271 RecordPixel(int i, int j, gevd_bufferxy& edgels,
00272 vcl_vector<int>& iloc, vcl_vector<int>& jloc)
00273 {
00274
00275
00276
00277
00278
00279 floatPixel(edgels, i, j) = -1;
00280 iloc.push_back(i), jloc.push_back(j);
00281 #ifdef DEBUG
00282 if (sdet_contour::debug_)
00283 vcl_cout << "Recording (" << i << ' ' << j << ")\n";
00284 #endif
00285 }
00286
00287
00288
00289
00290 void
00291 ErasePixel(vcl_vector<int>& xloc, vcl_vector<int>& yloc)
00292 {
00293 vcl_vector<int>::iterator xit = xloc.end();
00294 vcl_vector<int>::iterator yit = yloc.end();
00295 xloc.erase(xit-1);
00296 yloc.erase(yit-1);
00297 }
00298
00299
00300
00301
00302
00303
00304 static int
00305 NextPixel(int& i, int& j, const gevd_bufferxy& edgels)
00306 {
00307 float maxpix = 0, npix;
00308 int maxdir = 0, dir;
00309 for (dir = 0; dir < TWOPI; dir += HALFPI)
00310 if ((npix = floatPixel(edgels, i+DIS[dir], j+DJS[dir])) > maxpix)
00311 {
00312 maxpix = npix;
00313 maxdir = dir+TWOPI;
00314 }
00315 if (!maxdir)
00316 {
00317 for (dir = 1; dir < TWOPI; dir += HALFPI)
00318 if ((npix = floatPixel(edgels, i+DIS[dir], j+DJS[dir])) > maxpix)
00319 {
00320 maxpix = npix;
00321 maxdir = dir+TWOPI;
00322 }
00323 }
00324 if (maxdir)
00325 i += DIS[maxdir], j += DJS[maxdir];
00326 return maxdir;
00327 }
00328
00329
00330
00331
00332
00333
00334 static int
00335 next_pixel(int& i, int& j, const vbl_array_2d<vtol_vertex_2d_sptr>& vertexMap)
00336 {
00337 int maxdir = 0, dir;
00338 for (dir = 0; dir < TWOPI; dir += HALFPI)
00339 if (vertexMap.get(i+DIS[dir], j+DJS[dir]))
00340 {
00341 maxdir = dir+TWOPI;
00342 break;
00343 }
00344 if (!maxdir)
00345 {
00346 for (dir = 1; dir < TWOPI; dir += HALFPI)
00347 if (vertexMap.get(i+DIS[dir], j+DJS[dir]))
00348 {
00349 maxdir = dir+TWOPI;
00350 break;
00351 }
00352 }
00353 if (maxdir)
00354 i += DIS[maxdir], j += DJS[maxdir];
00355 return maxdir;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 int
00369 sdet_contour::FindChains(gevd_bufferxy& edgels, const int njunction,
00370 const int* junctionx, const int* junctiony,
00371 vcl_vector<vtol_edge_2d_sptr>& edges)
00372 {
00373 vul_timer t;
00374
00375
00376
00377
00378 vtol_vertex_2d_sptr mark = new vtol_vertex_2d;
00379 for (int k = 0; k < njunction; k++)
00380 vertexMap->put(junctionx[k], junctiony[k], mark);
00381
00382
00383
00384 const int rmax = FRAME;
00385 const int xmax = edgels.GetSizeX()-rmax-1;
00386 const int ymax = edgels.GetSizeY()-rmax-1;
00387 vcl_vector<int> xloc(xmax+ymax), yloc(xmax+ymax);
00388
00389 for (int j = rmax; j <= ymax; j++)
00390 for (int i = rmax; i <= xmax; i++)
00391 {
00392
00393 if (floatPixel(edgels, i, j) > minStrength &&
00394 on_contour(edgels, i, j))
00395 {
00396 int x = i, y = j;
00397
00398
00399 if (!NextPixel(x, y, edgels))
00400 {
00401 floatPixel(edgels, i, j) = 0;
00402 continue;
00403 }
00404
00405 xloc.clear(), yloc.clear();
00406 RecordPixel(i, j, edgels, xloc, yloc);
00407 int ii = x, jj = y;
00408 RecordPixel(ii, jj, edgels, xloc, yloc);
00409 if (NextPixel(x, y, edgels))
00410 RecordPixel(x, y, edgels, xloc, yloc);
00411 else {
00412 x = i, y = j;
00413 if (NextPixel(x, y, edgels)) {
00414 xloc.clear(), yloc.clear();
00415 RecordPixel(ii, jj, edgels, xloc, yloc);
00416 RecordPixel(i, j, edgels, xloc, yloc);
00417 RecordPixel(x, y, edgels, xloc, yloc);
00418 ii = i, jj = j;
00419 }
00420 else {
00421 floatPixel(edgels, i, j) = 0;
00422 floatPixel(edgels, ii, jj) = 0;
00423 continue;
00424 }
00425 }
00426
00427
00428
00429
00430 int dprod = (x - ii)*(ii - xloc[0]) + (y - jj)*(jj - yloc[0]);
00431 if (dprod < 0)
00432 {
00433 if (sdet_contour::debug_)
00434 vcl_cout << "dps(" << xloc[0] << ' ' << yloc[0] << ")(" << xloc[1]
00435 << ' ' << yloc[1] << ")(" << x << ' ' << y << ")= "
00436 << dprod << '\n' << vcl_flush;
00437
00438 ErasePixel(xloc, yloc);
00439 ErasePixel(xloc, yloc);
00440 RecordPixel(x, y, edgels, xloc, yloc);
00441 }
00442
00443
00444
00445 int niii = ii, njjj = jj;
00446 int nii = x, njj=y;
00447 while (NextPixel(x, y, edgels))
00448 {
00449
00450
00451 dprod = (x - nii)*(nii - niii) + (y - njj)*(njj - njjj);
00452 if (dprod < 0)
00453 {
00454 if (sdet_contour::debug_)
00455 vcl_cout << "dpf(" << niii << ' ' << njjj << ")(" << nii << ' '
00456 << njj << ")(" << x << ' ' << y << ")= " << dprod
00457 << '\n' << vcl_flush;
00458
00459 ErasePixel(xloc, yloc);
00460 RecordPixel(x, y,edgels, xloc, yloc);
00461 }
00462 else
00463 RecordPixel(x, y, edgels, xloc, yloc);
00464 niii = nii; njjj = njj;
00465 nii = x; njj = y;
00466 }
00467
00468
00469 if (vcl_abs(xloc[0]-x) > 1 ||
00470 vcl_abs(yloc[0]-y) > 1)
00471 {
00472
00473
00474 if (next_pixel(x, y, *vertexMap))
00475 xloc.push_back(x), yloc.push_back(y);
00476
00477
00478
00479 x = xloc[0], y = yloc[0];
00480
00481
00482 vcl_vector<int> xloctemp( xloc.size()), yloctemp( yloc.size());
00483 for (unsigned int iii=0; iii< xloc.size(); iii++)
00484 xloctemp[iii]= xloc[xloc.size()-1-iii];
00485 for (unsigned int jjj=0; jjj< yloc.size(); jjj++)
00486 yloctemp[jjj]= yloc[yloc.size()-1-jjj];
00487
00488
00489 for (unsigned int jk=0; jk<xloc.size(); jk++)
00490 xloc[jk]=xloctemp[jk];
00491 for (unsigned int jk=0; jk<yloc.size(); jk++)
00492 yloc[jk]=yloctemp[jk];
00493
00494
00495 int il = xloc.size();
00496 nii = xloc[il-1];
00497 njj = yloc[il-1];
00498 niii = xloc[il-2];
00499 njjj = yloc[il-2];
00500 while (NextPixel(x, y, edgels))
00501 {
00502
00503
00504 dprod = (x - nii)*(nii - niii)+(y - njj)*(njj - njjj);
00505 if (dprod < 0)
00506 {
00507 if (sdet_contour::debug_)
00508 vcl_cout << "dpr(" << niii << ' ' << njjj << ")(" << nii << ' '
00509 << njj << ")(" << x << ' ' << y << ")= " << dprod
00510 << '\n' << vcl_flush;
00511
00512 ErasePixel(xloc, yloc);
00513 RecordPixel(x, y, edgels, xloc, yloc);
00514 }
00515 else
00516 RecordPixel(x, y, edgels, xloc, yloc);
00517 niii = nii; njjj = njj;
00518 nii = x; njj = y;
00519 }
00520
00521
00522 if (next_pixel(x, y, *vertexMap))
00523 xloc.push_back(x), yloc.push_back(y);
00524 }
00525 int len = xloc.size();
00526
00527 if (len < minLength) {
00528 for (int k = 0; k < len; k++)
00529 floatPixel(edgels, xloc[k], yloc[k]) = 0;
00530 continue;
00531 }
00532
00533
00534
00535
00536 vtol_edge_2d_sptr edge = new vtol_edge_2d();
00537 vdgl_edgel_chain_sptr ec = new vdgl_edgel_chain;
00538 vdgl_interpolator_sptr it = new vdgl_interpolator_linear(ec);
00539 vdgl_digital_curve_sptr dc = new vdgl_digital_curve(it);
00540
00541 for (int k=0; k< len; k++)
00542 {
00543 x= xloc[k];
00544 y= yloc[k];
00545 ec->add_edgel( vdgl_edgel( x, y));
00546 edgeMap->put(x, y, edge);
00547 }
00548 edge->set_curve(*dc->cast_to_curve());
00549 LookupTableInsert(edges, edge);
00550 }
00551 }
00552
00553
00554
00555
00556 for (int k = 0; k < njunction; k++)
00557 vertexMap->put(junctionx[k], junctiony[k],NULL);
00558 for (int j = rmax; j <= ymax; j++)
00559 for (int i = rmax; i <= xmax; i++)
00560 if (floatPixel(edgels, i, j) < 0)
00561 floatPixel(edgels, i, j) = - floatPixel(edgels, i, j);
00562
00563 if (talkative_)
00564 vcl_cout << "Find " << edges.size()
00565 << " chains/cycles, with pixels > " << minLength
00566 << " and strength > " << minStrength
00567 << ", in " << t.real() << " msecs.\n";
00568
00569 return edges.size();
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 bool sdet_contour:: DetectJunction(vtol_vertex_2d_sptr const& endv, int& index,
00587 vtol_edge_2d_sptr& weaker,
00588 vtol_edge_2d_sptr& stronger,
00589 const int maxSpiral,
00590 const gevd_bufferxy& edgels)
00591 {
00592
00593 if (endv->numsup() > 1)
00594 return false;
00595 vcl_vector<vtol_edge_sptr> edges; endv->edges(edges);
00596 weaker = edges[0]->cast_to_edge_2d();
00597 vdgl_digital_curve_sptr dc = weaker->curve()->cast_to_vdgl_digital_curve();
00598
00599 const int len = dc->get_interpolator()->get_edgel_chain()->size();
00600
00601
00602
00603
00604
00605 const int rfuzz = vcl_min(len, 3*MINLENGTH);
00606 vtol_edge_2d_sptr* labels = new vtol_edge_2d_sptr[rfuzz];
00607
00608
00609
00610 if (endv == weaker->v1()->cast_to_vertex_2d())
00611 for (int r = 0; r < rfuzz; r++)
00612 {
00613 vdgl_edgel edgel= dc->get_interpolator()->get_edgel_chain()->edgel( r);
00614 labels[r] = edgeMap->get( int(edgel.get_x()), int(edgel.get_y()));
00615 edgeMap->put(int(edgel.get_x()), int(edgel.get_y()), NULL);
00616 }
00617 else
00618 for (int r = 0; r < rfuzz; r++)
00619 {
00620 vdgl_edgel edgel= dc->get_interpolator()->get_edgel_chain()->edgel(len-1-r);
00621 labels[r] = edgeMap->get( int( edgel.get_x()), int( edgel.get_y()));
00622 edgeMap->put(int(edgel.get_x()), int(edgel.get_y()), NULL);
00623 }
00624
00625
00626
00627
00628
00629
00630 stronger = NULL;
00631 int jx = int(endv->x()), jy = int(endv->y());
00632 for (int l = 0, n = 0; l < maxSpiral; l++)
00633 {
00634 float maxpix = 0; int maxn = 0;
00635 for (; n < RNS[l]; n++)
00636 {
00637 int x = jx+RIS[n], y = jy+RJS[n];
00638 if (edgeMap->get(x, y) &&
00639 floatPixel(edgels, x, y) > maxpix)
00640 {
00641 maxpix = floatPixel(edgels, x, y);
00642 maxn = n;
00643 }
00644 }
00645 if (maxpix) {
00646 stronger = edgeMap->get(jx+RIS[maxn], jy+RJS[maxn]);
00647 jx += RIS[maxn], jy += RJS[maxn];
00648 break;
00649 }
00650 }
00651
00652 if (endv == weaker->v1()->cast_to_vertex_2d())
00653 for (int r=0; r< rfuzz; r++)
00654 {
00655 vdgl_edgel edge= dc->get_interpolator()->get_edgel_chain()->edgel(r);
00656 edgeMap->put(int( edge.get_x()), int( edge.get_y()), labels[r]);
00657 }
00658 else
00659 for (int r=0; r< rfuzz; r++)
00660 {
00661 vdgl_edgel edgel= dc->get_interpolator()->get_edgel_chain()->edgel(len-1-r);
00662 edgeMap->put(int( edgel.get_x()), int( edgel.get_y()),labels[r]);
00663 }
00664 delete [] labels;
00665
00666 if (!stronger)
00667 return false;
00668
00669
00670
00671
00672 index = int(INVALID);
00673 vdgl_digital_curve_sptr dc2 =(stronger->curve()->cast_to_vdgl_digital_curve());
00674 vdgl_edgel_chain_sptr ec = dc2->get_interpolator()->get_edgel_chain();
00675 index = bdgl_curve_algs::closest_point(ec, jx, jy);
00676
00677
00678
00679
00680
00681 const int s = 3;
00682 if ((index<=s || index+s+1 > (int)ec->size())&&
00683 stronger->v1()&&stronger->v2())
00684 return false;
00685 if (sdet_contour::debug_)
00686 vcl_cout << "Closest index to (" << endv->x() << ' '
00687 << endv->y() << ") is " << index
00688 << " corresponding to " << ec->edgel(index)
00689 << "size = " << ec->size() << vcl_endl;
00690
00691 return true;
00692 }
00693
00694
00695
00696 bool sdet_contour::move_junction(vtol_vertex_2d_sptr const& junction,
00697 int& index,
00698 vdgl_digital_curve_sptr const & dc)
00699 {
00700 if (!junction)
00701 return false;
00702 int jx = int(junction->x()), jy = int(junction->y());
00703 vertexMap->put(jx, jy, NULL);
00704
00705 vdgl_edgel_chain_sptr ec = dc->get_interpolator()->get_edgel_chain();
00706 jx = int((*ec)[index].x());
00707 jy = int((*ec)[index].y());
00708
00709 junction->set_x(jx), junction->set_y(jy);
00710
00711
00712 vertexMap->put(jx, jy, junction);
00713 edgeMap->put(jx, jy, NULL);
00714 return true;
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724 void sdet_contour::update_edgel_chain(vtol_edge_2d_sptr const& edge,
00725 const int old_x, const int old_y,
00726 vtol_vertex_2d_sptr& v)
00727 {
00728 if (!edge||!v)
00729 {
00730 vcl_cout << "In update_edgel_chain - null inputs\n";
00731 return;
00732 }
00733
00734 double x = v->x(), y = v->y();
00735
00736 vdgl_digital_curve_sptr dc_old= edge->curve()->cast_to_vdgl_digital_curve();
00737 vdgl_edgel_chain_sptr ec_old= dc_old->get_interpolator()->get_edgel_chain();
00738 int N = ec_old->size();
00739
00740 vdgl_edgel_chain_sptr ec = new vdgl_edgel_chain;
00741 vdgl_interpolator_sptr it = new vdgl_interpolator_linear(ec);
00742 vsol_curve_2d_sptr dc = new vdgl_digital_curve(it);
00743
00744
00745
00746 if (edge->v1()==edge->v2())
00747 {
00748 vcl_cout << "Cycle case not implemented\n";
00749 return;
00750 }
00751
00752
00753
00754
00755 if (v==edge->v1()->cast_to_vertex_2d())
00756 {
00757
00758
00759 vdgl_edgel ed(x, y, bdgl_curve_algs::synthetic);
00760
00761 ec->add_edgel(ed);
00762
00763
00764 int npix =
00765 bdgl_curve_algs::add_straight_edgels(ec, old_x, old_y,
00766 sdet_contour::debug_);
00767
00768 if (!npix)
00769 return;
00770
00771
00772 for (int i=1; i<npix; i++)
00773 edgeMap->put(int((*ec)[i].x()),int((*ec)[i].y()),edge);
00774
00775
00776 for (int index = 0; index<N; index++)
00777 ec->add_edgel((*ec_old)[index]);
00778
00779
00780 edge->set_curve(*dc);
00781 return;
00782 }
00783
00784 if (v==edge->v2()->cast_to_vertex_2d())
00785 {
00786
00787
00788 for (int index = 0; index<N; index++)
00789 ec->add_edgel((*ec_old)[index]);
00790
00791
00792
00793 int npix =
00794 bdgl_curve_algs::add_straight_edgels(ec, x, y,
00795 sdet_contour::debug_);
00796
00797 if (!npix)
00798 return;
00799
00800 for (int i=N; i<N+npix; i++)
00801 edgeMap->put(int((*ec)[i].x()),int((*ec)[i].y()),edge);
00802
00803
00804 edge->set_curve(*dc);
00805 return;
00806 }
00807 }
00808
00809 void fill_cycle_gap(vdgl_edgel_chain_sptr const & ec)
00810 {
00811 if (!ec)
00812 return;
00813 int x0 = int((*ec)[0].x()), y0 = int((*ec)[0].y());
00814 bdgl_curve_algs::add_straight_edgels(ec, x0, y0,
00815 sdet_contour::debug_);
00816 }
00817
00818 #if 0 // unused local function
00819 static bool
00820 ConfirmJunctionOnCycle(int index, float threshold,
00821 vtol_edge_2d& cycle, const gevd_bufferxy& edgels)
00822 {
00823 if (sdet_contour::debug_)
00824 vcl_cerr << "ConfirmJunctionOnCycle() not run: returning 'TRUE'\n";
00825
00826 #if 1 // JLM
00827 return true;
00828 #else
00829 vdgl_digital_curve_sptr dc = cycle.curve()->cast_to_vdgl_digital_curve();
00830 const int len = dc->get_interpolator()->get_edgel_chain()->size();
00831 const int wrap = 10*len;
00832 const int radius = 3;
00833
00834 for (int n = index-radius; n <= index+radius; n++)
00835 {
00836 int nm = (n-1+wrap)%len;
00837 int np = (n+1+wrap)%len;
00838
00839 vdgl_edgel edgel_m= dc->get_interpolator()->get_edgel_chain()->edgel( nm);
00840 vdgl_edgel edgel_p= dc->get_interpolator()->get_edgel_chain()->edgel( np);
00841
00842 if (vcl_fabs(floatPixel(edgels, int( edgel_p.x()), int( edgel_p.y())) -
00843 floatPixel(edgels, int( edgel_m.x()), int( edgel_m.y())))
00844 > threshold)
00845 return true;
00846 }
00847 return false;
00848 #endif // 1
00849 }
00850 #endif // 0
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 void sdet_contour::BreakCycle(vtol_vertex_2d_sptr const& junction,
00867 int& index, vtol_edge_2d_sptr const& stronger,
00868 vtol_edge_2d_sptr & split)
00869 {
00870
00871 vdgl_digital_curve_sptr old_dc =
00872 (stronger->curve()->cast_to_vdgl_digital_curve());
00873 vdgl_edgel_chain_sptr old_ec = old_dc->get_interpolator()->get_edgel_chain();
00874 const int N = old_ec->size();
00875
00876
00877 move_junction(junction, index, old_dc);
00878
00879
00880 split = new vtol_edge_2d();
00881
00882
00883 vdgl_edgel_chain* es = new vdgl_edgel_chain;
00884 vdgl_interpolator* it =
00885 new vdgl_interpolator_linear(vdgl_edgel_chain_sptr(es));
00886 vdgl_digital_curve *ds =
00887 new vdgl_digital_curve( vdgl_interpolator_sptr( it));
00888 split->set_curve(*ds);
00889
00890
00891
00892 for (int k = index; k <N; k++)
00893 {
00894 es->add_edgel((*old_ec)[k]);
00895 int x = int((*old_ec)[k].x()), y = int((*old_ec)[k].y());
00896 edgeMap->put(x, y, split);
00897 if (sdet_contour::debug_)
00898 vcl_cout << "BreakCycle: edge1 edgel at (" << x << ' ' << y << ")\n";
00899 }
00900
00901 for (int k = 0; k <= index; k++)
00902 {
00903 es->add_edgel((*old_ec)[k]);
00904 int x = int((*old_ec)[k].x()), y = int((*old_ec)[k].y());
00905 edgeMap->put(x, y, split);
00906 if (sdet_contour::debug_)
00907 vcl_cout << "BreakCycle: edge1 edgel at (" << x << ' ' << y << ")\n";
00908 }
00909
00910 split->set_v1(junction->cast_to_vertex());
00911 split->set_v2(junction->cast_to_vertex());
00912 int x = int(junction->x());
00913 int y = int(junction->y());
00914 vertexMap->put(x, y, junction);
00915
00916
00917 }
00918
00919 #if 0 // unused local function
00920
00921
00922
00923 static bool
00924 ConfirmJunctionOnChain(int index, float threshold,
00925 vtol_edge_2d& chain, const gevd_bufferxy& edgels)
00926 {
00927 if (sdet_contour::debug_)
00928 vcl_cerr << "ConfirmJunctionOnChain() not run: returning 'TRUE'\n";
00929
00930 #if 1 // JLM
00931 return true;
00932 #else
00933 vdgl_digital_curve_sptr dc = chain.curve()->cast_to_vdgl_digital_curve();
00934 const int len = dc->get_interpolator()->get_edgel_chain()->size()-1;
00935
00936 if (len < 2*MINLENGTH-1)
00937 return false;
00938
00939 const int fuzz = MINLENGTH-1;
00940 const int radius = 3;
00941
00942
00943 for (int n = vcl_max(index-radius, fuzz); n <= vcl_min(index+radius,len-1-fuzz); n++)
00944 {
00945
00946
00947 vdgl_edgel cp1= dc->get_interpolator()->get_edgel_chain()->edgel(n+1);
00948 vdgl_edgel cm1= dc->get_interpolator()->get_edgel_chain()->edgel(n-1);
00949
00950
00951 if (vcl_fabs(floatPixel(edgels, int(cp1.x()), int(cp1.y())) -
00952 floatPixel(edgels, int(cm1.x()), int(cm1.y())))
00953 > threshold)
00954 {
00955 return true;
00956 }
00957 }
00958 return false;
00959 #endif // 1
00960 }
00961 #endif // 0
00962
00963 vtol_vertex_2d_sptr get_vertex_at_index(vtol_edge_2d_sptr& e, int index)
00964 {
00965 vdgl_digital_curve_sptr dc = e->curve()->cast_to_vdgl_digital_curve();
00966 if (!dc)
00967 return 0;
00968 vdgl_edgel ed = dc->get_interpolator()->get_edgel_chain()->edgel( index);
00969 vtol_vertex_2d_sptr v = new vtol_vertex_2d(ed.x(), ed.y());
00970 return v;
00971 }
00972
00973 bool find_vertex(vtol_vertex_2d_sptr& v,
00974 vcl_vector<vtol_vertex_2d_sptr>& vertices)
00975 {
00976 for (vcl_vector<vtol_vertex_2d_sptr>::iterator vit = vertices.begin();
00977 vit != vertices.end(); vit++)
00978 if ((*vit)==v)
00979 return true;
00980 return false;
00981 }
00982
00983 bool find_edge(vtol_edge_2d_sptr& e,
00984 vcl_vector<vtol_edge_2d_sptr>& edges)
00985 {
00986 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
00987 eit != edges.end(); eit++)
00988 if ((*eit)==e)
00989 return true;
00990 return false;
00991 }
00992
00993 void print_edge_lookup_table(vcl_vector<vtol_edge_2d_sptr>& edges)
00994 {
00995 int ei=0;
00996 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = edges.begin();
00997 eit != edges.end(); eit++, ei++)
00998 {
00999 if (!*eit)
01000 {
01001 vcl_cout << "edge[" << ei << "]= null\n";
01002 continue;
01003 }
01004 vcl_cout<< "edge["<< ei << "]= " << **eit
01005 << *((*eit)->v1()->cast_to_vertex_2d())
01006 << ' ' << *((*eit)->v2()->cast_to_vertex_2d()) << '\n';
01007 }
01008 }
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 void sdet_contour::BreakChain(vtol_vertex_2d_sptr const& junction,
01019 int& index,
01020 vtol_edge_2d_sptr const& stronger,
01021 vtol_edge_2d_sptr& longer,
01022 vtol_edge_2d_sptr& shorter)
01023 {
01024 vdgl_digital_curve_sptr dc = stronger->curve()->cast_to_vdgl_digital_curve();
01025
01026 const int N = dc->get_interpolator()->get_edgel_chain()->size();
01027
01028
01029 move_junction(junction, index, dc);
01030
01031
01032 vtol_edge_2d_sptr edge1 = new vtol_edge_2d();
01033 vdgl_edgel_chain *ec= new vdgl_edgel_chain;
01034 vdgl_interpolator *it= new vdgl_interpolator_linear( ec);
01035 vdgl_digital_curve *dc1 = new vdgl_digital_curve( it);
01036 edge1->set_curve(*dc1);
01037
01038
01039
01040 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01041 vdgl_edgel_chain *cxy1= ec;
01042 for (int k = 0; k <= index; k++)
01043 {
01044 cxy1->add_edgel( (*cxy)[k] );
01045 (*cxy1)[k] = (*cxy)[k];
01046 int x = int((*cxy1)[k].x()), y = int((*cxy1)[k].y());
01047 edgeMap->put(x , y, edge1);
01048 if (sdet_contour::debug_)
01049 vcl_cout << "BreakChain: edge1 edgel at (" << x << ' ' << y << ")\n";
01050 }
01051
01052
01053
01054 edge1->set_v1(stronger->v1()->cast_to_vertex());
01055
01056
01057 edge1->set_v2(junction->cast_to_vertex());
01058
01059
01060 int x11 = int(edge1->v1()->cast_to_vertex_2d()->x());
01061 int y11 = int(edge1->v1()->cast_to_vertex_2d()->y());
01062 int x12 = int(edge1->v2()->cast_to_vertex_2d()->x());
01063 int y12 = int(edge1->v2()->cast_to_vertex_2d()->y());
01064 edgeMap->put(x11, y11, NULL);
01065 edgeMap->put(x12, y12, NULL);
01066 vertexMap->put(x11, y11, edge1->v1()->cast_to_vertex_2d());
01067 vertexMap->put(x12, y12, edge1->v2()->cast_to_vertex_2d());
01068
01069
01070 vtol_edge_2d_sptr edge2 = new vtol_edge_2d();
01071 vdgl_edgel_chain *ec2= new vdgl_edgel_chain;
01072 vdgl_interpolator *it2= new vdgl_interpolator_linear( ec2);
01073 vdgl_digital_curve *dc2= new vdgl_digital_curve( it2);
01074 edge2->set_curve(*dc2);
01075
01076
01077
01078 vdgl_edgel_chain *cxy2= ec2;
01079 for (int k = index; k < N; k++)
01080 {
01081 cxy2->add_edgel((*cxy)[k]);
01082 int x = int((*cxy)[k].x()), y = int((*cxy)[k].y());
01083 edgeMap->put( x, y, edge2);
01084 if (sdet_contour::debug_)
01085 vcl_cout << "BreakChain: edge2 edgel at (" << x << ' ' << y << ")\n";
01086 }
01087
01088
01089 edge2->set_v2(stronger->v2()->cast_to_vertex());
01090
01091 edge2->set_v1(junction->cast_to_vertex());
01092
01093
01094 int x21 = int(edge2->v1()->cast_to_vertex_2d()->x());
01095 int y21 = int(edge2->v1()->cast_to_vertex_2d()->y());
01096 int x22 = int(edge2->v2()->cast_to_vertex_2d()->x());
01097 int y22 = int(edge2->v2()->cast_to_vertex_2d()->y());
01098 edgeMap->put(x21, y21, NULL);
01099 edgeMap->put(x22, y22, NULL);
01100 vertexMap->put(x21, y21, edge2->v1()->cast_to_vertex_2d());
01101 vertexMap->put(x22, y22, edge2->v2()->cast_to_vertex_2d());
01102
01103
01104
01105
01106
01107 if (cxy1->size() >= cxy2->size())
01108 longer = edge1, shorter = edge2;
01109 else
01110 longer = edge2, shorter = edge1;
01111 }
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 void
01123 sdet_contour::LoopChain(vtol_vertex_2d_sptr const& junction, int& index,
01124 vtol_edge_2d_sptr const& chain,
01125 vtol_edge_2d_sptr& straight,
01126 vtol_edge_2d_sptr& curled)
01127 {
01128 vdgl_digital_curve_sptr dc = chain->curve()->cast_to_vdgl_digital_curve();
01129 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01130 const int N = cxy->size();
01131
01132
01133 int old_x = int(junction->x()), old_y = int(junction->y());
01134 move_junction(junction, index, dc);
01135
01136
01137 straight = new vtol_edge_2d(), curled = new vtol_edge_2d();
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 if (junction == chain->v1()->cast_to_vertex_2d())
01149 {
01150 vdgl_edgel_chain *ec= new vdgl_edgel_chain;
01151 vdgl_interpolator *it= new vdgl_interpolator_linear( ec);
01152 vdgl_digital_curve *c= new vdgl_digital_curve( it);
01153 curled->set_curve(*c);
01154 vdgl_edgel_chain *xy= ec;
01155
01156
01157 if (!(int(junction->x())==old_x&&int(junction->y())==old_y))
01158 {
01159
01160 ec->add_edgel(vdgl_edgel((*cxy)[index].x(), (*cxy)[index].y()));
01161
01162
01163 int npix =
01164 bdgl_curve_algs::add_straight_edgels(ec, old_x, old_y,
01165 sdet_contour::debug_);
01166
01167
01168 for (int i=1; i<npix; i++)
01169 edgeMap->put(int((*xy)[i].x()),int((*xy)[i].y()),curled);
01170 }
01171
01172 for (int k = 0; k <= index; k++)
01173 {
01174 xy->add_edgel( (*cxy)[k] );
01175 edgeMap->put( int((*cxy)[k].x()), int((*cxy)[k].y()), curled);
01176 }
01177
01178 curled->set_v1(junction->cast_to_vertex());
01179 curled->set_v2(junction->cast_to_vertex());
01180 int x = int(junction->x()), y = int(junction->y());
01181 edgeMap->put(x, y, NULL);
01182 vertexMap->put(x, y, junction);
01183
01184
01185
01186 ec= new vdgl_edgel_chain;
01187 it= new vdgl_interpolator_linear( ec);
01188 c = new vdgl_digital_curve( it);
01189 straight->set_curve(*c);
01190 xy= ec;
01191
01192 for (int k = index; k < N; k++)
01193 {
01194 xy->add_edgel( (*cxy)[k] );
01195 edgeMap->put( int((*cxy)[k].x()), int((*cxy)[k].y()), straight);
01196 }
01197
01198 straight->set_v1(junction->cast_to_vertex());
01199 straight->set_v2(chain->v2());
01200
01201
01202 x = int(straight->v2()->cast_to_vertex_2d()->x());
01203 y = int(straight->v2()->cast_to_vertex_2d()->y());
01204 edgeMap->put(x, y, NULL);
01205 vertexMap->put(x, y, straight->v2()->cast_to_vertex_2d());
01206 }
01207 else
01208 {
01209
01210
01211
01212
01213
01214
01215
01216 vdgl_edgel_chain *ec= new vdgl_edgel_chain;
01217 vdgl_interpolator *it= new vdgl_interpolator_linear( ec);
01218 vdgl_digital_curve *c= new vdgl_digital_curve( it);
01219 straight->set_curve(*c);
01220 vdgl_edgel_chain *xy= ec;
01221
01222 for (int k = 0; k <=index; k++)
01223 {
01224 xy->add_edgel( (*cxy)[k] );
01225 edgeMap->put( int((*cxy)[k].x()), int((*cxy)[k].y()), straight);
01226 }
01227
01228
01229 straight->set_v1(chain->v1());
01230 straight->set_v2(junction->cast_to_vertex());
01231
01232
01233 int x = int(straight->v1()->cast_to_vertex_2d()->x());
01234 int y = int(straight->v1()->cast_to_vertex_2d()->y());
01235 edgeMap->put(x, y, NULL);
01236 vertexMap->put(x, y, straight->v1()->cast_to_vertex_2d());
01237
01238
01239 ec= new vdgl_edgel_chain;
01240 it= new vdgl_interpolator_linear( ec);
01241 c = new vdgl_digital_curve( it);
01242 curled->set_curve(*c);
01243 xy = ec;
01244
01245 int nc = 0;
01246
01247 for (int k = index; k < N; k++, nc++)
01248 {
01249 xy->add_edgel( (*cxy)[k] );
01250 edgeMap->put( int((*cxy)[k].x()), int((*cxy)[k].y()), curled);
01251 }
01252
01253
01254 if (!(int(junction->x())==old_x&&int(junction->y())==old_y))
01255 {
01256
01257 int new_x = int(junction->x()), new_y = int(junction->y());
01258 int npix =
01259 bdgl_curve_algs::add_straight_edgels(ec, new_x, new_y,
01260 sdet_contour::debug_);
01261
01262 for (int i=0; i<npix; i++)
01263 edgeMap->put(int((*xy)[nc+i].x()),int((*xy)[nc+i].y()),curled);
01264 }
01265
01266
01267 curled->set_v1(junction->cast_to_vertex());
01268 curled->set_v2(junction->cast_to_vertex());
01269
01270
01271 x = int(junction->x());
01272 y = int(junction->y());
01273 edgeMap->put(x, y, NULL);
01274 vertexMap->put(x, y, junction);
01275 }
01276
01277
01278 }
01279
01280
01281
01282
01283 bool sdet_contour::near_border(vtol_vertex_2d_sptr const& v)
01284 {
01285 const int xmin = FRAME;
01286 const int ymin = FRAME;
01287 const int xmax = vertexMap->rows()-FRAME-1;
01288 const int ymax = vertexMap->columns()-FRAME-1;
01289 int x = int(v->x()), y = int(v->y());
01290 return x<=xmin||x>=xmax||y<=ymin||y>=ymax;
01291 }
01292
01293
01294
01295
01296
01297
01298
01299
01300 vtol_vertex_2d_sptr
01301 sdet_contour::DetectTouch(vtol_vertex_2d_sptr const& endv,
01302 const int maxSpiral)
01303 {
01304 const int jx = int(endv->x()), jy = int(endv->y());
01305 for (int l = 0, n = 0; l < maxSpiral; l++)
01306 {
01307 int bx=0, by=0;
01308 vtol_vertex_2d_sptr best_neighbor = NULL;
01309 int max_edges = 0;
01310 for (; n < RNS[l]; n++)
01311 {
01312 int x = jx+RIS[n], y = jy+RJS[n];
01313 vtol_vertex_2d_sptr nbr = vertexMap->get(x, y);
01314 int nedges = 0;
01315 if (nbr)
01316 nedges = nbr->numsup();
01317 if (nedges > max_edges)
01318 {
01319 max_edges = nedges;
01320 best_neighbor = nbr;
01321 bx = x; by = y;
01322 }
01323 }
01324 if (sdet_contour::debug_)
01325 vcl_cout << "(bx,by) = (" << bx << ' ' << by << ")\n";
01326 if (max_edges)
01327 return best_neighbor;
01328 }
01329 return NULL;
01330 }
01331
01332
01333
01334 vtol_edge_2d_sptr
01335 DanglingEdge(vtol_vertex_2d_sptr const& v)
01336 {
01337 vcl_vector<vtol_edge_sptr> segs; v->edges(segs);
01338 if (segs.size()==1)
01339 return segs[0]->cast_to_edge_2d();
01340 else
01341 return 0;
01342 }
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356 bool
01357 sdet_contour::MergeEndPtsOfChain(vtol_vertex_2d_sptr const& endpt,
01358 vtol_vertex_2d_sptr const& other,
01359 vtol_vertex_2d_sptr& removed_vert)
01360 {
01361 if (sdet_contour::debug_)
01362 vcl_cout << " Merging end points of same edge " << *endpt << ' '
01363 << *other << '\n';
01364
01365 vcl_vector<vtol_edge_sptr> edges; endpt->edges(edges);
01366
01367 vtol_edge_2d_sptr edge = edges[0]->cast_to_edge_2d();
01368 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
01369 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01370 int N = cxy->size();
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380 while (true)
01381 {
01382
01383
01384 if (edge->v2()->cast_to_vertex_2d() == endpt)
01385 {
01386
01387 double xe = other->x();
01388 double ye = other->y();
01389 int nedgls =
01390 bdgl_curve_algs::add_straight_edgels(cxy, xe, ye,
01391 sdet_contour::debug_);
01392 for (int i = N; i<N+nedgls; i++)
01393 edgeMap->put( int((*cxy)[i].x()), int((*cxy)[i].y()), edge);
01394 edge->set_v2(other->cast_to_vertex());
01395 removed_vert = endpt;
01396 vertexMap->put(int(endpt->x()), int(endpt->y()), NULL);
01397 break;
01398 }
01399
01400
01401 if (edge->v1()->cast_to_vertex_2d() == endpt)
01402 {
01403
01404 double xe = endpt->x();
01405 double ye = endpt->y();
01406 int nedgls =
01407 bdgl_curve_algs::add_straight_edgels(cxy, xe, ye,
01408 sdet_contour::debug_);
01409 for (int i = N; i<N+nedgls; i++)
01410 edgeMap->put( int((*cxy)[i].x()), int((*cxy)[i].y()), edge);
01411 edge->set_v2(endpt->cast_to_vertex());
01412 removed_vert = other;
01413 vertexMap->put(int(other->x()), int(other->y()), NULL);
01414 break;
01415 }
01416 }
01417 return true;
01418 }
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 void
01431 sdet_contour::MergeEndPtTouchingEndPt(vtol_vertex_2d_sptr const& end1,
01432 vtol_vertex_2d_sptr const& end2,
01433 vtol_edge_2d_sptr& merge,
01434 vtol_edge_2d_sptr& longer,
01435 vtol_edge_2d_sptr& shorter)
01436 {
01437
01438
01439
01440 vcl_vector<vtol_edge_sptr> edges; end1->edges(edges);
01441 vtol_edge_2d_sptr edge1 = edges[0]->cast_to_edge_2d();
01442
01443
01444 end2->edges(edges);
01445 vtol_edge_2d_sptr edge2 = edges[0]->cast_to_edge_2d();
01446
01447
01448 vdgl_digital_curve_sptr dc1 = edge1->curve()->cast_to_vdgl_digital_curve();
01449 const int l1 = dc1->get_interpolator()->get_edgel_chain()->size();
01450 vdgl_digital_curve_sptr dc2 = edge2->curve()->cast_to_vdgl_digital_curve();
01451 const int l2 = dc2->get_interpolator()->get_edgel_chain()->size();
01452
01453
01454 vdgl_edgel_chain_sptr cxy1= dc1->get_interpolator()->get_edgel_chain();
01455
01456
01457 vdgl_edgel_chain_sptr cxy2= dc2->get_interpolator()->get_edgel_chain();
01458
01459
01460 merge = new vtol_edge_2d();
01461 vdgl_edgel_chain *ec = new vdgl_edgel_chain;
01462 vdgl_interpolator *it = new vdgl_interpolator_linear( ec);
01463 vdgl_digital_curve *dc = new vdgl_digital_curve(it);
01464
01465 merge->set_curve(*dc);
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477 if (sdet_contour::debug_)
01478 {
01479 vcl_cout << "end1 " << *end1 << '\n'
01480 << "end2 " << *end2 << '\n'
01481 << "edge1-v1 " << *(edge1->v1())
01482 << " edge1-v2 " << *(edge1->v2()) << '\n'
01483 << "edge2-v1 " << *(edge2->v1())
01484 << " edge2-v2 " << *(edge2->v2()) << '\n'
01485 << " (*cxy1)[0] ="<< (*cxy1)[0] << '\n'
01486 << " (*cxy1)[l1-1] =" <<(*cxy1)[l1-1] << '\n'
01487
01488 << " (*cxy2)[0] = "<<(*cxy2)[0] << '\n'
01489 << " (*cxy1)[l2-1] =" << (*cxy2)[l2-1] << '\n';
01490 }
01491
01492 vdgl_edgel_chain *cxy= ec;
01493
01494
01495 while (true)
01496 {
01497
01498 if (edge1->v2()->cast_to_vertex_2d() == end1)
01499 {
01500 if (sdet_contour::debug_)
01501 vcl_cout << "Case a\n";
01502 for (int i = 0; i < l1; i++)
01503 {
01504 cxy->add_edgel( (*cxy1)[i] );
01505 if (sdet_contour::debug_)
01506 vcl_cout << "merge edgel " << (*cxy1)[i] << '\n';
01507 }
01508 merge->set_v1(edge1->v1());
01509 break;
01510 }
01511
01512 if (edge1->v1()->cast_to_vertex_2d() == end1)
01513 {
01514 if (sdet_contour::debug_)
01515 vcl_cout << "Case b\n";
01516 for (int i = l1-1; i >= 0; --i)
01517 {
01518 cxy->add_edgel((*cxy1)[i]);
01519 if (sdet_contour::debug_)
01520 vcl_cout << "merge edgel " << (*cxy1)[i] << '\n';
01521 }
01522 merge->set_v1(edge1->v2());
01523 break;
01524 }
01525 }
01526
01527
01528 double xe = end2->cast_to_vertex_2d()->x();
01529 double ye = end2->cast_to_vertex_2d()->y();
01530 bdgl_curve_algs::add_straight_edgels(cxy, xe, ye,
01531 sdet_contour::debug_);
01532
01533
01534 while (true)
01535 {
01536
01537 if (edge2->v1()->cast_to_vertex_2d() == end2)
01538 {
01539 if (sdet_contour::debug_)
01540 vcl_cout << "Case c\n";
01541 for (int i = 1; i < l2; i++)
01542 {
01543 cxy->add_edgel( (*cxy2)[i] );
01544 if (sdet_contour::debug_)
01545 vcl_cout << "merge edgel " << (*cxy2)[i] << '\n';
01546 }
01547 merge->set_v2(edge2->v2());
01548 break;
01549 }
01550
01551 if (edge2->v2()->cast_to_vertex_2d() == end2)
01552 {
01553 if (sdet_contour::debug_)
01554 vcl_cout << "Case d\n";
01555 for (int i = l2-2; i >= 0; i--)
01556 {
01557 cxy->add_edgel( (*cxy2)[i] );
01558 if (sdet_contour::debug_)
01559 vcl_cout << "merge edgel " << (*cxy2)[i] << '\n';
01560 }
01561 merge->set_v2(edge2->v1());
01562 break;
01563 }
01564 }
01565
01566
01567 vertexMap->put(int(end1->x()), int(end1->y()), NULL);
01568 vertexMap->put(int(end2->x()), int(end2->y()), NULL);
01569 const int last = cxy->size()-1;
01570 for (int k = 1; k < last; k++)
01571 edgeMap->put( int((*cxy)[k].x()), int((*cxy)[k].y()), merge);
01572 if (edgeMap->get( int((*cxy)[0].x()), int((*cxy)[0].y())))
01573 edgeMap->put( int((*cxy)[0].x()), int((*cxy)[0].y()), merge);
01574 if (edgeMap->get( int((*cxy)[last].x()), int((*cxy)[last].y())))
01575 edgeMap->put( int((*cxy)[last].x()), int((*cxy)[last].y()), merge);
01576
01577 if (l1 >= l2)
01578 longer = edge1, shorter = edge2;
01579 else
01580 longer = edge2, shorter = edge1;
01581 if (sdet_contour::debug_)
01582 {
01583 vcl_cout << "longer " << *(longer->v1()->cast_to_vertex_2d())
01584 << ' ' << *(longer->v2()->cast_to_vertex_2d()) << '\n'
01585 << "shorter " << *(shorter->v1()->cast_to_vertex_2d())
01586 << ' ' << *(shorter->v2()->cast_to_vertex_2d()) << '\n';
01587 }
01588 }
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600 bool sdet_contour::
01601 MergeEndPtTouchingJunction(vtol_vertex_2d_sptr const& endpt,
01602 vtol_vertex_2d_sptr const& junction,
01603 vtol_edge_2d_sptr& old_edge,
01604 vtol_edge_2d_sptr& new_edge)
01605 {
01606 if (sdet_contour::debug_)
01607 vcl_cout << "Merge at Junction e" << *endpt<< " j" << *junction << '\n';
01608 vcl_vector<vtol_edge_sptr> edges; endpt->edges(edges);
01609
01610 old_edge = edges[0]->cast_to_edge_2d();
01611 vdgl_digital_curve_sptr old_dc = old_edge->curve()->cast_to_vdgl_digital_curve();
01612 vdgl_edgel_chain_sptr old_cxy= old_dc->get_interpolator()->get_edgel_chain();
01613 int N = old_cxy->size();
01614
01615 new_edge = new vtol_edge_2d();
01616 vdgl_edgel_chain *cxy = new vdgl_edgel_chain;
01617 vdgl_interpolator *it = new vdgl_interpolator_linear(cxy);
01618 vdgl_digital_curve *dc = new vdgl_digital_curve(it);
01619 new_edge->set_curve(*dc);
01620
01621 int xs, ys;
01622
01623 while (true)
01624 {
01625
01626
01627 if (old_edge->v2()->cast_to_vertex_2d() == endpt)
01628 {
01629 if (sdet_contour::debug_)
01630 vcl_cout << "Case ja\n";
01631 for (int i = 0; i+1 < N; ++i)
01632 {
01633 cxy->add_edgel( (*old_cxy)[i] );
01634 if (sdet_contour::debug_)
01635 vcl_cout << "junction edgel " << (*old_cxy)[i] << '\n';
01636 edgeMap->put( int((*old_cxy)[i].x()),
01637 int((*old_cxy)[i].y()), new_edge);
01638 }
01639
01640 new_edge->set_v1(old_edge->v1());
01641 xs = int(old_edge->v1()->cast_to_vertex_2d()->x());
01642 ys = int(old_edge->v1()->cast_to_vertex_2d()->y());
01643 vertexMap->put(xs, ys, new_edge->v1()->cast_to_vertex_2d());
01644 edgeMap->put(xs, ys, NULL);
01645 break;
01646 }
01647
01648
01649 if (old_edge->v1()->cast_to_vertex_2d() == endpt)
01650 {
01651 if (sdet_contour::debug_)
01652 vcl_cout << "Case jb\n";
01653 for (int i = N-1; i >=0; --i)
01654 {
01655 cxy->add_edgel((*old_cxy)[i]);
01656 if (sdet_contour::debug_)
01657 vcl_cout << "junction edgel " << (*old_cxy)[i] << '\n';
01658 edgeMap->put( int((*old_cxy)[i].x()),
01659 int((*old_cxy)[i].y()), new_edge);
01660 }
01661
01662
01663 new_edge->set_v1(old_edge->v2());
01664 xs = int(old_edge->v2()->cast_to_vertex_2d()->x());
01665 ys = int(old_edge->v2()->cast_to_vertex_2d()->y());
01666 vertexMap->put(xs, ys, new_edge->v1()->cast_to_vertex_2d());
01667 edgeMap->put(xs, ys, NULL);
01668 break;
01669 }
01670 }
01671
01672
01673
01674 double xe = junction->cast_to_vertex_2d()->x();
01675 double ye = junction->cast_to_vertex_2d()->y();
01676 int nedgls =
01677 bdgl_curve_algs::add_straight_edgels(cxy, xe, ye,
01678 sdet_contour::debug_);
01679
01680
01681
01682
01683
01684 bool self_intersects = false;
01685 for (int i = N; i<(N+nedgls-1)&&!self_intersects; i++)
01686 {
01687 int x = int((*cxy)[i].x()), y = int((*cxy)[i].y());
01688 #define WARN(x,y) vcl_cerr << "Warning: edgel "<<i<<" is at ("<<x<<','<<y\
01689 <<") which is outside of edge map of size "\
01690 <<edgeMap->rows()<<'x'<<edgeMap->cols()<<'\n'
01691 if (x < 0) { WARN(x,y); x = 0; }
01692 if (y < 0) { WARN(x,y); y = 0; }
01693 if (x >= int(edgeMap->rows())) { WARN(x,y); x = edgeMap->rows()-1; }
01694 if (y >= int(edgeMap->cols())) { WARN(x,y); y = edgeMap->cols()-1; }
01695 #undef WARN
01696
01697 if (sdet_contour::debug_)
01698 vcl_cout << " intersecting (" << i << ")(" << vnl_math_abs(x-xe)
01699 << ' ' << vnl_math_abs(y-ye) << ")\n";
01700
01701 self_intersects = self_intersects ||
01702 ((edgeMap->get(x, y)==new_edge)&&
01703 ((vnl_math_abs(x-xe)>1)||(vnl_math_abs(y-ye)>1)));
01704
01705 if (!self_intersects)
01706 edgeMap->put(x, y,new_edge);
01707 }
01708
01709 if (sdet_contour::debug_&&self_intersects)
01710 vcl_cout << "merge endpoint touching junction - self-intersection\n";
01711
01712 if (self_intersects)
01713 return false;
01714
01715
01716 new_edge->set_v2(junction->cast_to_vertex());
01717 int x = int(junction->x()), y = int(junction->y());
01718 vertexMap->put(x, y, junction);
01719 vertexMap->put(int(endpt->x()), int(endpt->y()), NULL);
01720
01721 edgeMap->put(x, y, NULL);
01722
01723 return true;
01724 }
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737 int
01738 sdet_contour::FindJunctions(gevd_bufferxy& edgels,
01739 vcl_vector<vtol_edge_2d_sptr>& edges,
01740 vcl_vector<vtol_vertex_2d_sptr >& vertices)
01741 {
01742 vul_timer t;
01743
01744 if (!edges.size())
01745 {
01746 vcl_cerr << "sdet_contour::FindChains must precede sdet_contour::FindJunctions.\n";
01747 return 0;
01748 }
01749
01750 const float connect_fuzz = 2;
01751
01752 for (unsigned int i=0; i< edges.size(); i++)
01753 {
01754 vtol_edge_2d_sptr edge = edges[i];
01755 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
01756 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01757
01758 const int last = cxy->size()-1;
01759
01760
01761 if (vcl_fabs((*cxy)[0].x()-(*cxy)[last].x()) > connect_fuzz ||
01762 vcl_fabs((*cxy)[0].y()-(*cxy)[last].y()) > connect_fuzz)
01763 {
01764 int x = int((*cxy)[0].x()), y = int((*cxy)[0].y());
01765 vtol_vertex_2d_sptr v1 = vertexMap->get(x, y);
01766
01767 if (!v1)
01768 {
01769
01770
01771 v1 = new vtol_vertex_2d((*cxy)[0].x(), (*cxy)[0].y());
01772 vertexMap->put(x, y, v1);
01773 LookupTableInsert(vertices, v1);
01774 }
01775 else
01776 {
01777 edgeMap->put( x, y, NULL);
01778 }
01779
01780 edge->set_v1(v1->cast_to_vertex());
01781 if (sdet_contour::debug_)
01782 vcl_cout << "adding vertex (" << x << ' ' << y
01783 << ")(" << v1->numsup() << ")\n";
01784 x = int((*cxy)[last].x()), y = int((*cxy)[last].y());
01785
01786 vtol_vertex_2d_sptr v2 = vertexMap->get(x, y);
01787
01788 if (!v2)
01789 {
01790
01791
01792 v2 = new vtol_vertex_2d((*cxy)[last].x(), (*cxy)[last].y());
01793 vertexMap->put(x, y, v2);
01794 LookupTableInsert(vertices, v2);
01795 }
01796 else
01797 {
01798 edgeMap->put( x, y, NULL);
01799 }
01800
01801 edge->set_v2(v2->cast_to_vertex());
01802 if (sdet_contour::debug_)
01803 vcl_cout << "adding vertex (" << x << ' ' << y
01804 << ")(" << v2->numsup() << ")\n";
01805 }
01806 else
01807 fill_cycle_gap(cxy);
01808 }
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819 int jcycle = 0, jchain = 0;
01820 for (unsigned int i=0; i< vertices.size(); i++)
01821 {
01822
01823 vtol_vertex_2d_sptr endv = vertices[i];
01824 vtol_edge_2d_sptr weaker = NULL, stronger = NULL;
01825 int index;
01826 if (DetectJunction(endv, index, weaker, stronger, maxSpiral, edgels))
01827 {
01828 if (sdet_contour::debug_)
01829 vcl_cout << "detected junction near (" << endv->x() <<' '<< endv->y()
01830 << ")\n";
01831
01832 int old_x = int(endv->x()), old_y = int(endv->y());
01833
01834
01835
01836 if (!stronger->v1())
01837 {
01838
01839 vtol_edge_2d_sptr split = NULL;
01840 BreakCycle(endv, index, stronger, split);
01841 LookupTableReplace(edges, stronger, split);
01842
01843
01844
01845 update_edgel_chain(weaker, old_x, old_y, endv);
01846
01847 if (sdet_contour::debug_) {
01848 vcl_cout << "new position on cycle (" << endv->x() << ' '
01849 << endv->y() << ")\n";
01850 }
01851 jcycle++;
01852 }
01853 else if (weaker == stronger)
01854 {
01855 vtol_edge_2d_sptr straight = NULL, curled = NULL;
01856
01857
01858 LoopChain(endv, index, stronger, straight, curled);
01859
01860 LookupTableReplace(edges, stronger, straight);
01861 LookupTableInsert(edges, curled);
01862
01863 if (sdet_contour::debug_)
01864 vcl_cout << "new position on loop chain (" << endv->x()
01865 << ' ' << endv->y()<< ")\n";
01866 jchain++;
01867 }
01868 else
01869 {
01870 vtol_edge_2d_sptr longer = NULL, shorter = NULL;
01871 BreakChain(endv, index, stronger,longer, shorter);
01872 LookupTableReplace(edges, stronger, longer);
01873 LookupTableInsert(edges, shorter);
01874
01875
01876
01877 update_edgel_chain(weaker, old_x, old_y, endv);
01878 if (sdet_contour::debug_)
01879 vcl_cout << "old position on chain (" << old_x
01880 << ' ' << old_y
01881 << ") new position on chain (" << endv->x()
01882 << ' ' << endv->y()<< ")(" << endv->numsup() <<")\n";
01883
01884 jchain++;
01885 }
01886 }
01887 }
01888
01889 if (talkative_)
01890 vcl_cout << "Find junctions with "
01891 << jcycle << " cycles and " << jchain << " chains, with jump > "
01892 << minJump << " and maxSpiral " << maxSpiral << vcl_endl;
01893
01894 int dendpt = 0, dchain = 0;
01895
01896 for (unsigned int i=0; i< vertices.size(); i++)
01897 {
01898
01899
01900 vtol_vertex_2d_sptr end1 = vertices[i];
01901
01902
01903
01904
01905 if (end1 && end1->numsup() == 1 && !near_border(end1))
01906 {
01907 if (sdet_contour::debug_)
01908 vcl_cout << "merge target end1(" << end1->x() << ' '
01909 << end1->y() << ")\n";
01910
01911 vtol_vertex_2d_sptr end2 = DetectTouch(end1, maxSpiral);
01912 if (end2)
01913 {
01914
01915 if (end2->numsup() == 1)
01916 {
01917 vtol_edge_2d_sptr seg = DanglingEdge(end1);
01918
01919 if (seg == DanglingEdge(end2))
01920 {
01921 vtol_vertex_2d_sptr removed_vert = NULL;
01922 if (MergeEndPtsOfChain(end1, end2, removed_vert))
01923 {
01924 LookupTableRemove(vertices, removed_vert);
01925 if (sdet_contour::debug_)
01926 vcl_cout << "cycle endpt1=" << *end1 << vcl_endl
01927 << "cycle endpt2=" << *end2 << vcl_endl;
01928 dendpt++;
01929 }
01930 }
01931 else
01932 {
01933
01934 if (sdet_contour::debug_)
01935 vcl_cout << "endpt1=" << *end1 << vcl_endl
01936 << "endpt2=" << *end2 << vcl_endl;
01937
01938 vtol_edge_2d_sptr merge=NULL, longer=NULL, shorter=NULL;
01939
01940 MergeEndPtTouchingEndPt(end1, end2,
01941 merge, longer, shorter);
01942 if (sdet_contour::debug_)
01943 vcl_cout << "merge=" << *merge << vcl_endl
01944 << "longer=" << *longer << vcl_endl
01945 << "shorter=" << *shorter << vcl_endl
01946 << "merge.v1=" << *merge->v1() << vcl_endl
01947 << "merge.v2=" << *merge->v2() << vcl_endl;
01948
01949 LookupTableReplace(edges, longer, merge);
01950 LookupTableRemove(edges, shorter);
01951 LookupTableRemove(vertices, end1);
01952 LookupTableRemove(vertices, end2);
01953 dendpt += 2, dchain += 1;
01954 }
01955 }
01956 else
01957 {
01958
01959 if (sdet_contour::debug_)
01960 vcl_cout << "junction endpt1=" << *end1 << vcl_endl
01961 << "junction endpt2=" << *end2 << vcl_endl;
01962 vtol_edge_2d_sptr old_edge=NULL, new_edge=NULL;
01963 if (MergeEndPtTouchingJunction(end1, end2, old_edge, new_edge))
01964 {
01965 LookupTableReplace(edges, old_edge, new_edge);
01966 LookupTableRemove(vertices, end1);
01967 dendpt++;
01968 }
01969 }
01970 }
01971 }
01972 }
01973
01974 if (sdet_contour::debug_)
01975 vcl_cout << "Merge and delete " << dendpt
01976 << " end points and " << dchain << " edges\n";
01977 if (dchain)
01978 LookupTableCompress(edges);
01979 if (dendpt)
01980 LookupTableCompress(vertices);
01981
01982
01983 int ncycle = 0;
01984 for (unsigned int i=0; i< edges.size(); i++)
01985 {
01986
01987 vtol_edge_2d_sptr edge = edges[i];
01988 if (!edge->v1())
01989 {
01990 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
01991 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
01992
01993 const int last = cxy->size()-1;
01994 vtol_vertex_2d_sptr v =
01995 new vtol_vertex_2d(((*cxy)[0].x()+(*cxy)[last].x())/2,
01996 ((*cxy)[0].y()+(*cxy)[last].y())/2);
01997 edge->set_v1(v->cast_to_vertex()); edge->set_v2(v->cast_to_vertex());
01998 vertexMap->put(int(v->x()), int(v->y()), v);
01999 LookupTableInsert(vertices, v);
02000 ncycle++;
02001 }
02002 }
02003 if (sdet_contour::debug_)
02004 vcl_cout << "Create " << ncycle
02005 << " virtual end points for isolated cycles.\n";
02006
02007 if (talkative_)
02008 vcl_cout << "All junctions found in " << t.real() << " msecs.\n";
02009
02010 return vertices.size();
02011 }
02012
02013
02014
02015
02016
02017
02018
02019 void
02020 sdet_contour::SubPixelAccuracy(vcl_vector<vtol_edge_2d_sptr>& edges,
02021 vcl_vector<vtol_vertex_2d_sptr >& vertices,
02022 const gevd_bufferxy& locationx,
02023 const gevd_bufferxy& locationy)
02024 {
02025
02026 vul_timer t;
02027 if (talkative_)
02028 vcl_cout << "Insert subpixel accuracy into edges/vertices";
02029
02030
02031 for (unsigned int i=0; i< vertices.size(); i++)
02032 {
02033 vtol_vertex_2d_sptr vert = vertices[i];
02034 int x = int(vert->x()), y = int(vert->y());
02035 vert->set_x(x + floatPixel(locationx, x, y));
02036 vert->set_y(y + floatPixel(locationy, x, y));
02037 }
02038
02039
02040 for (unsigned int i=0; i< edges.size(); i++)
02041 {
02042 vtol_edge_2d_sptr edge = edges[i];
02043 if (!edge) continue;
02044 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
02045 if (!dc) continue;
02046 if (!dc->get_interpolator()) continue;
02047 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
02048 if (!cxy) continue;
02049
02050 for (unsigned int k = 0; k < cxy->size(); ++k)
02051 {
02052
02053 int x = int((*cxy)[k].x()), y = int((*cxy)[k].y());
02054 double tempx= (*cxy)[k].x()+ floatPixel( locationx, x, y);
02055 double tempy= (*cxy)[k].y()+ floatPixel( locationy, x, y);
02056 (*cxy)[k].set_x( tempx);
02057 (*cxy)[k].set_y( tempy);
02058 }
02059 }
02060
02061
02062
02063
02064
02065
02066
02067 if (talkative_)
02068 vcl_cout << ", in " << t.real() << " msecs.\n";
02069 }
02070
02071
02072
02073
02074
02075 vtol_edge_2d_sptr DigitalEdge(vtol_vertex_2d_sptr const& vs,
02076 vtol_vertex_2d_sptr const& ve)
02077 {
02078 vsol_curve_2d_sptr dc= new vdgl_digital_curve(vs->point(), ve->point());
02079 return new vtol_edge_2d(vs, ve, dc);
02080 }
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095 void
02096 sdet_contour::InsertBorder(vcl_vector<vtol_edge_2d_sptr>& edges,
02097 vcl_vector<vtol_vertex_2d_sptr >& vertices)
02098 {
02099
02100 vul_timer t;
02101 bool merge = true;
02102
02103 vcl_vector<vtol_vertex_2d_sptr > xmin_verts;
02104 vcl_vector<vtol_vertex_2d_sptr > xmax_verts;
02105 vcl_vector<vtol_vertex_2d_sptr > ymin_verts;
02106 vcl_vector<vtol_vertex_2d_sptr > ymax_verts;
02107
02108 if (talkative_)
02109 vcl_cout << "Insert virtual border to enforce closure";
02110
02111
02112 const int rmax = FRAME;
02113 const int xmax = vertexMap->rows()-rmax-1;
02114 const int ymax = vertexMap->columns()-rmax-1;
02115 int cx[] = {rmax, xmax, rmax, xmax};
02116 int cy[] = {rmax, ymax, ymax, rmax};
02117 int d;
02118
02119
02120 vtol_vertex_2d_sptr V00 = new vtol_vertex_2d(rmax, rmax);
02121 vtol_vertex_2d_sptr V01 = new vtol_vertex_2d(rmax, ymax);
02122 vtol_vertex_2d_sptr V10 = new vtol_vertex_2d(xmax, rmax);
02123 vtol_vertex_2d_sptr V11 = new vtol_vertex_2d(xmax, ymax);
02124 xmin_verts.push_back(V00);
02125 xmax_verts.push_back(V10);
02126 ymin_verts.push_back(V00);
02127 ymax_verts.push_back(V01);
02128
02129 for (d = 0; d < 2; d++)
02130 {
02131 int x, y = cy[d];
02132 for (x = rmax; x<=xmax; x++)
02133 {
02134 vtol_vertex_2d_sptr v = vertexMap->get(x, y);
02135 if (v)
02136 vertexMap->put(x, y, NULL);
02137 else continue;
02138 if (d)
02139 ymax_verts.push_back(v);
02140 else
02141 ymin_verts.push_back(v);
02142 }
02143 }
02144
02145 for (d = 0; d < 2; d++)
02146 {
02147 int x = cx[d], y;
02148 for (y = rmax; y<=ymax; y++)
02149 {
02150 vtol_vertex_2d_sptr v = vertexMap->get(x, y);
02151 if (v)
02152 vertexMap->put(x, y, NULL);
02153 else continue;
02154 if (d)
02155 xmax_verts.push_back(v);
02156 else
02157 xmin_verts.push_back(v);
02158 }
02159 }
02160
02161 xmin_verts.push_back(V01);
02162 xmax_verts.push_back(V11);
02163 ymin_verts.push_back(V10);
02164 ymax_verts.push_back(V11);
02165
02166
02167
02168 for (d = 0; d < 2; d++)
02169 {
02170 vcl_vector<vtol_vertex_2d_sptr >* verts = &ymin_verts;
02171 if (d)
02172 verts = &ymax_verts;
02173 int len = (*verts).size();
02174 if (len<3) continue;
02175
02176 vtol_vertex_2d_sptr pre_v = (*verts)[0];
02177 vtol_vertex_2d_sptr v = (*verts)[1];
02178 int x = int(v->x());
02179 int pre_x = int(pre_v->x());
02180 if (merge&&(x-pre_x)<3)
02181 {
02182 vtol_vertex_sptr pv = pre_v->cast_to_vertex(),
02183 vv = v->cast_to_vertex();
02184 btol_vertex_algs::merge_superiors(pv, vv);
02185
02186 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= verts->begin();
02187 it!= verts->end(); ++it)
02188 {
02189 if (*it == v)
02190 {
02191 verts->erase( it);
02192 break;
02193 }
02194 }
02195 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= vertices.begin();
02196 it!= vertices.end(); ++it)
02197 {
02198 if (*it == v)
02199 {
02200 vertices.erase( it);
02201 break;
02202 }
02203 }
02204 len--;
02205 }
02206
02207 pre_v = (*verts)[len-2];
02208 v = (*verts)[len-1];
02209 pre_x = int(pre_v->x());
02210 if (merge&&(xmax+rmax-pre_x)<3)
02211 {
02212 vtol_vertex_sptr pv = pre_v->cast_to_vertex(),
02213 vv = v->cast_to_vertex();
02214 btol_vertex_algs::merge_superiors(pv, vv);
02215
02216 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= verts->begin();
02217 it!= verts->end(); ++it)
02218 {
02219 if (*it == pre_v)
02220 {
02221 verts->erase( it);
02222 break;
02223 }
02224 }
02225 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= vertices.begin();
02226 it!= vertices.end(); ++it)
02227 {
02228 if (*it == pre_v)
02229 {
02230 vertices.erase( it);
02231 break;
02232 }
02233 }
02234 len--;
02235 }
02236 }
02237
02238
02239 for (d = 0; d < 2; d++)
02240 {
02241 vcl_vector<vtol_vertex_2d_sptr >* verts = &xmin_verts;
02242 if (d)
02243 verts = &xmax_verts;
02244 int len = (*verts).size();
02245 if (len<3) continue;
02246
02247 vtol_vertex_2d_sptr pre_v = (*verts)[0];
02248 vtol_vertex_2d_sptr v = (*verts)[1];
02249
02250 int y = int(v->y()), pre_y = int(pre_v->y());
02251 if (merge&&(y-pre_y)<3)
02252 {
02253 vtol_vertex_sptr pv = pre_v->cast_to_vertex(),
02254 vv = v->cast_to_vertex();
02255 btol_vertex_algs::merge_superiors(pv, vv);
02256 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= verts->begin();
02257 it!= verts->end(); ++it)
02258 {
02259 if (*it == v)
02260 {
02261 verts->erase( it);
02262 break;
02263 }
02264 }
02265 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= vertices.begin();
02266 it!= vertices.end(); ++it)
02267 {
02268 if (*it == v)
02269 {
02270 vertices.erase( it);
02271 break;
02272 }
02273 }
02274 len--;
02275 }
02276
02277 pre_v = (*verts)[len-2];
02278 v = (*verts)[len-1];
02279 pre_y = int(pre_v->y());
02280 if (merge&&(ymax+rmax-pre_y)<3)
02281 {
02282 vtol_vertex_sptr pv = pre_v->cast_to_vertex(),
02283 vv = v->cast_to_vertex();
02284 btol_vertex_algs::merge_superiors(pv, vv);
02285 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= verts->begin();
02286 it!= verts->end(); ++it)
02287 {
02288 if (*it == pre_v)
02289 {
02290 verts->erase( it);
02291 break;
02292 }
02293 }
02294 for (vcl_vector<vtol_vertex_2d_sptr >::iterator it= vertices.begin();
02295 it!= vertices.end(); ++it)
02296 {
02297 if (*it == pre_v)
02298 {
02299 vertices.erase( it);
02300 break;
02301 }
02302 }
02303 len--;
02304 }
02305 }
02306
02307
02308 float xmi = 0, xmx = float(xmax + rmax);
02309 float ymi = 0, ymx = float(ymax + rmax);
02310 for (unsigned int iv=1; iv+1<xmin_verts.size(); ++iv)
02311 {
02312 vtol_vertex_2d_sptr v = xmin_verts[iv];
02313 if (!v) continue;
02314 vtol_vertex_2d_sptr vp = new vtol_vertex_2d(xmi, v->y());
02315 vertices.push_back(vp);
02316 xmin_verts[iv] = vp;
02317
02318 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
02319 edges.push_back(e);
02320 }
02321
02322 for (unsigned int iv=1; iv+1<xmax_verts.size(); ++iv)
02323 {
02324 vtol_vertex_2d_sptr v = xmax_verts[iv];
02325 if (!v) continue;
02326 vtol_vertex_2d_sptr vp = new vtol_vertex_2d( xmx, v->y());
02327 vertices.push_back(vp);
02328 xmax_verts[iv] = vp;
02329 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
02330 edges.push_back(e);
02331 }
02332 for (unsigned int iv=1; iv+1<ymin_verts.size(); ++iv)
02333 {
02334 vtol_vertex_2d_sptr v = ymin_verts[iv];
02335 if (!v) continue;
02336 vtol_vertex_2d_sptr vp = new vtol_vertex_2d(v->x(), ymi);
02337 vertices.push_back(vp);
02338 ymin_verts[iv] = vp;
02339 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
02340 edges.push_back(e);
02341 }
02342 for (unsigned int iv=1; iv+1<ymax_verts.size(); ++iv)
02343 {
02344 vtol_vertex_2d_sptr v = ymax_verts[iv];
02345 if (!v) continue;
02346 vtol_vertex_2d_sptr vp = new vtol_vertex_2d( v->x(), ymx);
02347 vertices.push_back(vp);
02348 ymax_verts[iv] = vp;
02349 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
02350 edges.push_back(e);
02351 }
02352 V00->set_x(0); V00->set_y(0); vertices.push_back(V00);
02353 V01->set_x(0); V01->set_y(ymax+rmax); vertices.push_back(V01);
02354 V10->set_x(xmax+rmax); V10->set_y(0); vertices.push_back(V10);
02355 V11->set_x(xmax+rmax); V11->set_y(ymax+rmax); vertices.push_back(V11);
02356
02357
02358
02359
02360 for (d = 0; d < 2; ++d)
02361 {
02362 vcl_vector<vtol_vertex_2d_sptr >* verts = &ymin_verts;
02363 if (d)
02364 verts = &ymax_verts;
02365 unsigned int len = (*verts).size();
02366 if (len<2)
02367 {
02368 vcl_cout <<"In sdet_contour::InsertBorder() - too few vertices\n";
02369 return;
02370 }
02371 for (unsigned int i=0; i+1<len; ++i)
02372 {
02373 vtol_vertex_2d_sptr v = (*verts)[i];
02374 vtol_vertex_2d_sptr vp = (*verts)[i+1];
02375 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
02376 edges.push_back(e);
02377 }
02378 }
02379
02380 for (d = 0; d < 2; ++d)
02381 {
02382 vcl_vector<vtol_vertex_2d_sptr >* verts = &xmin_verts;
02383 if (d)
02384 verts = &xmax_verts;
02385 unsigned int len = (*verts).size();
02386 if (len<2)
02387 {
02388 vcl_cout <<"In sdet_contour::InsertBorder() - too few vertices\n";
02389 return;
02390 }
02391 for (unsigned int i = 0; i+1<len; ++i)
02392 {
02393 vtol_vertex_2d_sptr v = (*verts)[i];
02394 vtol_vertex_2d_sptr vp = (*verts)[i+1];
02395 vtol_edge_2d_sptr e = DigitalEdge(v, vp);
02396 edges.push_back(e);
02397 }
02398 }
02399
02400 if (talkative_)
02401 vcl_cout << ", in " << t.real() << " msecs.\n";
02402 }
02403
02404
02405
02406
02407
02408
02409
02410 void
02411 EqualizeElements(double* elmts, int n, double v1, double v2)
02412 {
02413 double p0 = elmts[0], p1 = elmts[1], p2 = elmts[2];
02414 elmts[0] = (v1 + p1) / 2;
02415 for (int i = 1; i+2 < n; ++i)
02416 {
02417 elmts[i] = (p0 + p2)/2;
02418 p0 = p1; p1 = p2; p2 = elmts[i+2];
02419 }
02420 if (n>1) elmts[n-2] = (p0 + p2)/2;
02421 if (n>0) elmts[n-1] = (p1 + v2)/2;
02422 }
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435 void
02436 sdet_contour::EqualizeSpacing(vcl_vector<vtol_edge_2d_sptr>& chains)
02437 {
02438 vul_timer t;
02439
02440 if (talkative_)
02441 vcl_cout << "Equalize the spacing between pixels in chains\n";
02442
02443 for (unsigned int i= 0; i< chains.size(); ++i)
02444 {
02445 vtol_edge_2d_sptr e = chains[i];
02446 vdgl_digital_curve_sptr dc = e->curve()->cast_to_vdgl_digital_curve();
02447 const int len = dc->get_interpolator()->get_edgel_chain()->size();
02448 if (len > 2*MINLENGTH)
02449 {
02450 vtol_vertex_sptr v1 = e->v1(), v2 = e->v2();
02451
02452 vcl_vector<double> cx(len);
02453 vcl_vector<double> cy(len);
02454
02455 for (int qq=0; qq<len; ++qq)
02456 {
02457 vdgl_edgel e= dc->get_interpolator()->get_edgel_chain()->edgel( qq);
02458 cx[qq]= e.x();
02459 cy[qq]= e.y();
02460 }
02461
02462 EqualizeElements(&cx[0], len, v1->cast_to_vertex_2d()->x(), v2->cast_to_vertex_2d()->x());
02463 EqualizeElements(&cy[0], len, v1->cast_to_vertex_2d()->y(), v2->cast_to_vertex_2d()->y());
02464
02465 for (int qq=0; qq<len; ++qq)
02466 {
02467 vdgl_edgel e( cx[qq], cy[qq]);
02468 dc->get_interpolator()->get_edgel_chain()->set_edgel( qq, e);
02469 }
02470 }
02471 }
02472 if (talkative_)
02473 vcl_cout << ", in " << t.real() << " msecs.\n";
02474 }
02475
02476
02477
02478
02479
02480
02481
02482
02483 void
02484 sdet_contour::Translate(vcl_vector<vtol_edge_2d_sptr>& edges,
02485 vcl_vector<vtol_vertex_2d_sptr >& vertices,
02486 float tx, float ty)
02487 {
02488 vul_timer t;
02489
02490 if (talkative_)
02491 vcl_cout << "Translate edges/vertices\n";
02492
02493 for (unsigned int i=0; i< vertices.size(); ++i)
02494 {
02495 vtol_vertex_2d_sptr vert = vertices[i];
02496 vert->set_x(vert->x() + tx);
02497 vert->set_y(vert->y() + ty);
02498 }
02499 for (unsigned int i=0; i< edges.size(); ++i)
02500 {
02501 vtol_edge_2d_sptr edge = edges[i];
02502 vdgl_digital_curve_sptr dc = edge->curve()->cast_to_vdgl_digital_curve();
02503
02504 vdgl_edgel_chain_sptr cxy= dc->get_interpolator()->get_edgel_chain();
02505 for (unsigned int k = 0; k < cxy->size(); ++k)
02506 {
02507 vdgl_edgel e= (*cxy)[k];
02508
02509 e.set_x( e.x()+tx);
02510 e.set_y( e.y()+ty);
02511
02512 cxy->set_edgel( k, e);
02513 }
02514 }
02515
02516 if (talkative_)
02517 vcl_cout << ", in " << t.real() << " msecs.\n";
02518 }
02519
02520
02521
02522
02523
02524
02525 void
02526 sdet_contour::ClearNetwork(vcl_vector<vtol_edge_2d_sptr>*& edges,
02527 vcl_vector<vtol_vertex_2d_sptr >*& vertices)
02528 {
02529 delete edges; edges = NULL;
02530 delete vertices; vertices = NULL;
02531 }
02532
02533
02534
02535
02536
02537
02538
02539 void
02540 sdet_contour::SetEdgelData(gevd_bufferxy& grad_mag, gevd_bufferxy& angle, vcl_vector<vtol_edge_2d_sptr>& edges)
02541 {
02542 for (unsigned int i=0; i< edges.size(); ++i)
02543 {
02544 vtol_edge_2d_sptr e = edges[i];
02545 vdgl_digital_curve_sptr dc= e->curve()->cast_to_vdgl_digital_curve();
02546
02547 if (dc)
02548 {
02549 vdgl_edgel_chain_sptr xypos= dc->get_interpolator()->get_edgel_chain();
02550
02551 int len = xypos->size();
02552
02553 for (int i = 0; i < len; ++i)
02554 {
02555 int ix = int((*xypos)[i].x());
02556 int iy = int((*xypos)[i].y());
02557
02558
02559
02560 if (iy < 0 || ix < 0 ||
02561 ix >= grad_mag.GetSizeX() ||
02562 iy >= grad_mag.GetSizeY())
02563 {
02564 vcl_cerr << "*********** ERROR : (ix, iy) = ("
02565 << ix << ", " << iy << ")\n";
02566 if (ix < 0) ix = 0;
02567 if (iy < 0) iy = 0;
02568 if (ix >= grad_mag.GetSizeX()) ix = grad_mag.GetSizeX()-1;
02569 if (iy >= grad_mag.GetSizeY()) iy = grad_mag.GetSizeY()-1;
02570 }
02571
02572 (*xypos)[i].set_grad( floatPixel( grad_mag, ix, iy));
02573 (*xypos)[i].set_theta( floatPixel( angle, ix, iy));
02574 #if 0
02575 gr[i] = floatPixel(grad_mag, ix, iy);
02576 th[i] = floatPixel(angle, ix, iy);
02577 #endif
02578 }
02579 }
02580 }
02581 }
02582
02583
02584
02585
02586
02587 void
02588 sdet_contour::LookupTableInsert(vcl_vector<vtol_edge_2d_sptr>& set,
02589 vtol_edge_2d_sptr elmt)
02590 {
02591 elmt->set_id(set.size());
02592 set.push_back(elmt);
02593 }
02594
02595
02596
02597 void
02598 sdet_contour::LookupTableInsert(vcl_vector<vtol_vertex_2d_sptr >& set,
02599 vtol_vertex_2d_sptr elmt)
02600 {
02601 elmt->set_id(set.size());
02602 set.push_back(elmt);
02603 }
02604
02605
02606
02607
02608 void
02609 sdet_contour::LookupTableReplace(vcl_vector<vtol_edge_2d_sptr>& set,
02610 vtol_edge_2d_sptr deleted, vtol_edge_2d_sptr inserted)
02611 {
02612 const int i = deleted->get_id();
02613 inserted->set_id(i);
02614 set[i] = inserted;
02615 btol_edge_algs::unlink_all_inferiors_twoway(deleted);
02616 }
02617
02618
02619
02620 void
02621 sdet_contour::LookupTableReplace(vcl_vector<vtol_vertex_2d_sptr >& set,
02622 vtol_vertex_2d_sptr deleted, vtol_vertex_2d_sptr inserted)
02623 {
02624 const int i = deleted->get_id();
02625 inserted->set_id(i);
02626 set[i] = inserted;
02627 }
02628
02629
02630
02631
02632 void
02633 sdet_contour::LookupTableRemove(vcl_vector<vtol_edge_2d_sptr>& set,
02634 vtol_edge_2d_sptr elmt)
02635 {
02636 btol_edge_algs::unlink_all_inferiors_twoway(elmt);
02637 set[elmt->get_id()] = NULL;
02638 }
02639
02640
02641
02642 void
02643 sdet_contour::LookupTableRemove(vcl_vector<vtol_vertex_2d_sptr >& set,
02644 vtol_vertex_2d_sptr elmt)
02645 {
02646 set[elmt->get_id()] = NULL;
02647 }
02648
02649
02650
02651 void
02652 sdet_contour::LookupTableCompress(vcl_vector<vtol_edge_2d_sptr>& set)
02653 {
02654 vcl_vector<vtol_edge_2d_sptr> temp;
02655
02656 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = set.begin();
02657 eit != set.end(); eit++)
02658 if (*eit)
02659 temp.push_back(*eit);
02660 int i = 0;
02661 set.clear();
02662 for (vcl_vector<vtol_edge_2d_sptr>::iterator eit = temp.begin();
02663 eit != temp.end(); eit++, i++)
02664 {
02665 (*eit)->set_id(i);
02666 set.push_back(*eit);
02667 }
02668 }
02669
02670
02671 void
02672 sdet_contour::LookupTableCompress(vcl_vector<vtol_vertex_2d_sptr>& set)
02673 {
02674 vcl_vector<vtol_vertex_2d_sptr> temp;
02675
02676 for (vcl_vector<vtol_vertex_2d_sptr>::iterator vit = set.begin();
02677 vit != set.end(); vit++)
02678 if (*vit)
02679 temp.push_back(*vit);
02680 int i = 0;
02681 set.clear();
02682 for (vcl_vector<vtol_vertex_2d_sptr>::iterator vit = temp.begin();
02683 vit != temp.end(); vit++, i++)
02684 {
02685 (*vit)->set_id(i);
02686 set.push_back(*vit);
02687 }
02688 }