Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

bmrf_curve_3d_builder.cxx

Go to the documentation of this file.
00001 // This is brl/bseg/bmrf/bmrf_curve_3d_builder.cxx
00002 #include "bmrf_curve_3d_builder.h"
00003 //:
00004 // \file
00005 
00006 #include "bmrf_curve_3d.h"
00007 #include "bmrf_curvel_3d.h"
00008 #include "bmrf_network.h"
00009 #include "bmrf_node.h"
00010 #include "bmrf_arc.h"
00011 #include "bmrf_epi_seg.h"
00012 #include "bmrf_epipole.h"
00013 #include "bmrf_gamma_func.h"
00014 
00015 #include <vcl_algorithm.h>
00016 #include <vgl/vgl_point_2d.h>
00017 #include <vnl/vnl_double_2.h>
00018 #include <vnl/vnl_double_3.h>
00019 #include <vnl/vnl_double_4.h>
00020 #include <vnl/vnl_double_3x4.h>
00021 #include <vnl/vnl_double_3x3.h>
00022 #include <vnl/vnl_rotation_matrix.h>
00023 #include <vnl/vnl_inverse.h>
00024 #include <vnl/vnl_identity_3x3.h>
00025 #include <vnl/algo/vnl_svd.h>
00026 
00027 
00028 //: Constructor
00029 bmrf_curve_3d_builder::bmrf_curve_3d_builder()
00030  : network_(NULL), min_alpha_(0.0), max_alpha_(0.0), bb_xform_(0.0)
00031 {
00032 }
00033 
00034 
00035 //: Constructor
00036 bmrf_curve_3d_builder::bmrf_curve_3d_builder(const bmrf_network_sptr& network)
00037  : network_(network), min_alpha_(0.0), max_alpha_(0.0), bb_xform_(0.0)
00038 {
00039   // For our camera images are 1024 x 768
00040   // The focal length is 12.5mm / (6.25 um/pixel) = 2000 pixels
00041   vnl_double_3x3 K;
00042   K[0][0] = 2000;  K[0][1] = 0;     K[0][2] = 512;
00043   K[1][0] = 0;     K[1][1] = 2000;  K[1][2] = 384;
00044   K[2][0] = 0;     K[2][1] = 0;     K[2][2] = 1;
00045 
00046   // Use the identity camera by default
00047   vnl_double_3x4 C;
00048   C[0][0] = 1;  C[0][1] = 0;  C[0][2] = 0;  C[0][3] = 0;
00049   C[1][0] = 0;  C[1][1] = 1;  C[1][2] = 0;  C[1][3] = 0;
00050   C[2][0] = 0;  C[2][1] = 0;  C[2][2] = 1;  C[2][3] = 0;
00051   this->init_cameras(K*C);
00052 }
00053 
00054 
00055 //: Initialize the camera matrices
00056 void
00057 bmrf_curve_3d_builder::init_cameras(const vnl_double_3x4& C0, double scale)
00058 {
00059   C_.clear();
00060   if (!network_)
00061     return;
00062   vcl_set<int> frames = network_->frame_numbers();
00063   const vgl_point_2d<double>& ep = network_->epipole(1).location();
00064   if (offsets_.empty())
00065     compute_camera_offsets();
00066 
00067   vnl_double_3x3 M = C0.extract(3,3);
00068 
00069   // compute the 3d direction unit vector
00070   vnl_double_3 e;
00071   e[0] = ep.x();
00072   e[1] = ep.y();
00073   e[2] = 1.0;
00074   vnl_double_3 dir = vnl_inverse(M)*e;
00075   direction_.set(dir[0],dir[1],dir[2]);
00076   normalize(direction_);
00077 
00078   // compute the cameras
00079   vcl_set<int>::const_iterator fitr = frames.begin();
00080   if (fitr != frames.end()){
00081     C_[*fitr] = C0;
00082     double dt = scale;
00083     vnl_double_3x4 Ef = C0;
00084     for ( ++fitr;  fitr != frames.end();  ++fitr ) {
00085       dt *= offsets_[*fitr];
00086       Ef.set_column(3,Ef.get_column(3) - dt*e);
00087       C_[*fitr] = Ef;
00088     }
00089   }
00090 }
00091 
00092 
00093 //: Compute the relative change in spacing between cameras
00094 void
00095 bmrf_curve_3d_builder::compute_camera_offsets()
00096 {
00097   offsets_.clear();
00098   vcl_set<int> frames = network_->frame_numbers();
00099 
00100   for ( vcl_set<int>::const_iterator fitr = frames.begin();
00101         fitr != frames.end();  ++fitr ) {
00102     double cross_ratio_sum = 0.0;
00103     double cr_moment2 = 0.0;
00104     unsigned int count = 0;
00105     for ( vcl_set<bmrf_curve_3d_sptr>::const_iterator itr1 = curves_.begin();
00106           itr1 != curves_.end();  ++itr1)
00107     {
00108       for ( bmrf_curve_3d::const_iterator itr2 = (*itr1)->begin();
00109             itr2 != (*itr1)->end();  ++itr2)
00110       {
00111         bmrf_curvel_3d_sptr curvel = *itr2;
00112         double val = 0.0;
00113         if (curvel->cross_ratio(*fitr,val)){
00114           cross_ratio_sum += val;
00115           cr_moment2 += val*val;
00116           ++count;
00117         }
00118       }
00119     }
00120 
00121     double offset = 1.0;
00122     if (fitr == frames.begin())
00123       offset = 0.0;
00124     if (count>0){
00125       double avg_ratio = cross_ratio_sum/count;
00126       double var = 0.0;
00127       if (count>1)
00128         var = (cr_moment2 - avg_ratio*avg_ratio*count)/(count-1);
00129       vcl_cerr << "Frame "<< *fitr << ":\tmean = "<< avg_ratio << " \tstdev = " << vcl_sqrt(var) <<vcl_endl;
00130       offset = avg_ratio/(1.0 - avg_ratio);
00131     }
00132     offsets_[*fitr] = offset;
00133   }
00134 
00135   vcl_cerr << "All offsets\n";
00136   for ( vcl_set<int>::const_iterator fitr = frames.begin();
00137         fitr != frames.end();  ++fitr ) {
00138     vcl_cerr << offsets_[*fitr] << ' ';
00139   }
00140   vcl_cerr << vcl_endl;
00141 }
00142 
00143 
00144 //: Set the network
00145 void
00146 bmrf_curve_3d_builder::set_network(const bmrf_network_sptr& network)
00147 {
00148   network_ = network;
00149 }
00150 
00151 
00152 //: Return the constructed curves
00153 vcl_set<bmrf_curve_3d_sptr>
00154 bmrf_curve_3d_builder::curves() const
00155 {
00156   return curves_;
00157 }
00158 
00159 
00160 //: Return the cameras used in the reconstruction
00161 vcl_map<int,vnl_double_3x4>
00162 bmrf_curve_3d_builder::cameras() const
00163 {
00164   return C_;
00165 }
00166 
00167 
00168 //: Return the 3D direction of motion of the curves
00169 vgl_vector_3d<double>
00170 bmrf_curve_3d_builder::direction() const
00171 {
00172   return direction_;
00173 }
00174 
00175 
00176 //: Return the bounding box transformation
00177 vnl_double_4x4
00178 bmrf_curve_3d_builder::bb_xform() const
00179 {
00180   return bb_xform_;
00181 }
00182 
00183 
00184 bool bmrf_cmp_x(const vnl_double_3& rhs, const vnl_double_3& lhs)
00185 {
00186   return rhs[0] < lhs[0];
00187 }
00188 
00189 bool bmrf_cmp_y(const vnl_double_3& rhs, const vnl_double_3& lhs)
00190 {
00191   return rhs[1] < lhs[1];
00192 }
00193 
00194 bool bmrf_cmp_z(const vnl_double_3& rhs, const vnl_double_3& lhs)
00195 {
00196   return rhs[2] < lhs[2];
00197 }
00198 
00199 //: Compute the bounding box aligned with vehicle direction
00200 bool
00201 bmrf_curve_3d_builder::compute_bounding_box(const float *inlier_fractions, bool align_ep)
00202 {
00203   if (curves_.empty())
00204     return false;
00205 
00206   vnl_double_3x3 rot = vnl_identity_3x3();
00207 
00208   if ( align_ep )
00209   {
00210     vnl_double_3 base_axis(1.0, 0.0, 0.0);
00211     vnl_double_3 rot_axis(0.0, 1.0, 0.0);
00212     vnl_double_3 xz_proj(direction_.x(), 0.0, direction_.z());
00213     xz_proj.normalize();
00214     double ang = angle(xz_proj, base_axis);
00215     rot_axis *= ang;
00216     vnl_double_3x3 rot_y = vnl_rotation_matrix(rot_axis);
00217 
00218     rot_axis = vnl_double_3(0.0, 0.0, 1.0);
00219     vnl_double_3 xy_proj = rot_y * vnl_double_3(direction_.x(), direction_.y(), direction_.z());
00220     xy_proj.normalize();
00221     ang = angle(xy_proj, base_axis);
00222     rot_axis *= ang;
00223     vnl_double_3x3 rot_z = vnl_rotation_matrix(rot_axis);
00224 
00225     rot = rot_z*rot_y;
00226   }
00227   // rotate only about the z-axis
00228   else
00229   {
00230     vnl_double_3 x_axis(1.0, 0.0, 0.0);
00231     vnl_double_3 xy_proj(direction_.x(), direction_.y(), 0.0);
00232     xy_proj.normalize();
00233     double ang = angle(xy_proj, -x_axis);
00234     vcl_cerr << "bbox rotation angle: " <<ang << vcl_endl;
00235     vnl_double_3 rot_axis(0.0, 0.0, ang);
00236     rot = vnl_rotation_matrix(rot_axis);
00237   }
00238 
00239   vcl_vector<vnl_double_3> pts_z;
00240 
00241   for ( vcl_set<bmrf_curve_3d_sptr>::const_iterator itr1 = curves_.begin();
00242         itr1 != curves_.end();  ++itr1)
00243   {
00244     for ( bmrf_curve_3d::const_iterator itr2 = (*itr1)->begin();
00245           itr2 != (*itr1)->end();  ++itr2)
00246     {
00247       bmrf_curvel_3d_sptr curvel = *itr2;
00248       vnl_double_3 point(curvel->x(), curvel->y(), curvel->z());
00249       pts_z.push_back(rot*point);
00250     }
00251   }
00252 
00253   vcl_sort(pts_z.begin(), pts_z.end(), bmrf_cmp_z);
00254   vcl_vector<vnl_double_3> pts_x;
00255 
00256   // only consider points in x and y above 0.5 feet
00257   for ( vcl_vector<vnl_double_3>::const_iterator itr = pts_z.begin();
00258         itr != pts_z.end();  ++itr)
00259   {
00260     if ((*itr)[2] > 0.5) { pts_x.push_back(*itr); }
00261   }
00262   if (pts_x.empty()) { pts_x = pts_z; }
00263 
00264   vcl_vector<vnl_double_3> pts_y = pts_x;
00265 
00266   vcl_sort(pts_x.begin(), pts_x.end(), bmrf_cmp_x);
00267   vcl_sort(pts_y.begin(), pts_y.end(), bmrf_cmp_y);
00268 
00269   unsigned int min_ind_x = 0, min_ind_y = 0, min_ind_z = 0;
00270   unsigned int max_ind_x = pts_x.size()-1, max_ind_y = pts_y.size()-1, max_ind_z = pts_z.size()-1;
00271   if (inlier_fractions) {
00272     float fraction_out = (1.f - inlier_fractions[0])*.5f;
00273     min_ind_x = (unsigned int)(max_ind_x*fraction_out);
00274     max_ind_x = (unsigned int)(max_ind_x*(1.f-fraction_out));
00275     fraction_out = (1.f - inlier_fractions[1])*.5f;
00276     min_ind_y = (unsigned int)(max_ind_y*fraction_out);
00277     max_ind_y = (unsigned int)(max_ind_y*(1.f-fraction_out));
00278     fraction_out = (1.f - inlier_fractions[2])*.5f;
00279     min_ind_z = (unsigned int)(max_ind_z*fraction_out);
00280     max_ind_z = (unsigned int)(max_ind_z*(1.f-fraction_out));
00281   }
00282 
00283   vnl_double_3 min_point(pts_x[min_ind_x][0], pts_y[min_ind_y][1], pts_z[min_ind_z][2]);
00284   vnl_double_3 max_point(pts_x[max_ind_x][0], pts_y[max_ind_y][1], pts_z[max_ind_z][2]);
00285 
00286   vnl_double_3 diag_vector = max_point - min_point;
00287   vnl_vector_fixed<double,3> x_axis(0.0), y_axis(0.0), z_axis(0.0);
00288   x_axis[0] = diag_vector[0];
00289   y_axis[1] = diag_vector[1];
00290   z_axis[2] = diag_vector[2];
00291 
00292   vnl_double_3x3 inv_rot = rot.transpose();
00293 
00294   x_axis = inv_rot * x_axis;
00295   y_axis = inv_rot * y_axis;
00296   z_axis = inv_rot * z_axis;
00297 
00298   vnl_double_3 origin = inv_rot * min_point;
00299 
00300   bb_xform_.set_identity();
00301   bb_xform_(0,0)=x_axis[0]; bb_xform_(1,0)=x_axis[1]; bb_xform_(2,0)=x_axis[2];
00302   bb_xform_(0,1)=y_axis[0]; bb_xform_(1,1)=y_axis[1]; bb_xform_(2,1)=y_axis[2];
00303   bb_xform_(0,2)=z_axis[0]; bb_xform_(1,2)=z_axis[1]; bb_xform_(2,2)=z_axis[2];
00304   bb_xform_(0,3)=origin[0]; bb_xform_(1,3)=origin[1]; bb_xform_(2,3)=origin[2];
00305 
00306   return true;
00307 }
00308 
00309 
00310 //: Build the curves
00311 bool
00312 bmrf_curve_3d_builder::build(int min_prj, int min_len, double trim_thresh)
00313 {
00314   if (!network_)
00315     return false;
00316 
00317   unsigned int num_frames = network_->num_frames();
00318   if (num_frames < 2)
00319     return false;
00320 
00321   find_alpha_bounds();
00322 
00323   vcl_set<bmrf_curve_3d_sptr> growing_curves;
00324 
00325   // Build an initial set of curves
00326   vcl_set<bmrf_curvel_3d_sptr> empty_set;
00327   vcl_set<bmrf_curvel_3d_sptr> init_curvels = build_curvels(empty_set, min_alpha_);
00328   for ( vcl_set<bmrf_curvel_3d_sptr>::iterator itr = init_curvels.begin();
00329         itr != init_curvels.end(); ++itr)
00330   {
00331     bmrf_curve_3d_sptr new_curve = new bmrf_curve_3d;
00332     new_curve->push_back(*itr);
00333     curves_.insert(new_curve);
00334     growing_curves.insert(new_curve);
00335   }
00336 
00337   // Sweep through alpha
00338   double da = 0.001; // step size in alpha
00339   for ( double alpha = min_alpha_+da; alpha < max_alpha_; alpha += da ) {
00340     vcl_cout << "percent complete : " << (alpha - min_alpha_)/(max_alpha_-min_alpha_)*100.0<< vcl_endl;
00341     vcl_set<bmrf_curvel_3d_sptr> curvels = extend_curves(growing_curves, alpha);
00342     // find all curvels
00343     vcl_set<bmrf_curvel_3d_sptr> new_curvels = build_curvels(curvels, alpha);
00344     this->append_curvels(new_curvels, growing_curves, min_prj);
00345   }
00346 
00347   // Clean up curves
00348   for ( vcl_set<bmrf_curve_3d_sptr >::iterator itr = curves_.begin();
00349         itr != curves_.end();)
00350   {
00351     vcl_set<bmrf_curve_3d_sptr >::iterator next_itr = itr;
00352     ++next_itr;
00353 
00354     (*itr)->fill_gaps( network_->frame_numbers(), da);
00355     (*itr)->interp_gaps( network_->frame_numbers() );
00356     (*itr)->stat_trim( trim_thresh );
00357     if ( (*itr)->size() < (unsigned int)min_len )
00358       curves_.erase(itr);
00359     itr = next_itr;
00360   }
00361 
00362   return true;
00363 }
00364 
00365 
00366 //: Reconstruct the 3D curves from the curvel chains
00367 void
00368 bmrf_curve_3d_builder::reconstruct(float sigma)
00369 {
00370   for ( vcl_set<bmrf_curve_3d_sptr >::iterator itr = curves_.begin();
00371         itr != curves_.end();  ++itr)
00372   {
00373     (*itr)->reconstruct(C_, sigma);
00374   }
00375 }
00376 
00377 
00378 //: Determine the alpha bounds from the network
00379 void
00380 bmrf_curve_3d_builder::find_alpha_bounds()
00381 {
00382   min_alpha_ = 4.0;  // greater than pi
00383   max_alpha_ = -4.0; // less than -pi
00384   for ( bmrf_network::seg_node_map::const_iterator itr = network_->begin();
00385         itr != network_->end();  ++itr )
00386   {
00387     min_alpha_ = vcl_min(min_alpha_, itr->first->min_alpha());
00388     max_alpha_ = vcl_max(max_alpha_, itr->first->max_alpha());
00389   }
00390 }
00391 
00392 
00393 //: For sorting matches by arc probability
00394 static bool
00395 bmrf_arc_prob_cmp( const bmrf_arc_sptr& left_arc,
00396                    const bmrf_arc_sptr& right_arc )
00397 {
00398   return left_arc->probability() < right_arc->probability();
00399 }
00400 
00401 
00402 //: Build curvels by linking across time through probable arcs
00403 vcl_set<bmrf_curvel_3d_sptr>
00404 bmrf_curve_3d_builder::build_curvels(vcl_set<bmrf_curvel_3d_sptr>& all_curvels, 
00405                                      double alpha) const
00406 {
00407   vcl_set<int> frames = network_->frame_numbers();
00408 
00409   // find all arcs at alpha
00410   vcl_vector<bmrf_arc_sptr> all_arcs = this->find_arcs_at(alpha);
00411   // sort by probability
00412   vcl_sort(all_arcs.begin(), all_arcs.end(), bmrf_arc_prob_cmp);
00413 
00414   typedef vcl_map<bmrf_node_sptr, bmrf_curvel_3d_sptr> node_curvel_map;
00415   node_curvel_map node_map;
00416 
00417   for ( vcl_set<bmrf_curvel_3d_sptr>::const_iterator c_itr = all_curvels.begin();
00418         c_itr != all_curvels.end();  ++c_itr )
00419   {
00420     if ( (*c_itr)->num_projections() == 0 )
00421       continue;
00422     for ( vcl_set<int>::const_iterator fitr = frames.begin();
00423           fitr != frames.end();  ++fitr ) {
00424       bmrf_node_sptr update_node = (*c_itr)->node_at_frame(*fitr);
00425       if ( update_node )
00426         node_map[update_node] = *c_itr;
00427     }
00428   }
00429 
00430   vcl_set<bmrf_curvel_3d_sptr> new_curvels;
00431 
00432   while ( !all_arcs.empty() )
00433   {
00434     bmrf_arc_sptr curr_arc = all_arcs.back();
00435     all_arcs.pop_back();
00436 
00437     bmrf_node_sptr from_node = curr_arc->from();
00438     bmrf_node_sptr to_node = curr_arc->to();
00439 
00440     node_curvel_map::iterator itr1 = node_map.find(from_node);
00441     node_curvel_map::iterator itr2 = node_map.find(to_node);
00442     if ( itr1 == node_map.end() )
00443     {
00444       if ( itr2 == node_map.end() ) {
00445         bmrf_curvel_3d_sptr curr_curvel = new bmrf_curvel_3d;
00446         curr_curvel->set_proj_in_frame(from_node->frame_num(), alpha, from_node);
00447         curr_curvel->set_proj_in_frame(to_node->frame_num(), alpha, to_node);
00448         node_map[from_node] = curr_curvel;
00449         node_map[to_node] = curr_curvel;
00450         new_curvels.insert(curr_curvel);
00451       }
00452       else {
00453         bmrf_curvel_3d_sptr curr_curvel = itr2->second;
00454         bmrf_node_sptr other_node = curr_curvel->node_at_frame(from_node->frame_num());
00455         if ( !other_node ) {
00456           curr_curvel->set_proj_in_frame(from_node->frame_num(), alpha, from_node);
00457           node_map[from_node] = curr_curvel;
00458         }
00459       }
00460     }
00461     else
00462     {
00463       if ( itr2 == node_map.end() ){
00464         bmrf_curvel_3d_sptr curr_curvel = itr1->second;
00465         if ( !curr_curvel->node_at_frame(to_node->frame_num()) ){
00466           curr_curvel->set_proj_in_frame(to_node->frame_num(), alpha, to_node);
00467           node_map[to_node] = curr_curvel;
00468         }
00469       }
00470       else
00471       {
00472         bmrf_curvel_3d_sptr curvel_from = itr1->second;
00473         bmrf_curvel_3d_sptr curvel_to = itr2->second;
00474         if ( curvel_from->merge(curvel_to) ) {
00475           if (new_curvels.erase(curvel_to) == 0)
00476             all_curvels.erase(curvel_to);
00477           for ( vcl_set<int>::const_iterator fitr = frames.begin();
00478                 fitr != frames.end();  ++fitr ) {
00479             bmrf_node_sptr update_node = curvel_to->node_at_frame(*fitr);
00480             if ( update_node )
00481               node_map[update_node] = curvel_from;
00482           }
00483         }
00484       }
00485     }
00486   }
00487   return new_curvels;
00488 }
00489 
00490 
00491 //: extend all curves to the next alpha
00492 vcl_set<bmrf_curvel_3d_sptr>
00493 bmrf_curve_3d_builder::extend_curves( vcl_set<bmrf_curve_3d_sptr>& growing_curves,
00494                                       double alpha )
00495 {
00496   vcl_set<int> frames = network_->frame_numbers();
00497   vcl_set<bmrf_curvel_3d_sptr> new_curvels;
00498 
00499   for ( vcl_set<bmrf_curve_3d_sptr>::const_iterator itr = growing_curves.begin();
00500         itr != growing_curves.end();  ++itr )
00501   {
00502     bmrf_curve_3d::reverse_iterator c_itr = (*itr)->rbegin();
00503 
00504     bmrf_curvel_3d_sptr curvel = new bmrf_curvel_3d;
00505     new_curvels.insert(curvel);
00506     (*itr)->push_back(curvel);
00507 
00508     for ( vcl_set<int>::const_iterator fitr = frames.begin();
00509           fitr != frames.end();  ++fitr ) {
00510       bmrf_node_sptr node = (*c_itr)->node_at_frame(*fitr);
00511       if ( !node )
00512         continue;
00513       bool prev_valid = true;
00514       for (unsigned int c=0; c<2; ++c){
00515         if ( --c_itr == (*itr)->rend() || node != (*c_itr)->node_at_frame(*fitr)){
00516           prev_valid = false;
00517           break;
00518         }
00519       }
00520       if ( !prev_valid )
00521         continue;
00522 
00523       if ((node->epi_seg()->min_alpha() <= alpha) &&
00524           (node->epi_seg()->max_alpha() >= alpha))
00525         curvel->set_proj_in_frame(*fitr, alpha, node);
00526     }
00527   }
00528   return new_curvels;
00529 }
00530 
00531 
00532 //: Find all curves that intersect \p alpha in \p frame
00533 vcl_vector<bmrf_arc_sptr>
00534 bmrf_curve_3d_builder::find_arcs_at(double alpha) const
00535 {
00536   vcl_vector<bmrf_arc_sptr> matches;
00537   for ( bmrf_network::seg_node_map::const_iterator itr = network_->begin();
00538         itr != network_->end();  ++itr )
00539   {
00540     if ((itr->first->min_alpha() <= alpha) &&
00541         (itr->first->max_alpha() >= alpha))
00542     {
00543       for ( bmrf_node::arc_iterator a_itr = itr->second->begin(bmrf_node::TIME);
00544             a_itr != itr->second->end(bmrf_node::TIME); ++a_itr )
00545       {
00546         bmrf_epi_seg_sptr other_seg = (*a_itr)->to()->epi_seg();
00547         if ((other_seg->min_alpha() <= alpha) &&
00548             (other_seg->max_alpha() >= alpha))
00549         {
00550           matches.push_back(*a_itr);
00551         }
00552       }
00553     }
00554   }
00555   return matches;
00556 }
00557 
00558 
00559 //: Reconstruct the 3d location of a curvel from its projections
00560 void
00561 bmrf_curve_3d_builder::reconstruct_point(bmrf_curvel_3d_sptr curvel) const
00562 {
00563   unsigned int nviews = curvel->num_projections(true);
00564 
00565   vcl_cout << "reconstructing from " << nviews << " views" << vcl_endl;
00566 
00567   vnl_matrix<double> A(2*nviews, 4, 0.0);
00568 
00569   unsigned int v = 0;
00570   for ( vcl_map<int,vnl_double_3x4>::const_iterator C_itr = C_.begin();
00571         C_itr != C_.end();  ++C_itr ) {
00572     const int f = C_itr->first;
00573     const vnl_double_3x4 cam = C_itr->second;
00574     vnl_double_2 pos;
00575     if ( curvel->pos_in_frame(f,pos) ) {
00576       for (unsigned int i=0; i<4; i++) {
00577         A[2*v  ][i] = pos[0]*cam[2][i] - cam[0][i];
00578         A[2*v+1][i] = pos[1]*cam[2][i] - cam[1][i];
00579       }
00580       ++v;
00581     }
00582   }
00583   vnl_svd<double> svd_solver(A);
00584   vnl_double_4 p = svd_solver.nullvector();
00585 
00586   curvel->set(p[0]/p[3], p[1]/p[3], p[2]/p[3]);
00587 }
00588 
00589 
00590 //: Match the \p curvels to the ends of the \p growing_curves set of lists
00591 void
00592 bmrf_curve_3d_builder::append_curvels(vcl_set<bmrf_curvel_3d_sptr>& curvels,
00593                                       vcl_set<bmrf_curve_3d_sptr>& growing_curves,
00594                                       int min_prj)
00595 {
00596   vcl_set<bmrf_curve_3d_sptr> grown_curves;
00597 
00598   typedef vcl_pair<bmrf_curvel_3d_sptr, bmrf_curvel_3d_sptr> append_match;
00599   vcl_vector<vcl_pair<double, append_match> > matches;
00600   for ( vcl_set<bmrf_curve_3d_sptr>::iterator g_itr = growing_curves.begin();
00601         g_itr != growing_curves.end();  ++g_itr )
00602   {
00603     typedef vcl_set<bmrf_curvel_3d_sptr>::iterator curvel_iterator;
00604 
00605     bmrf_curvel_3d_sptr end_curvel = (*g_itr)->back();
00606     bmrf_curvel_3d_sptr prev_curvel = *(++((*g_itr)->rbegin()));
00607 
00608     for ( curvel_iterator c_itr = curvels.begin();
00609           c_itr != curvels.end();  ++c_itr )
00610     {
00611       double align = this->append_correct((*c_itr), prev_curvel);
00612       if ( align > 0 ) {
00613         matches.push_back(vcl_pair<double, append_match>(align, append_match(end_curvel, *c_itr)));
00614       }
00615     }
00616   }
00617 
00618   vcl_sort(matches.begin(), matches.end());
00619 
00620   while ( !matches.empty() )
00621   {
00622     bmrf_curvel_3d_sptr base_curvel = matches.back().second.first;
00623     bmrf_curvel_3d_sptr merge_curvel = matches.back().second.second;
00624     matches.pop_back();
00625     vcl_set<bmrf_curvel_3d_sptr>::iterator c_itr = curvels.find(merge_curvel);
00626     if ( c_itr == curvels.end() )
00627       continue;
00628     if ( base_curvel->merge(merge_curvel) )
00629       curvels.erase(c_itr);
00630   }
00631 
00632   for ( vcl_set<bmrf_curve_3d_sptr>::iterator g_itr = growing_curves.begin();
00633         g_itr != growing_curves.end();  ++g_itr )
00634   {
00635     if ( (*g_itr)->back()->num_projections() < min_prj )
00636       (*g_itr)->pop_back();
00637     else
00638       grown_curves.insert(*g_itr);
00639   }
00640 
00641   // make new curves for the unmatched curvels
00642   for ( vcl_set<bmrf_curvel_3d_sptr>::iterator c_itr = curvels.begin();
00643         c_itr != curvels.end();  ++c_itr )
00644   {
00645     if ( (*c_itr)->num_projections() < min_prj)
00646       continue;
00647     bmrf_curve_3d_sptr new_curve = new bmrf_curve_3d;
00648     new_curve->push_back(*c_itr);
00649     curves_.insert(new_curve);
00650     grown_curves.insert(new_curve);
00651   }
00652 
00653   growing_curves = grown_curves;
00654 }
00655 
00656 
00657 //: Return a measure (0.0 to 1.0) of how well \p new_c matches \p prev_c
00658 double
00659 bmrf_curve_3d_builder::append_correct( const bmrf_curvel_3d_sptr& new_c,
00660                                        const bmrf_curvel_3d_sptr& prev_c ) const
00661 {
00662   vcl_set<int> frames = network_->frame_numbers();
00663   unsigned int total_overlap = 0;
00664   unsigned int total_cover = 0;
00665   unsigned int total_equal = 0;
00666   for ( vcl_set<int>::const_iterator fitr = frames.begin();
00667         fitr != frames.end();  ++fitr )
00668   {
00669     bmrf_node_sptr p_node = prev_c->node_at_frame(*fitr);
00670     bmrf_node_sptr n_node = new_c->node_at_frame(*fitr);
00671     if ( p_node || n_node )
00672       ++total_cover;
00673     if ( p_node && n_node ) {
00674       ++total_overlap;
00675       if ( p_node == n_node )
00676         ++total_equal;
00677     }
00678   }
00679 
00680   if (total_overlap == 0)
00681     return 0.0;
00682 
00683   // Rate according to percentage of overlapping curvels that match
00684   // Use the percentage of curves that overlap as a tie-breaker
00685   double equal_ratio = double(total_equal)/double(total_overlap);
00686   double overlap_ratio = double(total_overlap)/double(total_cover);
00687   return equal_ratio - (1.0 - overlap_ratio)/double(frames.size());
00688 }

Generated on Thu Jan 10 14:51:52 2008 for contrib/brl/bseg/bmrf by  doxygen 1.4.4