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

bmrf_curve_3d.cxx

Go to the documentation of this file.
00001 // This is brl/bseg/bmrf/bmrf_curve_3d.cxx
00002 //:
00003 // \file
00004 
00005 #include "bmrf_curve_3d.h"
00006 #include "bmrf_curvel_3d.h"
00007 #include "bmrf_node.h"
00008 #include "bmrf_epi_seg.h"
00009 #include <vsl/vsl_list_io.h>
00010 #include <vnl/algo/vnl_qr.h>
00011 
00012 
00013 //: Constructor
00014 bmrf_curve_3d::bmrf_curve_3d()
00015 {
00016 }
00017 
00018 
00019 //: Trim the ends of the curve with few correspondences
00020 void
00021 bmrf_curve_3d::trim(int min_prj)
00022 {
00023   for (iterator itr = this->begin(); itr != this->end(); )
00024   {
00025     iterator next_itr = itr;
00026     ++next_itr;
00027     if ((*itr)->num_projections(true) < min_prj)
00028       this->erase(itr);
00029     itr = next_itr;
00030   }
00031 }
00032 
00033 
00034 //: Trim curvels with large deviation in gamma
00035 void
00036 bmrf_curve_3d::stat_trim(double max_std)
00037 {
00038   for (iterator itr = this->begin(); itr != this->end(); )
00039   {
00040     iterator next_itr = itr;
00041     ++next_itr;
00042     if ((*itr)->gamma_std() > max_std)
00043       this->erase(itr);
00044     itr = next_itr;
00045   }
00046 }
00047 
00048 
00049 //: Attempt to fill in missing correspondences
00050 void
00051 bmrf_curve_3d::fill_gaps(const vcl_set<int>& frames, double da)
00052 {
00053   for ( vcl_set<int>::const_iterator fitr = frames.begin();
00054         fitr != frames.end();  ++fitr )
00055   {
00056     bool filled = true;
00057     while ( filled )
00058     {
00059       filled = false;
00060 
00061       for ( iterator itr = this->begin(); itr != this->end(); )
00062       {
00063         bmrf_curvel_3d_sptr last_curvel = NULL;
00064         // move to the next valid node
00065         while (itr != this->end() && !(*itr)->node_at_frame(*fitr))
00066           ++itr;
00067         // move to the next NULL node
00068         while (itr != this->end() && (*itr)->node_at_frame(*fitr))
00069           last_curvel = *(itr++);
00070 
00071         if ( itr == this->end() )
00072           break;
00073 
00074         bmrf_node_sptr node = last_curvel->node_at_frame(*fitr);
00075         double alpha = last_curvel->alpha_at_frame(*fitr) + da;
00076         if ( node->epi_seg()->max_alpha() > alpha ){
00077           (*itr)->set_proj_in_frame(*fitr, alpha, node);
00078           filled = true;
00079         }
00080       }
00081 
00082       for (reverse_iterator itr = this->rbegin(); itr != this->rend(); )
00083       {
00084         bmrf_curvel_3d_sptr last_curvel = NULL;
00085         // move to the next valid node
00086         while (itr != this->rend() && !(*itr)->node_at_frame(*fitr))
00087           ++itr;
00088         // move to the next NULL node
00089         while (itr != this->rend() && (*itr)->node_at_frame(*fitr))
00090           last_curvel = *(itr++);
00091 
00092         if ( itr == this->rend() )
00093           break;
00094 
00095         bmrf_node_sptr node = last_curvel->node_at_frame(*fitr);
00096         double alpha = last_curvel->alpha_at_frame(*fitr) - da;
00097         if ( node->epi_seg()->min_alpha() < alpha ){
00098           (*itr)->set_proj_in_frame(*fitr, alpha, node);
00099           filled = true;
00100         }
00101       }
00102     }
00103   }
00104 }
00105 
00106 
00107 //: Attempt to interpolate artificial values for missing correspondences
00108 void
00109 bmrf_curve_3d::interp_gaps(const vcl_set<int>& frames)
00110 {
00111   for ( vcl_set<int>::const_iterator fitr = frames.begin();
00112         fitr != frames.end();  ++fitr )
00113   {
00114     vnl_double_2 last_point;
00115     iterator last_itr = this->end();
00116     int gap_size = 0;
00117     for (iterator itr = this->begin(); itr != this->end(); ++itr )
00118     {
00119       vnl_double_2 temp_pt;
00120       if ( (*itr)->pos_in_frame(*fitr, temp_pt) )
00121       {
00122         if ( gap_size > 0 && gap_size < 4)
00123         {
00124           int gap = 1;
00125           vnl_double_2 step = temp_pt - last_point;
00126           for (iterator fill_itr = ++last_itr;
00127                fill_itr != itr;  ++fill_itr, ++gap)
00128           {
00129             double ratio = double(gap)/double(gap_size+1);
00130             vnl_double_2 new_pt = last_point + step*ratio;
00131             (*fill_itr)->set_psuedo_point(*fitr, new_pt );
00132           }
00133         }
00134         last_point = temp_pt;
00135         last_itr = itr;
00136         gap_size = 0;
00137       }
00138       else if (last_itr != this->end()) {
00139         ++gap_size;
00140       }
00141     }
00142   }
00143 }
00144 
00145 
00146 //: Simultaneously reconstruct all points in a 3d curve
00147 void
00148 bmrf_curve_3d::reconstruct(const vcl_map<int,vnl_double_3x4>& cameras, float sigma)
00149 {
00150   unsigned int num_pts = this->size();
00151 
00152   float kernel[2];
00153   kernel[0] = 0.0f;
00154   kernel[1] = 1.0f;
00155   if (sigma > 0.0f) {
00156     kernel[0] = float(vcl_exp(-1.0/(2*sigma*sigma)));
00157     float kernel_sum = 2.0f*kernel[0] + kernel[1];
00158     kernel[0] /= kernel_sum;
00159     kernel[1] /= kernel_sum;
00160   }
00161 
00162   vnl_matrix<double> A(3*num_pts, 3*num_pts, 0.0);
00163   vnl_vector<double> b(3*num_pts, 0.0);
00164 
00165   bmrf_curve_3d::iterator itr = this->begin();
00166   for (unsigned int cnt=0; itr != this->end(); ++itr, ++cnt)
00167   {
00168     unsigned int num_views = (*itr)->num_projections(true);
00169     vnl_matrix<double> C(2*num_views, 3, 0.0);
00170     vnl_vector<double> d(2*num_views, 0.0);
00171     unsigned int v=0;
00172     for ( vcl_map<int,vnl_double_3x4>::const_iterator C_itr = cameras.begin();
00173           C_itr != cameras.end();  ++C_itr ) {
00174       const int f = C_itr->first;
00175       const vnl_double_3x4 cam = C_itr->second;
00176       vnl_double_2 pos;
00177       if ( (*itr)->pos_in_frame(f,pos) ) {
00178         for (unsigned int i=0; i<3; i++) {
00179           C[2*v  ][i] = (pos[0]*cam[2][i] - cam[0][i])/2000;
00180           C[2*v+1][i] = (pos[1]*cam[2][i] - cam[1][i])/2000;
00181         }
00182         d[2*v  ] = -(pos[0]*cam[2][3] - cam[0][3])/2000;
00183         d[2*v+1] = -(pos[1]*cam[2][3] - cam[1][3])/2000;
00184         ++v;
00185       }
00186     }
00187     vnl_matrix<double> Ct = C.transpose();
00188     C = Ct * C;
00189     d = Ct * d;
00190     for (int i=0; i<3; ++i)
00191     {
00192       for (int j=0; j<3; ++j) {
00193         A[3*cnt+i][3*cnt+j] = C[i][j];
00194       }
00195       b[3*cnt+i] = d[i];
00196       if (cnt > 0 && cnt < num_pts-1) {
00197         A[3*cnt+i][3*(cnt-1)+i] -= double(kernel[0]);
00198         A[3*cnt+i][3* cnt   +i] += 1.0-double(kernel[1]);
00199         A[3*cnt+i][3*(cnt+1)+i] -= double(kernel[0]);
00200       }
00201     }
00202   }
00203 
00204   vnl_qr<double> qr_solver(A);
00205   vnl_vector<double> p = qr_solver.solve(b);
00206 
00207   vnl_vector<double> error = A*p - b;
00208   error.normalize();
00209 
00210   vnl_vector<double> error2(error.size()/3,0.0);
00211   for (unsigned int cnt=0; cnt < error2.size(); ++cnt) {
00212     double e1 = error[3*cnt];
00213     double e2 = error[3*cnt+1];
00214     double e3 = error[3*cnt+2];
00215     error2[cnt] = vcl_sqrt(e1*e1+e2*e2+e3*e3);
00216   }
00217 
00218   double max = error2.max_value();
00219   double min = error2.min_value();
00220   error2 -= min;
00221   error2 *= 1.0/(max-min);
00222 
00223   itr = this->begin();
00224   for (unsigned int cnt=0; itr != this->end(); ++itr, ++cnt)
00225   {
00226     (*itr)->set(p[cnt*3], p[cnt*3+1], p[cnt*3+2]);
00227     (*itr)->set_proj_error(error2[cnt]);
00228   }
00229 }
00230 
00231 
00232 //: Binary save self to stream.
00233 void
00234 bmrf_curve_3d::b_write( vsl_b_ostream& os ) const
00235 {
00236   vsl_b_write(os, version());
00237   vsl_b_write(os, *((vcl_list<bmrf_curvel_3d_sptr> const*)this));
00238 }
00239 
00240 
00241 //: Binary load self from stream.
00242 void
00243 bmrf_curve_3d::b_read( vsl_b_istream& is )
00244 {
00245   if (!is) return;
00246 
00247   short ver;
00248   vsl_b_read(is, ver);
00249   switch (ver)
00250   {
00251    case 1:
00252    {
00253     vsl_b_read(is, *((vcl_list<bmrf_curvel_3d_sptr>*)this));
00254 
00255     break;
00256    }
00257 
00258    default:
00259     vcl_cerr << "I/O ERROR: bmrf_curve_3d::b_read(vsl_b_istream&)\n"
00260              << "           Unknown version number "<< ver << '\n';
00261     is.is().clear(vcl_ios::badbit); // Set an unrecoverable IO error on stream
00262     return;
00263   }
00264 }
00265 
00266 
00267 //: Return IO version number;
00268 short
00269 bmrf_curve_3d::version() const
00270 {
00271   return 1;
00272 }
00273 
00274 
00275 //: Print an ascii summary to the stream
00276 void
00277 bmrf_curve_3d::print_summary( vcl_ostream& os ) const
00278 {
00279   os << "num_pts=" << this->size();
00280 }
00281 
00282 //-----------------------------------------------------------------------------------------
00283 // External functions
00284 //-----------------------------------------------------------------------------------------
00285 
00286 //: Binary save bmrf_curve_3d to stream.
00287 void
00288 vsl_b_write(vsl_b_ostream &os, const bmrf_curve_3d* c)
00289 {
00290   if (c==0) {
00291     vsl_b_write(os, false); // Indicate null pointer stored
00292   }
00293   else{
00294     vsl_b_write(os,true); // Indicate non-null pointer stored
00295     c->b_write(os);
00296   }
00297 }
00298 
00299 
00300 //: Binary load bmrf_curve_3d from stream.
00301 void
00302 vsl_b_read(vsl_b_istream &is, bmrf_curve_3d* &c)
00303 {
00304   delete c;
00305   bool not_null_ptr;
00306   vsl_b_read(is, not_null_ptr);
00307   if (not_null_ptr) {
00308     c = new bmrf_curve_3d();
00309     c->b_read(is);
00310   }
00311   else
00312     c = 0;
00313 }
00314 
00315 
00316 //: Print an ASCII summary to the stream
00317 void
00318 vsl_print_summary(vcl_ostream &os, const bmrf_curve_3d* c)
00319 {
00320   os << "bmrf_curve_3d{ ";
00321   c->print_summary(os);
00322   os << " }";
00323 }
00324 

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