contrib/oxl/mvl/mvl_three_view_six_point_structure.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/mvl_three_view_six_point_structure.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author fsm
00008 
00009 #include "mvl_three_view_six_point_structure.h"
00010 
00011 #include <vcl_cmath.h>
00012 
00013 #include <vnl/algo/vnl_svd.h>
00014 #include <vnl/algo/vnl_rpoly_roots.h>
00015 
00016 #include <mvl/mvl_five_point_camera_pencil.h>
00017 #include <mvl/mvl_six_point_design_matrix_row.h>
00018 #include <mvl/mvl_psi.h>
00019 
00020 mvl_three_view_six_point_structure::mvl_three_view_six_point_structure()
00021   : u(3, 6)
00022   , v(3, 6)
00023 {
00024 }
00025 
00026 
00027 bool mvl_three_view_six_point_structure::compute()
00028 {
00029   vnl_double_3x4 A[3];
00030   vnl_double_3x4 B[3];
00031   vnl_matrix<double> design(3, 5);
00032 
00033   for (int i=0; i<3; ++i) {
00034     // compute camera pencils.
00035     if (! mvl_five_point_camera_pencil(u[i], v[i], &A[i], &B[i]))
00036       return false;
00037 
00038     // fill out design matrix.
00039     mvl_six_point_design_matrix_row(A[i].as_matrix(), B[i].as_matrix(), u[i][5], v[i][5], design[i]);
00040   }
00041 
00042   // compute pencil of solutions.
00043   vnl_svd<double> svd(design);
00044   vnl_vector<double> p = svd.V().get_column(3);
00045   vnl_vector<double> q = svd.V().get_column(4);
00046 
00047   // restrict the cubic to the pencil :
00048   vnl_vector<double> coeffs(4);
00049   mvl_psi_constraint_restrict(&p[0], &q[0], &coeffs[0]);
00050 
00051   // solve the cubic on the pencil.
00052   if (vcl_abs(coeffs[0]) > vcl_abs(coeffs[3])) {
00053     coeffs.flip();
00054     swap(p, q);
00055   }
00056   vnl_rpoly_roots roots(coeffs);
00057 
00058   for (int k=0; k<3; ++k) {
00059     // extract solution, if (approximately) real.
00060     double re = roots.real(k);
00061     double im = roots.imag(k);
00062     if (/* im != 0 */vcl_abs(im) > 0.03 * vcl_abs(re)) {
00063       solution[k].valid = false;
00064       //solution[k].clear();
00065       continue;
00066     }
00067     else {
00068       solution[k].valid = true;
00069       mvl_psi_invert((re * p + q).data_block(), solution[k].Q.data_block());
00070     }
00071 
00072     for (int i=0; i<3; ++i) {
00073       double st[2];
00074       if (! mvl_five_point_camera_pencil_parameters(A[i], B[i],
00075                                                     solution[k].Q,
00076                                                     u[i][5], v[i][5],
00077                                                     st, 0))
00078         solution[k].valid = false;
00079       else
00080         solution[k].P[i] = st[0] * A[i] + st[1] * B[i];
00081     }
00082   }
00083 
00084   return true;
00085 }