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