我在OpenCV中阅读了函数solvePnP()
的源代码,当flags
param使用默认值SOLVEPNP_ITERATIVE
时,它正在调用cvFindExtrinsicCameraParams2
,它首先使用 DLT 算法(如果我们有一组非平面的3D点)来初始化6DOF相机姿势,而SECOND使用CvLevMarq solver
来最小化重投影错误。
我的问题是:DLT将问题形成为线性最小二乘问题并用SVD分解解决它,它似乎是一个最优解,为什么我们之后仍然使用Lev-Marq迭代方法?
或者,DLT算法的问题/限制是什么?为什么封闭形式的解决方案导致成本函数 LOCAL 最小?
答案 0 :(得分:11)
当您想要找到问题的解决方案时,第一步是用数学术语表达这个问题,然后您可以使用现有的数学工具来找到方程式的解。然而,有趣的问题通常可以用许多不同的数学方式表达,每种方法都可能导致稍微不同的解决方案。然后,需要分析不同的方法,以了解哪一种方法提供最稳定/准确/有效的/等解决方案。
在PnP问题的情况下,我们希望找到3D点与其投影图像平面之间关联的相机姿势。
以数学方式表达此问题的第一种方法是将其转换为线性最小二乘问题。这种方法被称为DLT方法,并且它很有趣,因为线性最小二乘法具有封闭形式的解,可以使用奇异值分解来稳健地找到。然而,这种方法假设相机姿势P实际上只有6个时具有12个自由度(3个用于3D旋转加3个用于3D平移)。为了从这种方法的结果获得6DOF相机姿态,需要近似(DLT的线性成本函数不包括),导致解决方案不准确。
以数学方式表达PnP问题的第二种方法是使用几何误差作为成本函数,并找到最小化几何误差的相机姿势。由于几何误差是非线性的,因此该方法使用迭代求解器(例如Levenberg Marquardt算法)来估计解。这样的算法可以考虑相机姿态的6个自由度,从而得到准确的解决方案。但是,由于它们是迭代方法,因此需要为它们提供解决方案的初始估计,实际上通常使用DLT方法获得。
现在回答你问题的标题:确定,DLT算法给出了最佳的摄像机外部效应,但它仅在DLT算法解决的线性成本函数意义上是最优的。多年来,科学家发现更复杂的成本函数导致更准确的解决方案,但也更难以解决。