本文主要根据Ceres官方教程翻译的来。
开发Ceres库的一个重要出发点就是计算光束法平差Bundle Adjustment,简称BA。
关于光束法平差的原理可以参考这篇博客《Bundle Adjustment简述》 现简单的概况如下:
空间中一个点在成像平面的坐标系中投影成一个像素。这个投影称为初次投影。如果我们有多个相机,可以根据空间中同一点在不同相机中的投影(即像素坐标)来反向确定这个点的空间位置。然后使这个逆向计算出的空间点,再次向各个相机投影,如此我们会再次得到对应的像素。这个投影称为重投影。因为逆向计算是有误差的,相机矩阵也不是完全精准的。所以这个重投影和初次投影的位置往往是有微小偏差的。最理想的参数应该使空间点的初次投影和重投影的偏差尽可能小。如果我们有很多这样的数据,我们就可以通过优化的方法确定参数。这就是光束法平差的基本原理。具体计算可以参看上面提到的博客。
Ceres对BA的介绍如下:
给定一系列测得的图像,包含特征点位置和对应关系。BA的目标就是,通过最小化重投影误差,确定三维空间点的位置和相机参数。这个优化问题通常被描述为非线性最小二乘法问题,要最小化的目标函数即为测得图像中特征点位置和相机成像平面上的对应的投影之间的差的平方。Ceres例程使用了BAL数据集 。
第一步依然使定义一个模板functor来计算残差,在这个问题中也就是的重投影误差。每个残差值依赖于空间点的位置(3个参数)和相机参数(9个参数)。九个相机参数包含用Rodriques’ axis-angle表示的旋转向量(3个参数),平移参数(3个参数),以及焦距和两个径向畸变参数。相机模型的详细描述也可以在BAL的主页找到。
具体代码如下:
struct SnavelyReprojectionError {
SnavelyReprojectionError(double observed_x, double observed_y)
: observed_x(observed_x), observed_y(o