NOTE / 2019/4/21
[MVG] 三角化地图点
在ORB-SLAM等基于特征点的V-SLAM算法中,地图点大都通过三角化的方法给出初值,再利用最小化重投影误差优化的方式进行细化。 本篇给出了三角化的详细求解步骤。
一个3D点的齐次坐标为 ,它到图像上的投影为
两边同时左叉乘 , 有
展开后可得
上式三个方程实际上只能提供两个方程的约束,因为(1)式×(-u)-(2)式×v=(3)式。
一个帧可以形成两个方程,那么两个帧可以形成四个方程:
这里可以使用SVD求解(参考MVG),齐次坐标 即为 的最小奇异值的奇异向量。
下面给出代码
void triangulate ( const Eigen::Matrix3d& K,
const Eigen::Matrix4d T1, const Eigen::Matrix4d& T2,
const Eigen::Vector2d& uu1, const Eigen::Vector2d& uu2,
Eigen::Vector4d& X )
{
// construct P1 P2
const Eigen::Matrix<double, 3, 4> P1 = K * T1.block(0,0, 3, 4);
const Eigen::Matrix<double, 3, 4> P2 = K * T2.block(0, 0, 3, 4);
// get vectors
const Eigen::Matrix<double, 1, 4>& P11 = P1.block(0, 0, 1, 4);
const Eigen::Matrix<double, 1, 4>& P12 = P1.block(1, 0, 1, 4);
const Eigen::Matrix<double, 1, 4>& P13 = P1.block(2, 0, 1, 4);
const Eigen::Matrix<double, 1, 4>& P21 = P2.block(0, 0, 1, 4);
const Eigen::Matrix<double, 1, 4>& P22 = P2.block(1, 0, 1, 4);
const Eigen::Matrix<double, 1, 4>& P23 = P2.block(2, 0, 1, 4);
const double& u1 = uu1[0];
const double& v1 = uu1[1];
const double& u2 = uu2[0];
const double& v2 = uu2[1];
// construct H matrix.
Eigen::Matrix4d H;
H.block(0, 0, 1, 4) = v1 * P13 - P12;
H.block(1, 0, 1, 4) = P11 - u1 * P13;
H.block(2, 0, 1, 4) = v2 * P23 - P22;
H.block(3, 0, 1, 4) = P21 - u2 * P23;
// SVD
Eigen::JacobiSVD<Eigen::MatrixXd> svd ( H, Eigen::ComputeFullU | Eigen::ComputeFullV );
Eigen::Matrix4d V = svd.matrixV();
X = V.block(0, 3, 4, 1);
X = X / X(3, 0);
} // triangulate
全部工程代码
ydsf16/MVG_Algorithm
参考资料
[1] Multiple View Geometry in Computer Vision