PICCANTE  0.4
The hottest HDR imaging library!
essential_matrix.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_COMPUTER_VISION_ESSENTIAL_MATRIX_HPP
19 #define PIC_COMPUTER_VISION_ESSENTIAL_MATRIX_HPP
20 
21 #include <vector>
22 #include <random>
23 #include <stdlib.h>
24 
25 #include "../base.hpp"
26 
27 #include "../util/math.hpp"
28 #include "../util/eigen_util.hpp"
29 
30 #include "../computer_vision/triangulation.hpp"
31 #include "../computer_vision/camera_matrix.hpp"
32 
33 #ifndef PIC_DISABLE_EIGEN
34 
35 #ifndef PIC_EIGEN_NOT_BUNDLED
36  #include "../externals/Eigen/Dense"
37  #include "../externals/Eigen/SVD"
38  #include "../externals/Eigen/Geometry"
39 #else
40  #include <Eigen/Dense>
41  #include <Eigen/SVD>
42  #include <Eigen/Geometry>
43 #endif
44 
45 #endif
46 
47 namespace pic {
48 
49 #ifndef PIC_DISABLE_EIGEN
50 
59 PIC_INLINE Eigen::Matrix3d computeEssentialMatrix(Eigen::Matrix3d &F, Eigen::Matrix3d &K1, Eigen::Matrix3d &K2)
60 {
61  Eigen::Matrix3d K2t = Eigen::Transpose<Eigen::Matrix3d>(K2);
62  return K2t * F * K1;
63 }
64 
72 PIC_INLINE Eigen::Matrix3d computeEssentialMatrix(Eigen::Matrix3d &F, Eigen::Matrix3d &K)
73 {
74  return computeEssentialMatrix(F, K, K);
75 }
76 
91 PIC_INLINE void decomposeEssentialMatrix(Eigen::Matrix3d &E, Eigen::Matrix3d &R1, Eigen::Matrix3d &R2, Eigen::Vector3d &t)
92 {
93  //Solving the linear system
94  Eigen::JacobiSVD< Eigen::MatrixXd > svd(E, Eigen::ComputeThinU | Eigen::ComputeThinV);
95  Eigen::Matrix3d U = svd.matrixU();
96  Eigen::Matrix3d V = svd.matrixV();
97 
98  //Z matrix
99  Eigen::Matrix3d Z;
100  Z.setZero();
101  Z(0, 1) = 1.0;
102  Z(1, 0) = -1.0;
103 
104  //W matrix
105  Eigen::Matrix3d W;
106  W.setZero();
107  W(0, 1) = -1.0;
108  W(1, 0) = 1.0;
109  W(2, 2) = 1.0;
110 
111  //Rotation matrices R1 and R2
112  Eigen::Matrix3d Vt = Eigen::Transpose<Eigen::Matrix3d>(V);
113  Eigen::Matrix3d Wt = Eigen::Transpose<Eigen::Matrix3d>(W);
114 
115  Eigen::Matrix3d UVt = U * Vt;
116  double detUVt = UVt.determinant();
117 
118  R1 = detUVt * U * W * Vt;
119  R2 = detUVt * U * Wt * Vt;
120 
121  R1 = RotationMatrixRefinement(R1);
122  R2 = RotationMatrixRefinement(R2);
123 
124  //Translation vector
125  Eigen::Matrix3d Ut = Eigen::Transpose<Eigen::Matrix3d>(U);
126  Eigen::Matrix3d S = U * Z * Ut;
127 
128  t[0] = S(2, 1);
129  t[1] = S(0, 2);
130  t[2] = S(1, 0);
131 
132  t.normalize();
133 }
134 
146 PIC_INLINE bool decomposeEssentialMatrixWithConfiguration(Eigen::Matrix3d &E, Eigen::Matrix3d &K0, Eigen::Matrix3d &K1,
147  std::vector< Eigen::Vector2f > &points0, std::vector< Eigen::Vector2f > &points1,
148  Eigen::Matrix3d &R, Eigen::Vector3d &t)
149 {
150  if(points0.size() != points1.size()) {
151  return false;
152  }
153 
154  Eigen::Matrix3d R0, R1;
155  Eigen::Vector3d T;
156  decomposeEssentialMatrix(E, R0, R1, T);
157 
158  //for each configuration (R0, -T), (R0, T), (R1, -T), (R1, T)
159  //the sign of reconstructed points is checked
160  int type = -1;
161  int counter = -1;
162 
163  for(unsigned int j = 0; j < 4; j++) {
164 
165  Eigen::Matrix3d tmp_R = (j < 2) ? R0 : R1;
166  Eigen::Vector3d tmp_T;
167 
168  if((j % 2) == 0) {
169  tmp_T = T;
170  } else {
171  tmp_T = -T;
172  }
173 
174  Eigen::Matrix34d M0 = getCameraMatrixIdentity(K0);
175  Eigen::Matrix34d M1 = getCameraMatrix(K1, tmp_R, tmp_T);
176 
177  int tmp_counter = 0;
178  for(unsigned int i = 0; i < points0.size(); i++) {
179  //homogeneous coordinates
180  Eigen::Vector3d point_0 = Eigen::Vector3d(points0[i][0], points0[i][1], 1.0);
181  Eigen::Vector3d point_1 = Eigen::Vector3d(points1[i][0], points1[i][1], 1.0);
182 
183  Eigen::Vector4d p0 = triangulationHartleySturm(point_0, point_1, M0, M1);
184  Eigen::Vector3d p0_euc = Eigen::Vector3d(p0[0], p0[1], p0[2]);
185  Eigen::Vector3d p1 = rigidTransform(p0_euc, tmp_R, tmp_T);
186 
187  if((p0[2] >= 0.0) && (p1[2] >= 0.0)) {
188  tmp_counter++;
189  }
190 
191  }
192 
193  #ifdef PIC_DEBUG
194  printf("Front: %d %d\n",tmp_counter,j);
195  #endif
196 
197  if(tmp_counter > counter) {
198  type = j;
199  counter = tmp_counter;
200  }
201  }
202 
203  if(type > -1) {
204 
205  R = (type < 2) ? R0 : R1;
206 
207  if((type % 2) == 0) {
208  t = T;
209  } else {
210  t = -T;
211  }
212 
213  return true;
214 
215  } else {
216  R.setZero();
217  t.setZero();
218 
219  return false;
220  }
221 }
222 
223 #endif // PIC_DISABLE_EIGEN
224 
225 } // end namespace pic
226 
227 #endif // PIC_COMPUTER_VISION_ESSENTIAL_MATRIX_HPP
PIC_INLINE Eigen::Matrix34d getCameraMatrixIdentity(Eigen::Matrix3d &K)
getCameraMatrixIdentity
Definition: camera_matrix.hpp:118
PIC_INLINE Eigen::Matrix34d getCameraMatrix(Eigen::Matrix3d &K, Eigen::Matrix3d &R, Eigen::Vector3d &t)
getCameraMatrix
Definition: camera_matrix.hpp:132
PIC_INLINE Eigen::Vector4d triangulationHartleySturm(Eigen::Vector3d &point_0, Eigen::Vector3d &point_1, Eigen::Matrix34d &M0, Eigen::Matrix34d &M1, int maxIter=100)
triangulationHartl Sturm
Definition: triangulation.hpp:83
#define PIC_INLINE
Definition: base.hpp:33
PIC_INLINE void decomposeEssentialMatrix(Eigen::Matrix3d &E, Eigen::Matrix3d &R1, Eigen::Matrix3d &R2, Eigen::Vector3d &t)
decomposeEssentialMatrix decomposes an essential matrix E.
Definition: essential_matrix.hpp:91
PIC_INLINE Eigen::Vector3d rigidTransform(Eigen::Vector3d &point, Eigen::Matrix3d &R, Eigen::Vector3d &t)
rigidTransform computes a rigidi transformation in 3D.
Definition: eigen_util.hpp:333
Definition: bilateral_separation.hpp:25
PIC_INLINE Eigen::Matrix3d computeEssentialMatrix(Eigen::Matrix3d &F, Eigen::Matrix3d &K1, Eigen::Matrix3d &K2)
computeEssentialMatrix computes the essential matrix, E, from the fundamental matrix, F12, and the two intrics matrices K1 and K2
Definition: essential_matrix.hpp:59
PIC_INLINE Eigen::Matrix3d RotationMatrixRefinement(Eigen::Matrix3d &R)
RotationMatrixRefinement.
Definition: eigen_util.hpp:343
PIC_INLINE bool decomposeEssentialMatrixWithConfiguration(Eigen::Matrix3d &E, Eigen::Matrix3d &K0, Eigen::Matrix3d &K1, std::vector< Eigen::Vector2f > &points0, std::vector< Eigen::Vector2f > &points1, Eigen::Matrix3d &R, Eigen::Vector3d &t)
decomposeEssentialMatrixWithConfiguration decomposes an essential matrix E.
Definition: essential_matrix.hpp:146