Go to the documentation of this file.00001
00006 #ifndef VSLAM_SFM_UTILS_H_INCLUDED
00007 #define VSLAM_SFM_UTILS_H_INCLUDED
00008
00009 #include "utils.h"
00010 #include <Eigen/Dense>
00011 #include "Sophus/se3.h"
00012
00013
00028 void computeStructure(
00029 const SE3 & T_c1c2,
00030 const ImageMatchVec & matches_c1c2,
00031 const IdxPoint3dVec & idx_points3d_c1,
00032 Points3dSTL & points3d_c1,
00033 SE3 & scaled_T_c1c2);
00034
00040 void computeStructure(
00041 const Sophus::SE3 & T_c1c2,
00042 const ImageMatchVec & matches_c1c2,
00043 Points3dSTL & triangulated_points_c1);
00044
00050 void computeStructureForcePositiveDepths(
00051 const Sophus::SE3 & T_c1c2,
00052 const ImageMatchVec & matches_c1c2,
00053 Points3dSTL & triangulated_points_c1);
00054
00062 void computeStructure(
00063 const Sophus::SE3 & T_c1c2, const ImageMatch& match_c1c2, Vector3d & triangulated_point_c1);
00064
00072 void computeStructureForcePositiveDepth(
00073 const Sophus::SE3 & T_c1c2, const ImageMatch& match_c1c2, Vector3d & triangulated_point_c1);
00074
00075
00082 double computeScale(const Points3dSTL& points1, const Points3dSTL& points2);
00083
00084
00094 void computeScale( const Points3dSTL& points1, const Points3dSTL& points2,
00095 double& low, double& mid, double& hi);
00096
00103 bool extractTransformFromE(const ImageMatchVec & image_matches, const Matrix3d & E, SE3 & res_tr);
00104
00105
00107 inline Matrix3d computeE(const ImageMatchVec & matches){
00108 int n = matches.size();
00109 MatrixXd A(9, n);
00110
00111 for (int i=0 ; i < n; i++){
00112 Vector3d pt1 = matches[i].first;
00113 Vector3d pt2 = matches[i].second;
00114 A(0,i) = pt1.x()*pt2.x();
00115 A(1,i) = pt1.x()*pt2.y();
00116 A(2,i) = pt1.x()*pt2.z();
00117
00118 A(3,i) = pt1.y()*pt2.x();
00119 A(4,i) = pt1.y()*pt2.y();
00120 A(5,i) = pt1.y()*pt2.z();
00121
00122 A(6,i) = pt1.z()*pt2.x();
00123 A(7,i) = pt1.z()*pt2.y();
00124 A(8,i) = pt1.z()*pt2.z();
00125 }
00126
00127
00128 Matrix3d F;
00129 VectorXd E_s = A.transpose().jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(VectorXd::Zero(n));
00130 Eigen::SelfAdjointEigenSolver<MatrixXd> eigensolver(A * A.transpose());
00131 E_s = eigensolver.eigenvectors().col(1);
00132 F.col(0) = E_s.segment(0,3);
00133 F.col(1) = E_s.segment(3,3);
00134 F.col(2) = E_s.segment(6,3);
00135
00136
00137
00138
00139 Eigen::JacobiSVD<MatrixXd> svd2(F, Eigen::ComputeFullU | Eigen::ComputeFullV);
00140 Matrix3d Sigma = Matrix3d::Zero();
00141 Sigma(0,0) = 1;
00142 Sigma(1,1) = 1;
00143 Matrix3d E = svd2.matrixU() * Sigma * svd2.matrixV().transpose();
00144 return E;
00145 }
00146
00153 inline Vector3d closestPointOnEpipolarPlane(const Vector3d & hom_line, const Vector3d & hom_point){
00154
00155
00156 double tmp = hom_line.dot(hom_line);
00157 if(isApprox(tmp, 0.0, 0.0000000001)) return hom_point;
00158 double l_param = -hom_line.dot(hom_point) / tmp;
00159 return hom_point + l_param * hom_line;
00160 }
00161
00162
00163
00164 #endif