42 Eigen::Matrix3d* R2, Eigen::Vector3d* t) {
43 Eigen::JacobiSVD<Eigen::Matrix3d> svd(
44 E, Eigen::ComputeFullU | Eigen::ComputeFullV);
45 Eigen::Matrix3d U = svd.matrixU();
46 Eigen::Matrix3d V = svd.matrixV().transpose();
48 if (U.determinant() < 0) {
51 if (V.determinant() < 0) {
56 W << 0, 1, 0, -1, 0, 0, 0, 0, 1;
59 *R2 = U * W.transpose() * V;
60 *t = U.col(2).normalized();
64 const std::vector<Eigen::Vector2d>& points1,
65 const std::vector<Eigen::Vector2d>& points2,
66 Eigen::Matrix3d* R, Eigen::Vector3d* t,
67 std::vector<Eigen::Vector3d>* points3D) {
68 CHECK_EQ(points1.size(), points2.size());
75 const std::array<Eigen::Matrix3d, 4> R_cmbs{{R1, R2, R1, R2}};
76 const std::array<Eigen::Vector3d, 4> t_cmbs{{*t, *t, -*t, -*t}};
79 for (
size_t i = 0; i < R_cmbs.size(); ++i) {
80 std::vector<Eigen::Vector3d> points3D_cmb;
82 if (points3D_cmb.size() >= points3D->size()) {
85 *points3D = points3D_cmb;
91 const Eigen::Vector3d& t) {
98 const Eigen::Matrix3d R1 = proj_matrix1.leftCols<3>();
99 const Eigen::Matrix3d R2 = proj_matrix2.leftCols<3>();
100 const Eigen::Vector3d t1 = proj_matrix1.rightCols<1>();
101 const Eigen::Vector3d t2 = proj_matrix2.rightCols<1>();
104 const Eigen::Matrix3d R = R2 * R1.transpose();
105 const Eigen::Vector3d t = t2 - R * t1;
111 const Eigen::Vector2d& point1,
112 const Eigen::Vector2d& point2,
113 Eigen::Vector2d* optimal_point1,
114 Eigen::Vector2d* optimal_point2) {
115 const Eigen::Vector3d& point1h = point1.homogeneous();
116 const Eigen::Vector3d& point2h = point2.homogeneous();
118 Eigen::Matrix<double, 2, 3> S;
119 S << 1, 0, 0, 0, 1, 0;
122 Eigen::Vector2d n1 = S * E * point2h;
123 Eigen::Vector2d n2 = S * E.transpose() * point1h;
125 const Eigen::Matrix2d E_tilde = E.block<2, 2>(0, 0);
127 const double a = n1.transpose() * E_tilde * n2;
128 const double b = (n1.squaredNorm() + n2.squaredNorm()) / 2.0;
129 const double c = point1h.transpose() * E * point2h;
130 const double d = sqrt(b * b -
a * c);
131 double lambda = c / (b + d);
133 n1 -= E_tilde * lambda * n1;
134 n2 -= E_tilde.transpose() * lambda * n2;
136 lambda *= (2.0 * d) / (n1.squaredNorm() + n2.squaredNorm());
138 *optimal_point1 = (point1h - S.transpose() * lambda * n1).hnormalized();
139 *optimal_point2 = (point2h - S.transpose() * lambda * n2).hnormalized();
143 const bool left_image) {
146 Eigen::JacobiSVD<Eigen::Matrix3d> svd(E, Eigen::ComputeFullV);
147 e = svd.matrixV().block<3, 1>(0, 2);
149 Eigen::JacobiSVD<Eigen::Matrix3d> svd(E.transpose(), Eigen::ComputeFullV);
150 e = svd.matrixV().block<3, 1>(0, 2);
156 return E.transpose();
160 const std::vector<Eigen::Vector2d>& points1,
161 const std::vector<Eigen::Vector2d>& points2,
162 const std::vector<char>& inlier_mask,
163 Eigen::Matrix3d* E) {
164 CHECK_EQ(points1.size(), points2.size());
165 CHECK_EQ(points1.size(), inlier_mask.size());
170 size_t num_inliers = 0;
171 for (
const auto inlier : inlier_mask) {
177 std::vector<Eigen::Vector2d> inlier_points1(num_inliers);
178 std::vector<Eigen::Vector2d> inlier_points2(num_inliers);
180 for (
size_t i = 0; i < inlier_mask.size(); ++i) {
181 if (inlier_mask[i]) {
182 inlier_points1[j] = points1[i];
183 inlier_points2[j] = points2[i];
191 Eigen::Vector3d tvec;
192 std::vector<Eigen::Vector3d> points3D;
198 if (points3D.size() == 0) {
205 const bool refinement_success =
208 if (!refinement_success) {
Matrix< double, 3, 4 > Matrix3x4d
Eigen::Matrix3d InvertEssentialMatrix(const Eigen::Matrix3d &E)
Eigen::Matrix3d EssentialMatrixFromAbsolutePoses(const Eigen::Matrix3x4d &proj_matrix1, const Eigen::Matrix3x4d &proj_matrix2)
void FindOptimalImageObservations(const Eigen::Matrix3d &E, const Eigen::Vector2d &point1, const Eigen::Vector2d &point2, Eigen::Vector2d *optimal_point1, Eigen::Vector2d *optimal_point2)
Eigen::Matrix3d CrossProductMatrix(const Eigen::Vector3d &vector)
Eigen::Matrix3d EssentialMatrixFromPose(const Eigen::Matrix3d &R, const Eigen::Vector3d &t)
void DecomposeEssentialMatrix(const Eigen::Matrix3d &E, Eigen::Matrix3d *R1, Eigen::Matrix3d *R2, Eigen::Vector3d *t)
Eigen::Vector4d RotationMatrixToQuaternion(const Eigen::Matrix3d &rot_mat)
Eigen::Vector3d EpipoleFromEssentialMatrix(const Eigen::Matrix3d &E, const bool left_image)
bool RefineRelativePose(const ceres::Solver::Options &options, const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, Eigen::Vector4d *qvec, Eigen::Vector3d *tvec)
void PoseFromEssentialMatrix(const Eigen::Matrix3d &E, const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, Eigen::Matrix3d *R, Eigen::Vector3d *t, std::vector< Eigen::Vector3d > *points3D)
bool RefineEssentialMatrix(const ceres::Solver::Options &options, const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, const std::vector< char > &inlier_mask, Eigen::Matrix3d *E)
bool CheckCheirality(const Eigen::Matrix3d &R, const Eigen::Vector3d &t, const std::vector< Eigen::Vector2d > &points1, const std::vector< Eigen::Vector2d > &points2, std::vector< Eigen::Vector3d > *points3D)
Eigen::Matrix3d QuaternionToRotationMatrix(const Eigen::Vector4d &qvec)