7. Bundle Adjustment
给定一组测量的图像特征位置和对应关系,Bundle Adjustment 的目标是找到最小化重投影误差的 3D 点位置和相机参数。 该优化问题通常被表述为非线性最小二乘问题,其中误差是观察到的特征位置与相机图像平面上相应 3D 点的投影之间的差异的平方范数。 Ceres 为解决 Bundle Adjustment 问题提供了广泛的支持。
BAL 问题中的每个残差都取决于一个三维点和一个九参数相机。 定义相机的九个参数是:三个用于作为罗德里格斯轴角矢量的旋转,三个用于平移,一个用于焦距,两个用于径向畸变。 此相机型号的详细信息可以在 Bundler 主页和 BAL 主页中找到。
1)读取数据
拿到一个数据集,首先要了解其含义,即每个数据所代表的意义。然后根据其不同的意义分类,思考如何通过代码的方式如何读入数据。
第二次记录:
已经了解到,数据集分为三部分,1 header 相关的个数数据 2 某个相机观察到的3D点以及对应的2D观察点的数据 3 相机参数(9个)以及3D点的坐标
(1)读入第一部分的个数
1 相机个数:int num_cameras_;
2 所观测的现实世界的位置,即3D点数量:int num_points_;
3 观测的2D点的数量:int num_observations_;
以上可以通过通过数据集的第一行得到。
int num_observations() const {
return num_observations_; }
FscanfOrDie(fptr, "%d", &num_cameras_);
FscanfOrDie(fptr, "%d", &num_points_);
FscanfOrDie(fptr, "%d", &num_observations_);
(2)每个相机观察到的3D点的索引以及其对应的2D点的两个坐标(第二部分)
思考:只能按行读取数据,一次读取一行中的一个数据,其中一个隐含的条件是第二部分的行数与观测到的2D坐标点的个数相同,所以比较有用的便是 num_observations_ ,其描述了循环读取数据的次数。
每一行中第一个数据表示第几个相机,第二个数据表示观测到的第几个3D点,那么由于 “第几个”,所以定义索引:
int* point_index_;
int* camera_index_;
第几个观察到的2D点:double* observations_;
point_index_ = new int[num_observations_];
camera_index_ = new int[num_observations_];
observations_ = new double[2 * num_observations_];
point_index_ = new int[num_observations_];
camera_index_ = new int[num_observations_];
observations_ = new double[2 * num_observations_];
num_parameters_ = 9 * num_cameras_ + 3 * num_points_;
parameters_ = new double[num_parameters_];
for (int i = 0; i < num_observations_; ++i) {
FscanfOrDie(fptr, "%d", camera_index_ + i);
FscanfOrDie(fptr, "%d", point_index_ + i);
for (int j = 0; j < 2; ++j) {
FscanfOrDie(fptr, "%lf", observations_ + 2 * i + j);
}
}
(3)每个相机的参数以及3D点的坐标(第三部分)
如何读入这部分的数据?
1 首先确定这一部分总共有多少数据:int num_parameters_;
num_parameters_ = 9 * num_cameras_ + 3 * num_points_;
2 通过 “第几个“确定位置
double* parameters_;
3 首先将读取到的参数看作整体,然后再分配:
for (int i = 0; i < num_parameters_; ++i) {
FscanfOrDie(fptr, "%lf", parameters_ + i);
}
double* mutable_cameras() {
return parameters_; } //相机参数首地址
double* mutable_points() {
return parameters_ + 9 * num_cameras_; } //3D点的首地址
double* mutable_camera_for_observation(int i) {
//返回第i个相机
return mutable_cameras(<

本文介绍了Bundle Adjustment问题的优化过程,使用Ceres库进行非线性最小二乘求解。首先,详细阐述了如何从数据集中读取相机参数、3D点坐标和观测的2D点信息。接着,解析了SnavelyReprojectionError结构,用于计算重投影误差。最后,展示了如何构建Ceres问题并调用求解器进行优化。整个过程涵盖了数据处理、误差模型和数值求解的关键步骤。
最低0.47元/天 解锁文章
1408

被折叠的 条评论
为什么被折叠?



