SVD分解 三角测量

本文通过代码演示了如何使用SVD(奇异值分解)解决三角测量问题,涉及4x4矩阵A和SE3变换参数在相机投影下的应用。重点讲解了如何将像素坐标转换为世界坐标,并通过矩阵操作求解三维点的世界坐标,同时讨论了解质量判断标准。

原理的推导这篇文章已经很详细了,

这里放一段带注释的代码,便于理解。

   //SVD解三角测量
   //A:4✖4, P:4x1(X,Y,Z,1)
   //在这里解释一下原理
   //point1(归一化像素坐标)= 1/s1*K*[I|0]*pt_world, point1 = (u1, v1)
   //point2(归一化像素坐标)= 1/s2*K*[R21|t]*pt_world, point2=(u2, v2) //相对坐标变换
   //pr1 = K*[I|0], pr2 = K[R21|t], 就是这里的pose
   //下面矩阵中的";"表示换行
   //写成行向量pr1 = [pr1,1; pr1,2; pr1,3], pr2 = [pr2,1; pr2,2; pr2,3]
   //所以上面的变换成了[s1u1; s1v1; s1] = [pr1,1; pr1,2; pr1,3]P1, point2一样
   //把s1 = pr1,3*P1代入前两行,消掉第3行,得到[pr1,3*P1*u1] = [pr1,1*P1],后面同样
   //把point1, point2的4个等式组合,得到
   //[pr1,3*u1 - pr1,1]
   //[Pr1,3*v1 - pr1,2] * P1 = 0, 左边4x4的矩阵就是函数中的A,pr为函数中的m
   //[pr2,3*u2 - pr2,1]
   //[pr2,3*v2 - pr2,2]
   inline bool triangulation(const vector<SE3> &poses, vector<Vec3> points, Vec3 &pt_world) {
       MatXX A(2 * poses.size(), 4);
       VecX b(2 * poses.size());
       b.setZero();
       for(size_t i = 0; i < poses.size(); i++) {
           Mat34 m = poses[i].matrix3x4();
           A.block<1, 4>(2 * i, 0) = points[i][0] * m.row(2) - m.row(0);
           A.block<1, 4>(2 * i + 1, 0) = points[i][1] * m.row(2) - m.row(1);
       }
       auto svd = A.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV);
       //A(4x4) = UWV^T, 即A[V1, V2, V3, V4] = U*diag(sigma1, sigma2, sigma3, sigma4), sigma4 = 0
       //满足A*V4 = 0, SVD分解得到的V矩阵的最后一列作为P1的解
       pt_world = (svd.matrixV().col(3) / svd.matrixV()(3, 3)).head<3>();

       if (svd.singularValues()[3] / svd.singularValues()[2] < 1e-2) {
           // 解质量不好,放弃
           return false;
       }
       return true;
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值