00001
00002
00003
00004
00005 #include "brct_epi_reconstructor.h"
00006 #include <vcl_fstream.h>
00007 #include <vcl_cassert.h>
00008 #include <vcl_cstdio.h>
00009 #include <vcl_cmath.h>
00010 #include <vcl_cstdlib.h>
00011 #include <vgl/vgl_point_2d.h>
00012 #include <vgl/vgl_point_3d.h>
00013 #include <vgl/vgl_line_2d.h>
00014 #include <vgl/vgl_homg_point_2d.h>
00015 #include <vgl/vgl_homg_line_2d.h>
00016 #include <vgl/algo/vgl_homg_operators_2d.h>
00017 #if 0
00018 #include <mvl/FMatrix.h>
00019 #endif
00020 #include <vnl/vnl_inverse.h>
00021 #include <vnl/vnl_quaternion.h>
00022 #include <vdgl/vdgl_edgel.h>
00023 #include <vdgl/vdgl_edgel_chain.h>
00024 #include <vdgl/vdgl_edgel_chain_sptr.h>
00025 #include <vdgl/vdgl_interpolator_sptr.h>
00026 #include <vdgl/vdgl_interpolator.h>
00027 #include <vdgl/vdgl_interpolator_linear.h>
00028 #include <vdgl/vdgl_digital_curve.h>
00029 #include <vdgl/vdgl_digital_curve_sptr.h>
00030 #include <bdgl/bdgl_curve_algs.h>
00031 #include "brct_structure_estimator.h"
00032 #include "brct_algos.h"
00033
00034 const double brct_epi_reconstructor::large_num_ = 1e15;
00035
00036
00037
00038
00039 brct_epi_reconstructor::brct_epi_reconstructor()
00040 {
00041 e_ = 0;
00042 cur_pos_ = 0;
00043 queue_size_ = 100;
00044 memory_size_ = 0;
00045 num_points_ = 0;
00046 debug_ = false;
00047 }
00048
00049 brct_epi_reconstructor::brct_epi_reconstructor(const char* fname)
00050 {
00051
00052 read_data(fname);
00053 e_ = 0;
00054 cur_pos_ = 0;
00055 queue_size_ = 100;
00056 memory_size_ = 0;
00057 num_points_ = 0;
00058 debug_ = false;
00059 }
00060
00061 void brct_epi_reconstructor::init()
00062 {
00063
00064 cur_pos_ = 0;
00065
00066
00067 memory_size_ = 0;
00068
00069
00070 queue_size_ = 100;
00071 observes_.resize(queue_size_);
00072 motions_.resize(queue_size_);
00073
00074 init_cam_intrinsic();
00075
00076 init_velocity();
00077 init_covariant_matrix();
00078
00079 init_state_3d_estimation();
00080 memory_size_ = 2;
00081
00082 cur_pos_ = (cur_pos_ + 1) % queue_size_;
00083 }
00084
00085
00086 brct_epi_reconstructor::~brct_epi_reconstructor()
00087 {
00088 delete e_;
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void brct_epi_reconstructor::init_state_3d_estimation()
00106 {
00107 double dt = time_tick_[1] - time_tick_[0];
00108 vnl_double_3 T(X_[3]*dt,X_[4]*dt,X_[5]*dt);
00109 vcl_cout<<"T = "<<T<<'\n';
00110 debug_ = false;
00111
00112 vnl_double_3x4 E0, E1;
00113
00114
00115 E0[0][0] = 1; E0[0][1] = 0; E0[0][2] = 0; E0[0][3] = 0;
00116 E0[1][0] = 0; E0[1][1] = 1; E0[1][2] = 0; E0[1][3] = 0;
00117 E0[2][0] = 0; E0[2][1] = 0; E0[2][2] = 1; E0[2][3] = 0;
00118
00119
00120 E1[0][0] = 1; E1[0][1] = 0; E1[0][2] = 0; E1[0][3] = T[0];
00121 E1[1][0] = 0; E1[1][1] = 1; E1[1][2] = 0; E1[1][3] = T[1];
00122 E1[2][0] = 0; E1[2][1] = 0; E1[2][2] = 1; E1[2][3] = T[2];
00123
00124 vnl_double_3x4 P0 = K_*E0, P1 = K_*E1;
00125
00126
00127 motions_[0] = vnl_double_3(0.0,0.0,0.0);
00128 motions_[1] = T;
00129
00130
00131 vnl_double_3 e = K_*T;
00132
00133
00134 vnl_double_3x3 F;
00135 F[0][0] = 0; F[0][1] = -e[2]; F[0][2] = e[1];
00136 F[1][0] = e[2]; F[1][1] = 0; F[1][2] = -e[0];
00137 F[2][0] = -e[1]; F[2][1] = e[0]; F[2][2] = 0;
00138 #if 0
00139 FMatrix FM(F);
00140 #endif
00141
00142
00143
00144
00145
00146 unsigned int c = tracks_.size();
00147 joe_observes_.resize(c);
00148 grad_angles_.resize(c);
00149 vnl_double_3x3 Sigma3d;
00150 vnl_double_2x2 Sigma2d;
00151 Sigma2d.set_identity();
00152 Sigma3d.set_identity();
00153 vcl_cout<<Sigma3d<<'\n';
00154 int k = 0;
00155 for (unsigned int t =0; t<c; ++t)
00156 {
00157 vcl_vector<bugl_normal_point_3d_sptr> pts_3d;
00158 vcl_vector<bugl_gaussian_point_2d<double> > tracked_points0;
00159 vcl_vector<bugl_gaussian_point_2d<double> > tracked_points1;
00160 vcl_vector<double> grad_angles;
00161
00162 vdgl_digital_curve_sptr dc0 = tracks_[t][0];
00163
00164 vdgl_digital_curve_sptr dc1 = tracks_[t][1];
00165
00166
00167
00168 int npts0 = dc0->n_pts();
00169 int npts1 = dc1->n_pts();
00170 int npts = 2* ((npts0 < npts1) ? npts0 : npts1);
00171 for (int i=0; i<npts; i++)
00172 {
00173 double index = i/double(npts);
00174
00175
00176 vgl_point_2d<double> p0(dc0->get_x(index),dc0->get_y(index));
00177
00178
00179 double angle0 = dc0->get_theta(index);
00180 vnl_double_2x2 sigma1;
00181 sigma1.set_identity();
00182 bugl_gaussian_point_2d<double> x0(p0, sigma1);
00183
00184
00185
00186
00187
00188 vgl_line_2d<double> lr;
00189
00190
00191
00192 vgl_point_2d<double> p1;
00193 if (bdgl_curve_algs::match_intersection(dc1, lr, p0, angle0, p1))
00194 {
00195 bugl_gaussian_point_2d<double> x1(p1, Sigma2d);
00196
00197 vgl_point_3d<double> point_3d =
00198 brct_algos::triangulate_3d_point(x0, P0, x1, P1);
00199 if (debug_)
00200 vcl_cout << "P0[" << k << "]= (" << point_3d.x()
00201 << ' ' << point_3d.y() << ' ' << point_3d.z()
00202 << ")\n";
00203 bugl_normal_point_3d_sptr p3d_sptr =
00204 new bugl_normal_point_3d(point_3d, Sigma3d);
00205 pts_3d.push_back(p3d_sptr);
00206
00207 grad_angles_[t].push_back(angle0);
00208 tracked_points0.push_back(x0);
00209 tracked_points1.push_back(x1);
00210 observes_[0].push_back(x0);
00211 observes_[1].push_back(x1);
00212 k++;
00213 }
00214 }
00215 curve_3d_.add_curve(pts_3d);
00216 joe_observes_[t].push_back(tracked_points0);
00217 joe_observes_[t].push_back(tracked_points1);
00218 }
00219
00220 num_points_ = curve_3d_.get_num_points();
00221 prob_.resize(num_points_);
00222 for (int i=0; i<num_points_; i++)
00223 {
00224 prob_[i] = 1.0/num_points_;
00225 }
00226
00227 X_[0] = T[0];
00228 X_[1] = T[1];
00229 X_[2] = T[2];
00230 }
00231
00232
00233
00234
00235
00236 void brct_epi_reconstructor::init_covariant_matrix()
00237 {
00238
00239 Q_.set_identity();
00240
00241
00242
00243 vnl_double_3x3 Sigma;
00244
00245 Sigma = 0; Sigma[0][0] = 1;
00246 Sigma[1][1] = 0.25; Sigma[2][2] = 0.25;
00247
00248 vnl_double_3 xaxis(1, 0, 0);
00249 vnl_double_3 T(X_[0], X_[1], X_[2]);
00250 vnl_double_3 axis = vnl_cross_3d(xaxis, T);
00251 axis /= axis.magnitude();
00252 double theta = angle(T, xaxis);
00253
00254 vnl_quaternion<double> q(axis, theta);
00255 vnl_double_3x3 RT = q.rotation_matrix_transpose();
00256 Sigma = RT.transpose()*Sigma*RT;
00257
00258 Q0_ = 0.0;
00259 for (int i=0; i<3; i++)
00260 for (int j=0; j<3; j++)
00261 Q0_[i][j] = Sigma[i][j];
00262
00263
00264 for (int i=0; i<2; i++)
00265 for (int j=0; j<2; j++)
00266 R_[i][j] = 0;
00267
00268 for (int i=0; i<2; i++)
00269 R_[i][i] = 0.25;
00270 }
00271
00272 #if 0
00273 void brct_epi_reconstructor::init_cam_intrinsic()
00274 {
00275
00276 K_[0][0] = 841.3804; K_[0][1] = 0; K_[0][2] = 331.0916;
00277 K_[1][0] = 0; K_[1][1] = 832.7951; K_[1][2] = 221.5451;
00278 K_[2][0] = 0; K_[2][1] = 0; K_[2][2] = 1;
00279 }
00280 #endif
00281
00282 void brct_epi_reconstructor::init_cam_intrinsic()
00283 {
00284
00285 K_[0][0] = 2100; K_[0][1] = 0; K_[0][2] = 400;
00286 K_[1][0] = 0; K_[1][1] = 2100; K_[1][2] = 384;
00287 K_[2][0] = 0; K_[2][1] = 0; K_[2][2] = 1;
00288 }
00289
00290
00291 vnl_double_3x4 brct_epi_reconstructor::get_projective_matrix(const vnl_double_3& v ) const
00292 {
00293 vnl_double_3x4 M_ex;
00294
00295 for (int i=0; i<3; i++)
00296 for (int j=0; j<3; j++)
00297 M_ex[i][j] = 0;
00298
00299 for (int i=0; i<3; i++)
00300 M_ex[i][i] = 1;
00301
00302 for (int i=0; i<3; i++)
00303 M_ex[i][3] = v[i];
00304
00305 return K_*M_ex;
00306 }
00307
00308
00309 vnl_matrix_fixed<double, 2, 6> brct_epi_reconstructor::get_H_matrix(vnl_double_3x4 &P, vnl_double_3 &X)
00310 {
00311 vnl_matrix_fixed<double, 2, 6> H;
00312
00313
00314 double temp = P[2][3];
00315 for (int k = 0; k<3; k++)
00316 temp += P[2][k]*X[k];
00317
00318 for (int i=0; i<2; i++)
00319 {
00320
00321 double t = 0;
00322 for (int k=0; k<3; k++)
00323 t += P[i][k] * X[k];
00324 t += P[i][3];
00325
00326 for (int j=0; j<3; j++)
00327 H[i][j] = K_[i][j] / temp - t * K_[2][j] / (temp*temp);
00328
00329 for (int j=3; j<6; j++)
00330 H[i][j] = 0;
00331 }
00332
00333 return H;
00334 }
00335
00336
00337 vnl_double_2 brct_epi_reconstructor::projection(const vnl_double_3x4 &P, const vnl_double_3 &X)
00338 {
00339 vnl_double_2 z;
00340 double t1 = 0;
00341 for (int k=0; k<3; k++)
00342 t1 += P[2][k]*X[k];
00343 t1 += P[2][3];
00344
00345 for (int i=0; i<2; i++)
00346 {
00347 double t0 =0;
00348 for (int k=0; k<3; k++)
00349 t0 += P[i][k]*X[k];
00350 t0 += P[i][3];
00351
00352 z[i] = t0/t1;
00353 }
00354
00355 return z;
00356 }
00357
00358
00359 void brct_epi_reconstructor::update_observes(const vnl_double_3x4 &P, int iframe)
00360 {
00361 observes_[iframe%queue_size_].resize(num_points_);
00362 vnl_double_2x2 sigma;
00363 sigma.set_identity();
00364
00365 unsigned int c = tracks_.size();
00366 for (unsigned int t=0; t<c; ++t)
00367 {
00368 int frag_size = curve_3d_.get_fragment_size(t);
00369 for (int i=0; i<frag_size; i++)
00370 {
00371 int pos = curve_3d_.get_global_pos(t, i);
00372 bugl_gaussian_point_2d<double> x = brct_algos::project_3d_point(P, *curve_3d_.get_point(pos));
00373 vgl_point_2d<double> u = brct_algos::most_possible_point(tracks_[t][iframe], x);
00374
00375 observes_[iframe%queue_size_][pos].set_point(u);
00376 observes_[iframe%queue_size_][pos].set_covariant_matrix(sigma);
00377 }
00378 }
00379 }
00380
00381 bool brct_epi_reconstructor::match_point(vdgl_digital_curve_sptr const& dc,
00382 bugl_gaussian_point_2d<double>& p0,
00383 double grad_angle,
00384 bugl_gaussian_point_2d<double>& p)
00385 {
00386 vnl_double_2x2 sigma;
00387 sigma.set_identity();
00388
00389 vgl_point_2d<double> e((*e_)[0], (*e_)[1]), temp;
00390 vgl_line_2d<double> el(e, p0);
00391 if (!bdgl_curve_algs::match_intersection(dc, el, p0, grad_angle, temp))
00392 return false;
00393 p = bugl_gaussian_point_2d<double>(temp, sigma);
00394 return true;
00395 }
00396
00397
00398 void brct_epi_reconstructor::update_observes_joe(int iframe)
00399 {
00400 unsigned int c = tracks_.size();
00401 for (unsigned int t=0; t<c; ++t)
00402 {
00403
00404 vdgl_digital_curve_sptr dci = tracks_[t][iframe];
00405
00406 vcl_vector<bugl_gaussian_point_2d<double> > pts0 =
00407 joe_observes_[t][0];
00408 unsigned int npts = pts0.size();
00409
00410 vcl_vector<bugl_gaussian_point_2d<double> > cur_frame(npts);
00411 for (unsigned int i = 0; i<npts; ++i)
00412 {
00413 #if 0
00414 if (i>0)
00415 {
00416 vgl_line_2d<double> l(pts0[i-1], pts0[i]);
00417 double ang = l.slope_degrees();
00418 if (ang<0)
00419 ang +=180;
00420 if (debug_)
00421 vcl_cout << "\nTrack Tangent:" << ang << '\n';
00422 }
00423 #endif // 0
00424
00425 bugl_gaussian_point_2d<double> p;
00426 if (!match_point(dci, pts0[i], grad_angles_[t][i], p))
00427 vcl_cout << "Match failed for (" << pts0[i].x() << ' '
00428 << pts0[i].y() << ")\n";
00429 cur_frame[i]=p;
00430 }
00431 joe_observes_[t].push_back(cur_frame);
00432 }
00433 }
00434
00435 vcl_vector<bugl_gaussian_point_2d<double> >
00436 brct_epi_reconstructor::get_cur_joe_observes(int frame)
00437 {
00438 vcl_vector<bugl_gaussian_point_2d<double> > pts(num_points_);
00439 unsigned int c = tracks_.size();
00440 unsigned int ip = 0;
00441 for (unsigned int t = 0; t<c; ++t)
00442 for (unsigned int i = 0; i<joe_observes_[t][frame].size(); ++i, ++ip)
00443 pts[ip] = joe_observes_[t][frame][i];
00444 return pts;
00445 }
00446
00447 void brct_epi_reconstructor::write_results(const char* fname)
00448 {
00449 vcl_ofstream out(fname);
00450 int num_total_points = curve_3d_.get_num_points();
00451 out<<"[ point3d "
00452 <<num_total_points<<" ]\n";
00453
00454 for (int i=0; i<num_total_points; i++)
00455 {
00456 out<<curve_3d_.get_point(i)->x()<<' '
00457 <<curve_3d_.get_point(i)->y()<<' '
00458 <<curve_3d_.get_point(i)->z()<<' '
00459 <<curve_3d_.get_point(i)->exists()<<'\n';
00460 }
00461
00462
00463 int frame = 0;
00464 unsigned int c = tracks_.size();
00465 for (unsigned int t = 0; t<c; ++t)
00466 {
00467 out<<"[ curve "<< t <<' '<< joe_observes_[t][frame].size()<<" ]\n";
00468 for (unsigned int i = 0; i<joe_observes_[t][frame].size(); ++i)
00469 {
00470 out<< joe_observes_[t][frame][i].x()<< ' '
00471 << joe_observes_[t][frame][i].y()<< ' '
00472 << joe_observes_[t][frame][i].exists()<<'\n';
00473 }
00474 }
00475 return;
00476 }
00477
00478 void brct_epi_reconstructor::print_motion_array()
00479 {
00480 unsigned int n_frames = tracks_[0].size();
00481 if (!n_frames||!num_points_)
00482 return;
00483 for (unsigned int i = 2; i+1<n_frames; ++i)
00484 update_observes_joe(i);
00485 vnl_matrix<double> H(n_frames, num_points_);
00486 vcl_vector<bugl_gaussian_point_2d<double> > temp_0, temp_i, temp_i1;
00487 temp_0 = get_cur_joe_observes(0);
00488 for (unsigned int i = 0; i+1<n_frames; ++i)
00489 {
00490 temp_i = get_cur_joe_observes(i);
00491 temp_i1 = get_cur_joe_observes(i+1);
00492 for (unsigned int j = 0; j<temp_0.size(); ++j)
00493 {
00494 bugl_gaussian_point_2d<double>& gp_0 = temp_0[j], gp_i = temp_i[j],
00495 gp_i1 = temp_i1[j];
00496 if (!gp_0.exists()||!gp_i.exists()||!gp_i1.exists())
00497 continue;
00498 vnl_double_2 p_i(gp_i.x(), gp_i.y());
00499 vnl_double_2 p_i1(gp_i1.x(), gp_i1.y());
00500 double gamma = brct_algos::motion_constant(*e_, i, p_i, p_i1);
00501 vcl_cout << "gamma[" << i << "][" << j << "]("
00502 << gp_0.x() << ' ' << gp_0.y() << ") = " << gamma << '\n';
00503 H.put(i, j, gamma);
00504 }
00505 brct_algos::print_motion_array(H);
00506 }
00507 }
00508
00509
00510
00511 void brct_epi_reconstructor::update_confidence()
00512 {
00513 #if 1
00514 vcl_vector<vnl_double_3x4> cams(memory_size_);
00515 for (int i = 0; i < memory_size_; i++)
00516 cams[i] = get_projective_matrix(motions_[(cur_pos_-i)%memory_size_]);
00517
00518 double normalization_factor = 0;
00519 unsigned int c = tracks_.size();
00520 for (unsigned int t=0; t<c; ++t)
00521 {
00522 int frag_size = curve_3d_.get_fragment_size(t);
00523 for (int i=0; i<frag_size; i++)
00524 {
00525 double prob = 1;
00526 int pos = curve_3d_.get_global_pos(t, i);
00527
00528 for (int f = 0; f<memory_size_; ++f)
00529 {
00530 bugl_gaussian_point_2d<double> x = brct_algos::project_3d_point(cams[f], *curve_3d_.get_point(pos));
00531
00532 double probability = 0;
00533 vgl_point_2d<double> u = brct_algos::most_possible_point(tracks_[t][cur_pos_ - f], x);
00534 vnl_double_2 z1(x.x(), x.y()), z2(u.x(), u.y());
00535 if (probability<matched_point_prob(z1,z2)){
00536 probability = matched_point_prob(z1,z2);
00537 }
00538
00539 prob *= probability;
00540 }
00541
00542 prob_[pos] = prob;
00543 normalization_factor += prob_[pos];
00544 }
00545 }
00546
00547 vcl_cout<<"normalization_factor = "<<normalization_factor;
00548
00549
00550 if (normalization_factor == 0)
00551 return ;
00552
00553 for (int i=0; i<num_points_; i++)
00554 prob_[i] /= normalization_factor;
00555 #endif
00556
00557 #if 0
00558 for (int i=0; i<num_points_; i++)
00559 prob_[i] = 1.0/vnl_det(curve_3d_.get_point(i)->get_covariant_matrix());
00560 #endif
00561 }
00562
00563 #if 0 //original inc()
00564 void brct_epi_reconstructor::inc()
00565 {
00566 if ((unsigned)(cur_pos_+1) >= tracks_[0].size()){
00567 vcl_cout<<"\n at the end of last curve\n";
00568 return;
00569 }
00570
00571 cur_pos_ ++;
00572
00573
00574
00575
00576 vnl_matrix_fixed<double, 6, 6> A = get_transit_matrix(cur_pos_-1, cur_pos_);
00577 vcl_cout<<A<<'\n'
00578 <<X_<<'\n';
00579
00580 vnl_vector_fixed<double, 6> Xpred = A*X_;
00581
00582 vnl_double_3 camCenter(Xpred[0],Xpred[1],Xpred[2]);
00583 vnl_double_3x4 P = get_projective_matrix(camCenter);
00584
00585
00586
00587 update_observes(P, cur_pos_);
00588
00589
00590 vcl_vector<bugl_gaussian_point_2d<double> > & cur_measures = observes_[cur_pos_%queue_size_];
00591
00592
00593
00594
00595
00596 for (int i=0; i<num_points_; i++)
00597 {
00598 vnl_double_3 X;
00599
00600 X[0] = curve_3d_.get_point(i)->x();
00601 X[1] = curve_3d_.get_point(i)->y();
00602 X[2] = curve_3d_.get_point(i)->z();
00603
00604 vnl_matrix_fixed<double, 2, 6> H = get_H_matrix(P, X);
00605
00606 vnl_matrix_fixed<double, 6, 6> Qpred = A*Q_*A.transpose() + Q0_;
00607
00608 G_ = Qpred*H.transpose()*vnl_inverse(H*Qpred*H.transpose()+R_);
00609
00610 vnl_double_2 z(cur_measures[i].x(), cur_measures[i].y());
00611
00612 vnl_double_2 z_pred = projection(P,X);
00613 if (matched_point_prob(z, z_pred) >= 0)
00614 {
00615
00616
00617 Xpred = Xpred + G_*(z - z_pred)*prob_[i];
00618
00619 vnl_matrix_fixed<double, 6, 6> I;
00620 I.set_identity();
00621 Q_ = (I - G_*H)*Qpred;
00622 }
00623 }
00624
00625
00626 double dt = time_tick_[cur_pos_] - time_tick_[cur_pos_-1];
00627 Xpred[3] = (Xpred[0] - X_[0])/dt;
00628 Xpred[4] = (Xpred[1] - X_[1])/dt;
00629 Xpred[5] = (Xpred[2] - X_[2])/dt;
00630
00631 vnl_double_3 xNew(Xpred[0], Xpred[1], Xpred[2]);
00632
00633 motions_[cur_pos_%queue_size_] = xNew;
00634 P = get_projective_matrix(motions_[cur_pos_%queue_size_] );
00635 update_observes(P, cur_pos_);
00636
00637
00638 X_ = Xpred;
00639 vcl_cout<<"X_ = "<< X_;
00640
00641 if (memory_size_ < queue_size_)
00642 ++memory_size_;
00643
00644
00645
00646
00647
00648 vcl_vector<vnl_double_3x4> Ps(memory_size_);
00649 vcl_vector<vnl_double_2> pts(memory_size_);
00650 for (int i=0; i<num_points_; i++)
00651 {
00652
00653 for (int j=0; j<memory_size_; j++)
00654 {
00655 if (observes_[j][i].x() != this->large_num_ ||
00656 observes_[j][i].y() != this->large_num_){
00657 pts[j] = vnl_double_2(observes_[j][i].x(), observes_[j][i].y());
00658 Ps[j] = get_projective_matrix(motions_[j]);
00659 }
00660 }
00661
00662
00663 vgl_point_3d<double> X3d = brct_algos::bundle_reconstruct_3d_point(pts, Ps);
00664
00665
00666
00667
00668
00669
00670 bugl_normal_point_3d_sptr p3d_sptr = curve_3d_.get_point(i);
00671 vnl_double_3 dX(X3d.x() - p3d_sptr->x(), X3d.y() - p3d_sptr->y(), X3d.z() - p3d_sptr->z());
00672
00673
00674 vnl_double_3x3 Sigma3d = p3d_sptr->get_covariant_matrix();
00675 Sigma3d = Sigma3d*(cur_pos_-1.0)/(double)cur_pos_;
00676 for (int m = 0; m<3; m++)
00677 for (int n = 0; n<3; n++)
00678 Sigma3d[m][n] += dX[m]*dX[n] /(cur_pos_);
00679
00680 p3d_sptr->set_point(X3d);
00681 p3d_sptr->set_covariant_matrix(Sigma3d);
00682 }
00683
00684
00685 update_confidence();
00686 }
00687 #else //end of original inc()
00688
00689
00690 void brct_epi_reconstructor::inc()
00691 {
00692 if ((unsigned)(cur_pos_+1) >= tracks_[0].size()){
00693 vcl_cout<<"\n at the end of last curve\n";
00694 return;
00695 }
00696
00697 cur_pos_ ++;
00698 update_observes_joe(cur_pos_);
00699
00700
00701
00702 vcl_vector<bugl_gaussian_point_2d<double> >
00703 temp0 = get_cur_joe_observes(0),
00704 temp1 = get_cur_joe_observes(1),
00705 temp = get_cur_joe_observes(cur_pos_);
00706
00707 vcl_vector<vnl_double_2> points_0, points_1, points;
00708 int ip = 0;
00709 for (vcl_vector<bugl_gaussian_point_2d<double> >::iterator pit = temp0.begin(); pit != temp0.end(); pit++, ip++)
00710 {
00711 bugl_gaussian_point_2d<double>& gp1 = temp1[ip], gp = temp[ip];
00712 if (!(*pit).exists()||!gp1.exists()||!gp.exists())
00713 continue;
00714 vnl_double_2 p0((*pit).x(), (*pit).y());
00715 vnl_double_2 p1(gp1.x(), gp1.y());
00716 vnl_double_2 p(gp.x(), gp.y());
00717 points_0.push_back(p0);
00718 points_1.push_back(p1);
00719 points.push_back(p);
00720 }
00721 vnl_double_3 T;
00722 brct_algos::camera_translation(K_, *e_, points_0, points_1, points, T);
00723
00724 vnl_double_3 Tk;
00725
00726 vcl_cout << "X prior to update " << X_ << '\n';
00727
00728 #if 0
00729 vcl_cout << "Camera translation " << T << '\n';
00730 vnl_matrix_fixed<double, 6, 6> A = get_transit_matrix(cur_pos_-1, cur_pos_);
00731
00732 vnl_vector_fixed<double, 6> Xpred = A*X_;
00733 #endif
00734 #if 1
00735
00736 vnl_vector_fixed<double, 6> Xpred=X_;
00737 Xpred[0]=T[0]; Xpred[1]=T[1]; Xpred[2]=T[2];
00738 #endif
00739 vcl_cout << Xpred<< vcl_flush <<'\n';
00740 Tk[0]=Xpred[0]; Tk[1]=Xpred[1]; Tk[2]=Xpred[2];
00741 motions_[cur_pos_%queue_size_] = Tk;
00742
00743
00744 X_ = Xpred;
00745
00746 if (memory_size_ < queue_size_)
00747 ++memory_size_;
00748
00749
00750
00751
00752
00753 vcl_vector<vnl_double_3x4> Ps(memory_size_);
00754 vcl_vector<vnl_double_2> pts(memory_size_);
00755 unsigned int c = tracks_.size();
00756 int ipt = 0;
00757 for (unsigned int t=0; t<c; ++t)
00758 {
00759 unsigned int n = joe_observes_[t][0].size();
00760 for (unsigned int ip = 0; ip<n; ++ip, ++ipt)
00761 {
00762 for (int j =0; j<memory_size_; j++)
00763 if (joe_observes_[t][j][ip].exists()){
00764 pts[j] =
00765 vnl_double_2(joe_observes_[t][j][ip].x(),
00766 joe_observes_[t][j][ip].y());
00767 Ps[j] = get_projective_matrix(motions_[j]);
00768 }
00769
00770 vgl_point_3d<double> X3d =
00771 brct_algos::bundle_reconstruct_3d_point(pts, Ps);
00772 if (debug_)
00773 vcl_cout << "Pi[" << ipt << "]= (" << X3d.x()
00774 << ' ' << X3d.y() << ' ' << X3d.z()
00775 << ")\n";
00776
00777
00778 bugl_normal_point_3d_sptr p3d_sptr = curve_3d_.get_point(ipt);
00779 vnl_double_3 dX(X3d.x() - p3d_sptr->x(),
00780 X3d.y() - p3d_sptr->y(),
00781 X3d.z() - p3d_sptr->z());
00782 if (debug_)
00783 vcl_cout << "3dERROR " << dX.magnitude() << '\n';
00784 if (p3d_sptr->exists()&&dX.magnitude()>3)
00785 {
00786 if (debug_)
00787 vcl_cout << "Killing [" << ipt
00788 << "]= (" << X3d.x()
00789 << ' ' << X3d.y() << ' ' << X3d.z()
00790 << ")\n";
00791 p3d_sptr->set_point();
00792 continue;
00793 }
00794 #ifdef DEBUG
00795 vcl_cout << "dX( " << dX[0] << ' ' << dX[1] << ' ' << dX[2]
00796 #endif
00797
00798
00799 vnl_double_3x3 Sigma3d = p3d_sptr->get_covariant_matrix();
00800 Sigma3d = Sigma3d*(cur_pos_-1.0)/(double)cur_pos_;
00801 for (int m = 0; m<3; m++)
00802 for (int n = 0; n<3; n++)
00803 Sigma3d[m][n] += dX[m]*dX[n] /(cur_pos_);
00804
00805 p3d_sptr->set_point(X3d);
00806 p3d_sptr->set_covariant_matrix(Sigma3d);
00807 }
00808 }
00809 }
00810 #endif //end of joe version of inc()
00811
00812 void brct_epi_reconstructor::read_data(const char *fname)
00813 {
00814 vcl_ifstream fin(fname);
00815
00816 if (!fin){
00817 vcl_cerr<<"cannot open the file - "<<fname<<'\n';
00818 vcl_exit(2);
00819 }
00820
00821 char buff[255];
00822 fin >> buff;
00823
00824 time_tick_ = read_timestamp_file(buff);
00825
00826 while (fin>>buff){
00827 if (vcl_strlen(buff)<2 || buff[0]=='#')
00828 continue;
00829
00830
00831 this->add_track(read_track_file(buff));
00832 }
00833 }
00834
00835 vcl_vector<double> brct_epi_reconstructor::read_timestamp_file(char *fname)
00836 {
00837 vcl_ifstream fin(fname);
00838
00839 if (!fin){
00840 vcl_cerr<<"cannot open the file - "<<fname<<'\n';
00841 vcl_exit(2);
00842 }
00843
00844 int nviews =0, junk=0;
00845 fin >> nviews;
00846 vcl_vector<double> times(nviews);
00847
00848 for (int i=0; i<nviews; i++){
00849 fin>> junk >> times[i];
00850 }
00851
00852 return times;
00853 }
00854
00855 void
00856 brct_epi_reconstructor::add_track(vcl_vector<vdgl_digital_curve_sptr> const& track)
00857 {
00858 tracks_.push_back(track);
00859 }
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 vcl_vector<vdgl_digital_curve_sptr> brct_epi_reconstructor::read_track_file(char *fname)
00882 {
00883 vcl_ifstream fp(fname);
00884
00885 if (!fp){
00886 vcl_cerr<<" cannot open the file - "<<fname<<'\n';
00887 vcl_exit(2);
00888 }
00889
00890 char buffer[1000];
00891 int MAX_LEN=1000;
00892 int numEdges;
00893
00894 vcl_vector<vdgl_digital_curve_sptr > tracker;
00895
00896 double x, y, dir, conf;
00897 while (fp.getline(buffer,MAX_LEN))
00898 {
00899
00900 if (vcl_strlen(buffer)<2 || buffer[0]=='#')
00901 continue;
00902
00903
00904
00905
00906 if (!vcl_strncmp(buffer, "[BEGIN CONTOUR]", sizeof("[BEGIN CONTOUR]")-1))
00907 {
00908
00909 fp.getline(buffer,MAX_LEN);
00910
00911 vcl_sscanf(buffer,"EDGE_COUNT=%d",&(numEdges));
00912
00913
00914 vdgl_edgel_chain_sptr ec=new vdgl_edgel_chain;
00915
00916 for (int j=0; j<numEdges;j++)
00917 {
00918
00919 fp.getline(buffer,MAX_LEN);
00920 vcl_sscanf(buffer," [%lf, %lf] %lf %lf ", &(x), &(y), &(dir), &(conf));
00921 vdgl_edgel e;
00922 e.set_x(x);
00923 e.set_y(y);
00924 e.set_theta(dir);
00925 e.set_grad(conf);
00926 ec->add_edgel(e);
00927
00928 }
00929
00930 tracker.push_back(new vdgl_digital_curve(new vdgl_interpolator_linear(ec)));
00931
00932 fp.getline(buffer,MAX_LEN);
00933
00934
00935 assert(!vcl_strncmp(buffer, "[END CONTOUR]", sizeof("[END CONTOUR]")-1));
00936
00937 continue;
00938 }
00939 }
00940
00941 return tracker;
00942 }
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955 void brct_epi_reconstructor::init_velocity()
00956 {
00957 vcl_vector<vgl_homg_line_2d<double> > lines;
00958
00959 if (!e_)
00960 {
00961 vcl_cerr<<"epipole is not initialized\n";
00962 return;
00963 }
00964 vnl_double_3 e((*e_)[0],(*e_)[1],1.0);
00965 init_cam_intrinsic();
00966
00967
00968 double trans_dist = 1.0;
00969 vnl_double_3 T = vnl_inverse(K_) * e;
00970
00971 T /= vcl_sqrt(T[0]*T[0] + T[1]*T[1] + T[2]*T[2]);
00972
00973
00974 if (T[2]<0)
00975 T *= trans_dist;
00976 else
00977 T *= -trans_dist;
00978
00979
00980 X_[0] = T[0];
00981 X_[1] = T[1];
00982 X_[2] = T[2];
00983
00984 double dt = time_tick_[1]-time_tick_[0];
00985
00986
00987
00988 X_[3] = -T[0] /dt;
00989 X_[4] = -T[1] /dt;
00990 X_[5] = -T[2] /dt;
00991 }
00992
00993 bugl_curve_3d brct_epi_reconstructor::get_curve_3d()
00994 {
00995 return curve_3d_;
00996 }
00997
00998 vcl_vector<vgl_point_3d<double> > brct_epi_reconstructor::get_local_pts()
00999 {
01000 vcl_vector<vgl_point_3d<double> > pts;
01001
01002 double xc=0, yc=0, zc=0;
01003
01004 for (int i=0; i<num_points_; i++)
01005 {
01006 bugl_normal_point_3d_sptr pt3d_sptr = curve_3d_.get_point(i);
01007 xc += pt3d_sptr->x();
01008 yc += pt3d_sptr->y();
01009 zc += pt3d_sptr->z();
01010 }
01011
01012 xc /= num_points_;
01013 yc /= num_points_;
01014 zc /= num_points_;
01015
01016 for (int i=0; i<num_points_; i++)
01017 if (prob_[i] > 0) {
01018 bugl_normal_point_3d_sptr pt3d_sptr = curve_3d_.get_point(i);
01019 vgl_point_3d<double> pt(pt3d_sptr->x()-xc, pt3d_sptr->y()-yc, pt3d_sptr->z()-zc);
01020 pts.push_back(pt);
01021 }
01022
01023 return pts;
01024 }
01025
01026
01027 vcl_vector<vgl_point_2d<double> > brct_epi_reconstructor::get_next_observes()
01028 {
01029 vcl_vector<vgl_point_2d<double> > pts(num_points_);
01030
01031 unsigned int c = tracks_.size();
01032 for (unsigned int t=0; t<c; ++t)
01033 {
01034 vdgl_digital_curve_sptr dc = tracks_[t][(cur_pos_+1)%queue_size_];
01035 vdgl_interpolator_sptr interp = dc->get_interpolator();
01036 vdgl_edgel_chain_sptr ec = interp->get_edgel_chain();
01037 unsigned int size = ec->size();
01038 for (unsigned int i=0; i<size; ++i)
01039 {
01040 double s = double(i) / double(size);
01041 pts.push_back(vgl_point_2d<double> (dc->get_x(s), dc->get_y(s)));
01042 }
01043 }
01044 return pts;
01045 }
01046
01047
01048 vcl_vector<vgl_point_2d<double> > brct_epi_reconstructor::get_cur_observes()
01049 {
01050 vcl_vector<vgl_point_2d<double> > pts;
01051
01052 unsigned int c = tracks_.size();
01053
01054 for (unsigned int t=0; t<c; ++t)
01055 {
01056 vdgl_digital_curve_sptr dc = tracks_[t][cur_pos_];
01057 vdgl_interpolator_sptr interp = dc->get_interpolator();
01058 vdgl_edgel_chain_sptr ec = interp->get_edgel_chain();
01059 unsigned int size = ec->size();
01060 for (unsigned int i=0; i<size; ++i)
01061 {
01062 double s = double(i) / double(size);
01063 pts.push_back(vgl_point_2d<double>(dc->get_x(s), dc->get_y(s)));
01064 }
01065 }
01066 return pts;
01067 }
01068
01069 vcl_vector<vgl_point_2d<double> > brct_epi_reconstructor::get_joe_cur_observes()
01070 {
01071 vcl_vector<bugl_gaussian_point_2d<double> > pts =
01072 this->get_cur_joe_observes(cur_pos_);
01073
01074 unsigned int Np = pts.size();
01075 vcl_vector<vgl_point_2d<double> > res;
01076 for (unsigned int i=0; i<Np; ++i)
01077 res.push_back(vgl_point_2d<double>(pts[i].x(), pts[i].y()));
01078 return res;
01079 }
01080
01081
01082 vcl_vector<vgl_point_2d<double> > brct_epi_reconstructor::get_joe_pre_observes()
01083 {
01084 assert(cur_pos_ > 0);
01085 vcl_vector<bugl_gaussian_point_2d<double> > pts =
01086 this->get_cur_joe_observes(cur_pos_-1);
01087
01088 unsigned int Np = pts.size();
01089 vcl_vector<vgl_point_2d<double> > res;
01090 for (unsigned int i=0; i<Np; ++i)
01091 res.push_back(vgl_point_2d<double>(pts[i].x(), pts[i].y()));
01092 return res;
01093 }
01094
01095 vcl_vector<vgl_point_2d<double> > brct_epi_reconstructor::get_joe_next_observes()
01096 {
01097 vcl_vector<bugl_gaussian_point_2d<double> > pts =
01098 this->get_cur_joe_observes(cur_pos_+1);
01099
01100 unsigned int Np = pts.size();
01101 vcl_vector<vgl_point_2d<double> > res;
01102 for (unsigned int i=0; i<Np; ++i)
01103 res.push_back(vgl_point_2d<double>(pts[i].x(), pts[i].y()));
01104 return res;
01105 }
01106
01107
01108 vcl_vector<vgl_point_2d<double> > brct_epi_reconstructor::get_pre_observes()
01109 {
01110 assert(cur_pos_ > 0);
01111 vcl_vector<vgl_point_2d<double> > pts;
01112
01113 unsigned int c = tracks_.size();
01114
01115 for (unsigned int t = 0; t<c; ++t)
01116 {
01117 vdgl_digital_curve_sptr dc = tracks_[t][(cur_pos_-1)%queue_size_];
01118 vdgl_interpolator_sptr interp = dc->get_interpolator();
01119 vdgl_edgel_chain_sptr ec = interp->get_edgel_chain();
01120 unsigned int size = ec->size();
01121 for (unsigned int i=0; i<size; ++i)
01122 {
01123 double s = double(i) / double(size);
01124 pts.push_back(vgl_point_2d<double> (dc->get_x(s), dc->get_y(s)));
01125 }
01126 }
01127 return pts;
01128 }
01129
01130 vnl_double_3 brct_epi_reconstructor::get_next_motion(vnl_double_3 v)
01131 {
01132 return motions_[cur_pos_]+v;
01133 }
01134
01135
01136 vnl_matrix<double> brct_epi_reconstructor::get_predicted_curve()
01137 {
01138
01139
01140
01141 vnl_matrix_fixed<double, 6, 6> A = get_transit_matrix(cur_pos_, cur_pos_+1);
01142 vnl_vector_fixed<double, 6> Xpred = A*X_;
01143 vnl_double_3 camCenter(Xpred[0],Xpred[1],Xpred[2]);
01144 vnl_double_3x4 P = get_projective_matrix(camCenter);
01145
01146 vnl_matrix<double> t(2, num_points_);
01147 for (int i=0; i<num_points_; i++)
01148 {
01149 vgl_point_2d<double> x = brct_algos::projection_3d_point(*curve_3d_.get_point(i), P);
01150
01151 t[0][i] = x.x();
01152 t[1][i] = x.y();
01153 }
01154
01155 return t;
01156 }
01157
01158
01159 vcl_vector<vnl_matrix<double> > brct_epi_reconstructor::get_back_projection() const
01160 {
01161 vcl_vector<vnl_matrix<double> > res(memory_size_);
01162 for (int f=0; f<memory_size_; f++)
01163 {
01164 vnl_double_3x4 P = get_projective_matrix(motions_[f]);
01165
01166 vnl_matrix<double> t(2, num_points_);
01167
01168 for (int i=0; i<num_points_; i++)
01169 {
01170 vgl_point_2d<double> p = brct_algos::projection_3d_point(* curve_3d_.get_point(i), P);
01171 t[0][i] = p.x();
01172 t[1][i] = p.y();
01173 }
01174
01175 res[f] = t;
01176 }
01177
01178 return res;
01179 }
01180
01181
01182 vgl_point_2d<double> brct_epi_reconstructor::get_cur_epipole() const
01183 {
01184 vnl_double_3 T(motions_[cur_pos_%queue_size_]);
01185
01186
01187 vnl_double_3x4 E1, E2;
01188 E1[0][0] = 1; E1[0][1] = 0; E1[0][2] = 0; E1[0][3] = 0;
01189 E1[1][0] = 0; E1[1][1] = 1; E1[1][2] = 0; E1[1][3] = 0;
01190 E1[2][0] = 0; E1[2][1] = 0; E1[2][2] = 1; E1[2][3] = 0;
01191
01192 E2[0][0] = 1; E2[0][1] = 0; E2[0][2] = 0; E2[0][3] = T[0];
01193 E2[1][0] = 0; E2[1][1] = 1; E2[1][2] = 0; E2[1][3] = T[1];
01194 E2[2][0] = 0; E2[2][1] = 0; E2[2][2] = 1; E2[2][3] = T[2];
01195
01196 vnl_double_3x4 P1 = K_*E1, P2 = K_*E2;
01197
01198
01199 vnl_double_3 e = K_*T;
01200 vgl_homg_point_2d<double> res(e[0], e[1], e[2]);
01201 return res;
01202 }
01203
01204 void brct_epi_reconstructor::init_epipole(double x, double y)
01205 {
01206 if (!e_)
01207 e_ = new vnl_double_2;
01208
01209 (*e_)[0] = x;
01210 (*e_)[1] = y;
01211 }
01212
01213
01214 double brct_epi_reconstructor::matched_point_prob(vnl_double_2& z, vnl_double_2& z_pred)
01215 {
01216
01217
01218
01219
01220 vnl_double_2 dz = z - z_pred;
01221 double d2 = dz[0]*dz[0] + dz[1]*dz[1];
01222
01223 if (d2 > 5)
01224 return 0;
01225 else
01226 return vcl_exp(-d2/2);
01227 }
01228
01229
01230 vnl_matrix_fixed<double, 6, 6> brct_epi_reconstructor::get_transit_matrix(int i, int j)
01231 {
01232 assert(i>=0 && j>=0 && j>=i);
01233 vnl_matrix_fixed<double, 6, 6> A;
01234
01235 double dt = time_tick_[j] - time_tick_[i];
01236
01237
01238 for (int i=0; i<6; i++)
01239 for (int j=0; j<6; j++)
01240 A[i][j] = 0.0;
01241
01242 for (int i = 0; i<6; i++)
01243 A[i][i] = 1;
01244
01245 for (int i=0; i<3; i++)
01246 A[i][i+3] = dt;
01247
01248 return A;
01249 }
01250
01251 void brct_epi_reconstructor::print_track(const int track_index, const int frame)
01252 {
01253 if ((unsigned int)track_index>=tracks_.size())
01254 return;
01255 vcl_vector<vdgl_digital_curve_sptr> track = tracks_[track_index];
01256 if ((unsigned int)frame>=track.size())
01257 return;
01258 for (vcl_vector<vdgl_digital_curve_sptr>::iterator cit = track.begin();
01259 cit != track.end(); cit++)
01260 {
01261 vdgl_interpolator_sptr intp = (*cit)->get_interpolator();
01262 vdgl_edgel_chain_sptr chain = intp->get_edgel_chain();
01263 vcl_cout << *chain << '\n';
01264 }
01265 }