Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
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
00035 if (! mvl_five_point_camera_pencil(u[i], v[i], &A[i], &B[i]))
00036 return false;
00037
00038
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
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
00048 vnl_vector<double> coeffs(4);
00049 mvl_psi_constraint_restrict(&p[0], &q[0], &coeffs[0]);
00050
00051
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
00060 double re = roots.real(k);
00061 double im = roots.imag(k);
00062 if (vcl_abs(im) > 0.03 * vcl_abs(re)) {
00063 solution[k].valid = false;
00064
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 }