00001 #include "bbgm_features.h"
00002
00003
00004 #include <vnl/io/vnl_io_vector_fixed.h>
00005 #include <vgl/vgl_point_2d.h>
00006 #include <vgl/algo/vgl_convex_hull_2d.h>
00007 #include <brip/brip_line_generator.h>
00008
00009
00010
00011
00012
00013
00014
00015 unsigned bbgm_mask_feature::uid_ = 0;
00016
00017 unsigned bbgm_mask_feature::ni() const
00018 {
00019 if (mid_ == brip_rect_mask::ntypes||aid_ == brip_rect_mask::ntypes)
00020 return 0;
00021 brip_rect_mask m(static_cast<brip_rect_mask::mask_id>(mid_));
00022 m.set_angle_id(static_cast<brip_rect_mask::ang_id>(aid_));
00023 return m.ni();
00024 }
00025
00026 unsigned bbgm_mask_feature::nj() const
00027 {
00028 if (mid_ == brip_rect_mask::ntypes||aid_ == brip_rect_mask::ntypes)
00029 return 0;
00030 brip_rect_mask m(static_cast<brip_rect_mask::mask_id>(mid_));
00031 m.set_angle_id(static_cast<brip_rect_mask::ang_id>(aid_));
00032 return m.nj();
00033 }
00034
00035 vcl_vector<vgl_point_2d<unsigned short> > bbgm_mask_feature::
00036 pixels(unsigned i, unsigned j)
00037 {
00038 vcl_vector<vgl_point_2d<unsigned short> > pix;
00039 if (mid_ == brip_rect_mask::ntypes||aid_ == brip_rect_mask::ntypes)
00040 return pix;
00041 brip_rect_mask m(static_cast<brip_rect_mask::mask_id>(mid_));
00042 m.set_angle_id(static_cast<brip_rect_mask::ang_id>(aid_));
00043 unsigned ni = m.ni(), nj = m.nj();
00044 int ri = (ni-1)/2, rj = (nj-1)/2;
00045 for (int jj = -rj; jj<=rj; ++jj) {
00046 for (int ii = -ri; ii<=ri; ++ii) {
00047 if (m(ii, jj)>0) {
00048 unsigned short pi = static_cast<unsigned short>(ii+i);
00049 unsigned short pj = static_cast<unsigned short>(jj+j);
00050 if (pi>=320||pj>=180) {
00051 vcl_cout << "Write out of bounds in mask(" << pi << ' ' << pj << ")\n";
00052 continue;
00053 }
00054 pix.push_back(vgl_point_2d<unsigned short>(pi, pj));
00055 }
00056 }
00057 }
00058 return pix;
00059 }
00060
00061
00062
00063
00064 vcl_string bbgm_mask_feature::is_a() const
00065 {
00066 return "bbgm_mask_feature";
00067 }
00068
00069
00070 bbgm_mask_feature* bbgm_mask_feature::clone() const
00071 {
00072 return new bbgm_mask_feature(*this);
00073 }
00074
00075
00076
00077
00078 short bbgm_mask_feature::version() const
00079 {
00080 return 1;
00081 }
00082
00083
00084
00085
00086 void bbgm_mask_feature::b_write(vsl_b_ostream &os) const
00087 {
00088 vsl_b_write(os, version());
00089 vsl_b_write(os, mid_);
00090 vsl_b_write(os, aid_);
00091 vsl_b_write(os, p_);
00092 }
00093
00094
00095
00096 void bbgm_mask_feature::b_read(vsl_b_istream &is)
00097 {
00098 if (!is)
00099 return;
00100 short ver;
00101 vsl_b_read(is, ver);
00102 switch (ver)
00103 {
00104 case 1:
00105 vsl_b_read(is, mid_);
00106 vsl_b_read(is, aid_);
00107 vsl_b_read(is, p_);
00108 break;
00109 default:
00110 vcl_cerr << "bbgm_mask_feature: unknown I/O version " << ver << '\n';
00111 }
00112 }
00113
00114
00115 void vsl_b_write(vsl_b_ostream &os, const bbgm_mask_feature& b)
00116 {
00117 b.b_write(os);
00118 }
00119
00120
00121 void vsl_b_read(vsl_b_istream &is, bbgm_mask_feature& b)
00122 {
00123 bbgm_mask_feature temp;
00124 temp.b_read(is);
00125 b = temp;
00126 }
00127
00128 void vsl_print_summary(vcl_ostream& , const bbgm_mask_feature & )
00129 {
00130 vcl_cerr << "bbgm_mask_feature::vsl_print_summary not implemented\n";
00131 }
00132
00133
00134
00135
00136
00137 unsigned bbgm_mask_pair_feature::uid_ = 0;
00138
00139
00140 vcl_vector<vgl_point_2d<unsigned short> > bbgm_mask_pair_feature::pixels()
00141 {
00142 vcl_vector<vgl_point_2d<unsigned short> > pixp;
00143
00144 float isf = static_cast<float>(i0_), jsf = static_cast<float>(j0_);
00145
00146 float ief = static_cast<float>(i1_), jef = static_cast<float>(j1_);
00147 float lif = 0, ljf = 0;
00148 bool init = true;
00149 while (brip_line_generator::generate(init, isf, jsf, ief, jef,
00150 lif, ljf))
00151 {
00152
00153 unsigned ili = static_cast<unsigned short>(lif),
00154 ilj = static_cast<unsigned short>(ljf);
00155 if (ili>=320||ilj>=180) {
00156 vcl_cout << "Write out of bounds in mask pair(" << ili << ' ' << ilj << ")\n";
00157 continue;
00158 }
00159 pixp.push_back(vgl_point_2d<unsigned short>(ili, ilj));
00160 }
00161
00162 bbgm_mask_feature mf0(mid_, ang0_), mf1(mid_, ang1_);
00163 vcl_vector<vgl_point_2d<unsigned short> > pixm0 = mf0.pixels(i0_, j0_);
00164 vcl_vector<vgl_point_2d<unsigned short> > pixm1 = mf0.pixels(i1_, j1_);
00165 vcl_vector<vgl_point_2d<unsigned short> > pix;
00166 for (vcl_vector<vgl_point_2d<unsigned short> >::iterator pit = pixp.begin();
00167 pit!= pixp.end(); ++pit)
00168 pix.push_back(*pit);
00169
00170 for (vcl_vector<vgl_point_2d<unsigned short> >::iterator pit = pixm0.begin();
00171 pit!= pixm0.end(); ++pit) {
00172 bool found = false;
00173 for (vcl_vector<vgl_point_2d<unsigned short> >::iterator pot = pix.begin();
00174 pot != pix.end()&&!found; ++pot)
00175 if ((*pot)==(*pit)) {
00176 found = true;
00177 }
00178 if (!found) pix.push_back(*pit);
00179 }
00180 for (vcl_vector<vgl_point_2d<unsigned short> >::iterator pit = pixm1.begin();
00181 pit!= pixm1.end(); ++pit) {
00182 bool found = false;
00183 for (vcl_vector<vgl_point_2d<unsigned short> >::iterator pot = pix.begin();
00184 pot != pix.end()&&!found; ++pot)
00185 if ((*pot)==(*pit)) {
00186 found = true;
00187 }
00188 if (!found) pix.push_back(*pit);
00189 }
00190 return pix;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199 vcl_string bbgm_mask_pair_feature::is_a() const
00200 {
00201 return "bbgm_mask_pair_feature";
00202 }
00203
00204
00205 bbgm_mask_pair_feature* bbgm_mask_pair_feature::clone() const
00206 {
00207 return new bbgm_mask_pair_feature(*this);
00208 }
00209
00210
00211
00212
00213 short bbgm_mask_pair_feature::version() const
00214 {
00215 return 1;
00216 }
00217
00218
00219
00220
00221 void bbgm_mask_pair_feature::b_write(vsl_b_ostream &os) const
00222 {
00223 vsl_b_write(os, version());
00224 vsl_b_write(os, static_cast<unsigned>(mid_));
00225 vsl_b_write(os, static_cast<unsigned>(ang0_));
00226 vsl_b_write(os, static_cast<unsigned>(ang1_));
00227 vsl_b_write(os, i0_);
00228 vsl_b_write(os, j0_);
00229 vsl_b_write(os, i1_);
00230 vsl_b_write(os, j1_);
00231 vsl_b_write(os, id0_);
00232 vsl_b_write(os, id1_);
00233 vsl_b_write(os, p_);
00234 }
00235
00236
00237
00238 void bbgm_mask_pair_feature::b_read(vsl_b_istream &is)
00239 {
00240 if (!is)
00241 return;
00242 short ver;
00243 vsl_b_read(is, ver);
00244 switch (ver)
00245 {
00246 case 1:
00247 unsigned temp0, temp1, temp2;
00248 vsl_b_read(is, temp0);
00249 vsl_b_read(is, temp1);
00250 vsl_b_read(is, temp2);
00251 vsl_b_read(is, i0_);
00252 vsl_b_read(is, j0_);
00253 vsl_b_read(is, i1_);
00254 vsl_b_read(is, j1_);
00255 vsl_b_read(is, id0_);
00256 vsl_b_read(is, id1_);
00257 vsl_b_read(is, p_);
00258 mid_ = static_cast<brip_rect_mask::mask_id>(temp0);
00259 ang0_ = static_cast<brip_rect_mask::ang_id>(temp1);
00260 ang1_ = static_cast<brip_rect_mask::ang_id>(temp2);
00261 break;
00262 default:
00263 vcl_cerr << "bbgm_mask_pair_feature: unknown I/O version " << ver << '\n';
00264 break;
00265 }
00266 }
00267
00268
00269 void vsl_b_write(vsl_b_ostream &os, const bbgm_mask_pair_feature& b)
00270 {
00271 b.b_write(os);
00272 }
00273
00274
00275 void vsl_b_read(vsl_b_istream &is, bbgm_mask_pair_feature& b)
00276 {
00277 bbgm_mask_pair_feature temp;
00278 temp.b_read(is);
00279 b = temp;
00280 }
00281
00282 void vsl_print_summary(vcl_ostream& , const bbgm_mask_pair_feature& )
00283 {
00284 vcl_cerr << "bbgm_mask_pair_feature::vsl_print_summary not implemented\n";
00285 }
00286
00287
00288
00289
00290
00291 unsigned bbgm_pair_group_feature::uid_ = 0;
00292
00293
00294 bbgm_pair_group_feature::
00295 bbgm_pair_group_feature(bbgm_mask_pair_feature const& mp)
00296 {
00297 id_ = mp.id();
00298 mid_ = mp.mask_id();
00299 pairs_.insert(mp);
00300 unsigned short ci, cj;
00301 mp.center(ci, cj);
00302 ci_ = ci; cj_ = cj;
00303 p_ = mp();
00304 }
00305
00306
00307 vgl_box_2d<unsigned> bbgm_pair_group_feature::bounding_box() const
00308 {
00309 vgl_box_2d<unsigned> box;
00310 if (!pairs_.size())
00311 return box;
00312 vcl_set<bbgm_mask_pair_feature, fless >::const_iterator vit;
00313 for (vit=pairs_.begin(); vit != pairs_.end(); ++vit)
00314 {
00315 unsigned short ci, cj;
00316 vit->center(ci, cj);
00317 vgl_point_2d<unsigned> p(ci, cj);
00318 box.add(p);
00319 }
00320 return box;
00321 }
00322
00323 vgl_polygon<double> bbgm_pair_group_feature::convex_hull() const
00324 {
00325 vcl_vector<vgl_point_2d<double> > points;
00326 vcl_set<bbgm_mask_pair_feature, fless >::const_iterator vit;
00327 for (vit=pairs_.begin(); vit != pairs_.end(); ++vit)
00328 {
00329 unsigned short ci, cj;
00330 vit->center(ci, cj);
00331 vgl_point_2d<double> p(ci, cj);
00332 points.push_back(p);
00333 }
00334 if (points.size()<3)
00335 return vgl_polygon<double>();
00336 vgl_convex_hull_2d<double> h(points);
00337
00338 return h.hull();
00339 }
00340
00341 vcl_vector<vgl_point_2d<unsigned short> > bbgm_pair_group_feature::pixels()
00342 {
00343 vcl_vector<vgl_point_2d<unsigned short> > pix;
00344 vcl_set<bbgm_mask_pair_feature, fless >::iterator pit = pairs_.begin();
00345 for (; pit!=pairs_.end(); ++pit)
00346 {
00347 bbgm_mask_pair_feature mpf = *pit;
00348 vcl_vector<vgl_point_2d<unsigned short> > pixp = mpf.pixels();
00349 for (vcl_vector<vgl_point_2d<unsigned short> >::iterator pxt = pixp.begin();
00350 pxt!= pixp.end(); ++pxt) {
00351 bool found = false;
00352 for (vcl_vector<vgl_point_2d<unsigned short> >::iterator pot = pix.begin();
00353 pot != pix.end()&&!found; ++pot)
00354 if ((*pot)==(*pxt)) {
00355 found = true;
00356 }
00357 if (!found) pix.push_back(*pxt);
00358 }
00359
00360 unsigned short im, jm;
00361 mpf.center(im, jm);
00362
00363 float isf = static_cast<float>(ci_), jsf = static_cast<float>(cj_);
00364
00365 float ief = static_cast<float>(im), jef = static_cast<float>(jm);
00366 float lif = 0, ljf = 0;
00367 bool init = true;
00368 while (brip_line_generator::generate(init, isf, jsf, ief, jef,
00369 lif, ljf))
00370 {
00371
00372 unsigned short ili = static_cast<unsigned short>(lif),
00373 ilj = static_cast<unsigned short>(ljf);
00374 vgl_point_2d<unsigned short> pt(ili, ilj);
00375 if (ili>=320||ilj>=180) {
00376 vcl_cout << "Write out of bounds in pair group(" << ili << ' ' << ilj << ")\n";
00377 continue;
00378 }
00379 bool found = false;
00380 for (vcl_vector<vgl_point_2d<unsigned short> >::iterator pot = pix.begin();
00381 pot != pix.end()&&!found; ++pot)
00382 if ((*pot)==pt) {
00383 found = true;
00384 }
00385 if (!found) pix.push_back(pt);
00386 }
00387 }
00388 return pix;
00389 }
00390
00391
00392
00393
00394
00395 vcl_string bbgm_pair_group_feature::is_a() const
00396 {
00397 return "bbgm_pair_group_feature";
00398 }
00399
00400
00401 bbgm_pair_group_feature* bbgm_pair_group_feature::clone() const
00402 {
00403 return new bbgm_pair_group_feature(*this);
00404 }
00405
00406
00407
00408
00409 short bbgm_pair_group_feature::version() const
00410 {
00411 return 1;
00412 }
00413
00414
00415
00416
00417 void bbgm_pair_group_feature::b_write(vsl_b_ostream &os) const
00418 {
00419 vsl_b_write(os, version());
00420 vsl_b_write(os, static_cast<unsigned>(mid_));
00421 vsl_b_write(os, ci_);
00422 vsl_b_write(os, cj_);
00423
00424
00425 unsigned n = pairs_.size();
00426 vsl_b_write(os, n);
00427 vcl_set<bbgm_mask_pair_feature, fless>::const_iterator vit;
00428 vit = pairs_.begin();
00429 for (; vit!= pairs_.end(); ++vit)
00430 vsl_b_write(os, *vit);
00431 vsl_b_write(os, p_);
00432 }
00433
00434
00435
00436 void bbgm_pair_group_feature::b_read(vsl_b_istream &is)
00437 {
00438 if (!is)
00439 return;
00440 short ver;
00441 vsl_b_read(is, ver);
00442 switch (ver)
00443 {
00444 case 1:
00445 unsigned temp;
00446 vsl_b_read(is, temp);
00447 vsl_b_read(is, ci_);
00448 vsl_b_read(is, cj_);
00449 unsigned n;
00450 vsl_b_read(is, n);
00451 for (unsigned i = 0; i<n; ++i) {
00452 bbgm_mask_pair_feature mpf;
00453 vsl_b_read(is, mpf);
00454 pairs_.insert(mpf);
00455 }
00456 vsl_b_read(is, p_);
00457 mid_ = static_cast<brip_rect_mask::mask_id>(temp);
00458 break;
00459 default:
00460 vcl_cerr << "bbgm_pair_group_feature: unknown I/O version " << ver << '\n';
00461 break;
00462 }
00463 }
00464
00465
00466 void vsl_b_write(vsl_b_ostream &os, const bbgm_pair_group_feature& b)
00467 {
00468 b.b_write(os);
00469 }
00470
00471
00472 void vsl_b_read(vsl_b_istream &is, bbgm_pair_group_feature& b)
00473 {
00474 bbgm_pair_group_feature temp;
00475 temp.b_read(is);
00476 b = temp;
00477 }
00478
00479 void vsl_print_summary(vcl_ostream& , const bbgm_pair_group_feature& )
00480 {
00481 vcl_cerr << "bbgm_pair_group_feature::vsl_print_summary not implemented\n";
00482 }
00483
00484 bool pair_intersect(bbgm_mask_pair_feature const& mp0,
00485 bbgm_mask_pair_feature const& mp1,
00486 bool plus_intersect_only)
00487 {
00488
00489 unsigned id00 = mp0.id0(), id01 = mp0.id1();
00490 unsigned id10 = mp1.id0(), id11 = mp1.id1();
00491 if (id00==id10||id00==id11||id01==id00||id01==id11)
00492 return true;
00493
00494 brip_rect_mask::mask_id mid = mp0.mask_id();
00495 brip_rect_mask::ang_id ang00 = mp0.ang0();
00496 brip_rect_mask::ang_id ang01 = mp0.ang1();
00497 brip_rect_mask::ang_id ang10 = mp1.ang0();
00498 brip_rect_mask::ang_id ang11 = mp1.ang1();
00499 unsigned short i00, j00, i01, j01, i10, j10, i11, j11;
00500 mp0.x0(i00, j00); mp0.x1(i01, j01);
00501 mp1.x0(i10, j10); mp1.x1(i11, j11);
00502 if (plus_intersect_only) {
00503 if (brip_rect_mask::intersect(mid, ang00, i00, j00, ang10, i10, j10))
00504 return true;
00505 if (brip_rect_mask::intersect(mid, ang00, i00, j00, ang11, i11, j11))
00506 return true;
00507 if (brip_rect_mask::intersect(mid, ang01, i01, j01, ang10, i10, j10))
00508 return true;
00509 if (brip_rect_mask::intersect(mid, ang01, i01, j01, ang11, i11, j11))
00510 return true;
00511 }
00512 else {
00513 if (brip_rect_mask::intersect_domain(mid, ang00, i00, j00, ang10, i10, j10))
00514 return true;
00515 if (brip_rect_mask::intersect_domain(mid, ang00, i00, j00, ang11, i11, j11))
00516 return true;
00517 if (brip_rect_mask::intersect_domain(mid, ang01, i01, j01, ang10, i10, j10))
00518 return true;
00519 if (brip_rect_mask::intersect_domain(mid, ang01, i01, j01, ang11, i11, j11))
00520 return true;
00521 }
00522 return false;
00523 }
00524
00525 bbgm_pair_group_feature pair_group_merge(bbgm_pair_group_feature const& pg0,
00526 bbgm_pair_group_feature const& pg1,
00527 float p_path)
00528 {
00529
00530 const vcl_set<bbgm_mask_pair_feature, fless>& pairs0 =
00531 pg0.pairs();
00532 double pr0 = pg0();
00533
00534 const vcl_set<bbgm_mask_pair_feature, fless>& pairs1 = pg1.pairs();
00535 double pr1 = pg1();
00536
00537 vcl_set<bbgm_mask_pair_feature, fless> merged_verts;
00538
00539 vcl_set<bbgm_mask_pair_feature, fless>::const_iterator pit;
00540
00541 for (pit = pairs0.begin(); pit != pairs0.end(); ++pit)
00542 merged_verts.insert(*pit);
00543
00544 for (pit = pairs1.begin(); pit != pairs1.end(); ++pit)
00545 merged_verts.insert(*pit);
00546 double np = merged_verts.size();
00547 if (np==0) return pg0;
00548 double dp = vcl_pow(pr0, (np-1.0)/np);
00549 dp *= vcl_pow(pr1, 1.0/np);
00550 float p = static_cast<float>(dp)*p_path;
00551 bbgm_pair_group_feature pgm;
00552 pgm.set_prob(merged_verts, p);
00553 return pgm;
00554 }
00555
00556 bbgm_pair_group_feature
00557 pair_group_max_union(bbgm_pair_group_feature const& pg0,
00558 bbgm_pair_group_feature const& pg1)
00559 {
00560
00561 const vcl_set<bbgm_mask_pair_feature, fless>& pairs0 = pg0.pairs();
00562
00563 const vcl_set<bbgm_mask_pair_feature, fless>& pairs1 = pg1.pairs();
00564
00565
00566 vcl_set<bbgm_mask_pair_feature, fless> merged_verts;
00567
00568 vcl_set<bbgm_mask_pair_feature, fless>::const_iterator pit;
00569
00570 float pmax = 0.0f;
00571 for (pit = pairs0.begin(); pit != pairs0.end(); ++pit) {
00572 merged_verts.insert(*pit);
00573 if ((*pit)()>pmax)
00574 pmax = (*pit)();
00575 }
00576 for (pit = pairs1.begin(); pit != pairs1.end(); ++pit) {
00577 merged_verts.insert(*pit);
00578 if ((*pit)()>pmax)
00579 pmax = (*pit)();
00580 }
00581 bbgm_pair_group_feature pgm;
00582 pgm.set_prob(merged_verts, pmax);
00583 return pgm;
00584 }