vpgl_essential_matrix.hxx
Go to the documentation of this file.
1 // This is core/vpgl/vpgl_essential_matrix.hxx
2 #ifndef vpgl_essential_matrix_hxx_
3 #define vpgl_essential_matrix_hxx_
4 //:
5 // \file
6 
7 #include <iosfwd>
9 #include <vnl/vnl_fwd.h>
10 #include <vnl/vnl_vector_fixed.h>
11 #include <vnl/vnl_matrix_fixed.h>
12 #include <vnl/vnl_det.h>
13 #include <vgl/vgl_point_2d.h>
14 #include <vgl/vgl_point_3d.h>
15 #include <vgl/vgl_homg_point_3d.h>
17 #ifdef _MSC_VER
18 # include <vcl_msvc_warnings.h>
19 #endif
20 #include "vpgl_proj_camera.h"
21 
22 
23 //---------------------------------
24 template <class T>
26 
27 template <class T>
30  const vpgl_calibration_matrix<T>& K_left,
31  const vpgl_calibration_matrix<T>& K_right)
32 {
34  vnl_matrix_fixed<T, 3, 3> krm = K_right.get_matrix();
36  this->set_matrix(klm.transpose()*fm*krm);
37 }
38 
39 //--------------------------------------------
40 //: Compute from Euclidean properties of perspective cameras
41 template <class T>
44  const vpgl_perspective_camera<T>& cl )
45 {
46  //copy the cameras
47  vpgl_perspective_camera<T> crc = cr, clc = cl;
48  //set the calibration matrices to identity
50  crc.set_calibration(K); clc.set_calibration(K);
51  vpgl_proj_camera<T> ppr = static_cast<vpgl_proj_camera<T> >(crc);
52  vpgl_proj_camera<T> ppl = static_cast<vpgl_proj_camera<T> >(clc);
53  this->set_matrix(crc, clc);
54 }
55 
56 //---------------------------------
57 //: Copy Constructor
58 template <class T>
61 : vpgl_fundamental_matrix<double>(other)
62 {
63 }
64 
65 //---------------------------------
66 template <class T>
69 {
71  return *this;
72 }
73 
74 //---------------------------------
75 //: Destructor
76 template <class T>
78 
79 //---------------------------------
80 // Decompose the essential matrix to obtain rotation and translation of
81 // the "left" camera. A correspondence is needed in order to remove the
82 // ambiguity of the decomposition. There are four possible solutions.
83 // The translation vector, t, in the decomposition,[R|t], is normalized to
84 // have magnitude, translation_mag.
85 template <class T>
87  const vgl_point_2d<T>& left_corr,
88  const vgl_point_2d<T>& right_corr,
90  const T translation_mag )
91 {
92  //The right camera is the identity camera [I|0]
94 
96  W[0][0]=0; W[0][1]=-1;W[0][2]=0;
97  W[1][0]=1; W[1][1]=0; W[1][2]=0;
98  W[2][0]=0; W[2][1]=0; W[2][2]=1;
99 
100  vnl_svd<T> SVD(E.get_matrix().as_ref());
101  vnl_matrix_fixed<T,3,3> U=SVD.U();
102  vnl_matrix_fixed<T,3,3> V=SVD.V();
105  // checking for the correct combination of cameras
106  for ( int c = 0; c < 4; c++ )
107  {
108  if ( c == 0 ) { //case 1
109  R=U*W.transpose()*V.transpose();
110  t=U.get_column(2);
111  }
112  if ( c == 1 ) { //case 2
113  R=U*W*V.transpose();
114  t=U.get_column(2);
115  }
116  if ( c == 2 ) { //case 3
117  R=U*W.transpose()*V.transpose();
118  t=-U.get_column(2);
119  }
120  if ( c == 3 ) { //case 4
121  R=U*W*V.transpose();
122  t=-U.get_column(2);
123  }
124  if ( vnl_det<T>( R ) < 0 ) R = -R ;
125  t*=translation_mag;
126  vnl_vector_fixed<T, 3> cc = -R.transpose()*t;
127  p_left.set_rotation( vgl_rotation_3d<T>(R) );
128  p_left.set_camera_center( vgl_point_3d<T>( cc(0), cc(1), cc(2) ) );
129  vpgl_proj_camera<T> ppl =
130  static_cast<vpgl_proj_camera<T> >(p_left);
131  vpgl_proj_camera<T> ppr =
132  static_cast<vpgl_proj_camera<T> >(p_right);
133  //Test to see if the 3-d point formed by triangulation is in front
134  //of the camera. There should exist one solution.
135  vgl_point_3d<T> p3d = triangulate_3d_point<T>(ppl, left_corr, ppr, right_corr );
136  vgl_homg_point_3d<T> ph3d(p3d);
137  if (!p_right.is_behind_camera(ph3d) && !p_left.is_behind_camera(ph3d))
138  break;
139  if ( c == 3 ) {
140  std::cerr << "ERROR: extract_left_camera in vpgl_essential_matrix failed.\n";
141  return false;
142  }
143  }
144 
145  return true;
146 }
147 
148 template <class T>
149 std::ostream& operator<<(std::ostream& s, vpgl_essential_matrix<T> const& p)
150 {
151  s << p.get_matrix();
152  return s;
153 }
154 
155 //: Read vpgl_perspective_camera from stream
156 template <class T>
157 std::istream& operator>>(std::istream& s, vpgl_essential_matrix<T>& p)
158 {
160  s >> m;
161  p.set_matrix(m);
162  return s;
163 }
164 
165 // Code for easy instantiation.
166 #undef vpgl_ESSENTIAL_MATRIX_INSTANTIATE
167 #define vpgl_ESSENTIAL_MATRIX_INSTANTIATE(T) \
168 template class vpgl_essential_matrix<T >; \
169 template bool extract_left_camera(const vpgl_essential_matrix<T >& E, \
170  const vgl_point_2d<T >& left_corr, \
171  const vgl_point_2d<T >& right_corr, \
172  vpgl_perspective_camera<T >& p_left, \
173  const T translation_mag); \
174 template std::ostream& operator<<(std::ostream&, const vpgl_essential_matrix<T >&); \
175 template std::istream& operator>>(std::istream&, vpgl_essential_matrix<T >&)
176 
177 
178 #endif // vpgl_essential_matrix_hxx_
A class for the essential matrix between two projective cameras.
vnl_matrix_ref< T > as_ref()
void set_rotation(const vgl_rotation_3d< T > &R)
bool extract_left_camera(const vpgl_essential_matrix< T > &E, const vgl_point_2d< T > &left_corr, const vgl_point_2d< T > &right_corr, vpgl_perspective_camera< T > &p_left, const T translation_mag)
Left camera extractor. Normalized correspondence pair is needed to determine which of four solutions ...
std::istream & operator>>(std::istream &is, vpgl_local_rational_camera< T > &p)
Read from stream.
#define m
A class representing the "K" matrix of a perspective camera matrix as described in.
void set_camera_center(const vgl_point_3d< T > &camera_center)
const vpgl_essential_matrix< T > & operator=(const vpgl_essential_matrix< T > &em)
Assignment.
void set_calibration(const vpgl_calibration_matrix< T > &K)
Setters and getters.
vnl_matrix_fixed< T, num_cols, num_rows > transpose() const
vnl_matrix_fixed< T, 3, 3 > F_
Internal representation of the fundamental matrix.
vnl_matrix_fixed< T, 3, 3 > get_matrix() const
Get the calibration matrix.
std::ostream & operator<<(std::ostream &s, const vpgl_local_rational_camera< T > &p)
Write to stream.
This class implements the perspective camera class as described in Hartley & Zisserman as a finite ca...
A camera model using the standard 3x4 matrix representation.
bool is_behind_camera(const vgl_homg_point_3d< T > &world_point) const
Determine whether the given point lies in front of the principal plane.
vpgl_essential_matrix()
Default constructor creates dummy rank 2 matrix.
~vpgl_essential_matrix() override
Destructor.
const vnl_matrix_fixed< T, 3, 3 > & get_matrix() const
Get a copy of the FM in vnl form.
void set_matrix(const vpgl_proj_camera< T > &cr, const vpgl_proj_camera< T > &cl)