gaoxiang12 / slambook2

edition 2 of the slambook
MIT License
5.39k stars 2k forks source link

ch7 pose_estimation_3d2d.cpp #249

Open 0315Clyyy opened 1 year ago

0315Clyyy commented 1 year ago

小白求助一下各位,请问为什么在 pose_estimation_3d2d.cpp 中面对图为每条边对应两个节点的情况依然将边设置一元边?是因为只有一个优化变量T吗?既然设置了一元边为什么在 typedef g2o::BlockSolver<g2o::BlockSolverTraits<6, 3>> BlockSolverType; 中设置<6,3>呢?这和在前面ch6讲的曲线拟合时设置的 typedef g2o::BlockSolver<g2o::BlockSolverTraits<3, 1>> BlockSolverType; 有什么区别呢?

silverbulletmdc commented 1 year ago

读完第九章我才理解这个问题,之前有点误人子弟了。 g2o主要面向的是图优化问题,所以问题定义的时候需要一些图优化的基本信息。 这里的6,3两个维度分别是相机和路标点的维度。这里的Block指代的其实是hessian矩阵中长方形的非0块。(见第二版图9-7) 也就是说,g2o优化的问题必须满足下面的定义:存在两种待优化节点。每条边的两端必须是这两种节点(同种类节点之间不存在边)。这样最后优化问题的Hessian矩阵才符合箭头矩阵的形式,G2O实际是专门优化这种问题的。而两个模版参数分别是两种节点各自的维度,方便后面g2o进行Schur消元。

在一开始的曲线拟合问题中,实际上只存在一个节点(a,b,c)。因此实际上Hessian矩阵就是简单的3*3形式,没有右侧的长方形区域,不需要做Schur消元。所以这个地方的<3,1>实际没有被优化器使用。为了验证这个想法,我把<3,1>改为<3,10>,然后编译执行后依然得到了正确的结果. image image 所以我感觉代码中这里的注释写错了。1并不是误差的维度。

另外3d2d里只优化了T,所以实际上block也没有用到。我感觉这里的<6,3>改了应该也不会影响。不过写成<6,3>方便后面扩展到同时优化位姿和路标。 image (这里改成了<6,1>) image (依然可以获得正确结果)