十四讲第十章ceres_ba

ceres_custombundle

ceres同样包含common(提供了命令解析commandargs、参数配置bundleparams、数据存储读写BALProblem、重投影函数projection及常用数学工具tools)和data(存放txt格式数据集)。
除此之外包含SnavelyReprojectionError.h(计算重投影误差代价函数)以及ceresBundle.cpp(ceres优化)

1. SnavelyReprojectionError.h

定义误差类,承接观测数据,计算误差,生成误差雅克比,使用了common中的projection.h及tools/rotation.h
第一步:定义误差类,通过构造函数读取观测值坐标
第二步:通过重载的括号函数用于计算重投影误差,与g2o_bal_class中类似,参数为camera,point和用于承接结果的predictions
第三步:通过静态成员函数create(观测值),直接生成误差对应雅克比矩阵代价函数对象的指针,作为向优化器中添加问题函数的第一个参数.
   使用ceres的自动求导模板类创建,模板参数为误差类,输出维度,输入维度(camera,point),构造函数参数为具体模板参数设定的对象.使用create函数传入的参数观测值实例化一个误差对象,将该误差对象用于实例化误差雅克比AutoDiffCostFunction对象.

2. ceresBundle.cpp

用到BALProblem(用于数据读取存储),BundleParams(优化参数解析配置)和SnavelyReprojectionError.h
主要包含三个函数SetSolverOptionsFromFlags、BuildProblem、SolveProblem
其中SetSolverOptionsFromFlags是执行了SetMinimizerOptions、SetLinearSolver、SetOrdering的调用。

i. SetSolverOptionsFromFlags

参数为数据类BALProblem*,参数类const BundleParams&以及优化求解器ceres::Solver::Options*
执行

SetMinimizerOptions(options,params); 
SetLinearSolver(options,params);
SetOrdering(bal_problem, options,params);

可以直接列出一堆options->,此处根据设计的功能,分成了三个函数。根本上还是定义个option对象,直接一通options->就好了。

i.i SetMinimizerOptions 设置下降优化计算相关选项

传入的参数为优化求解器设置Solver::options*,参数对象const BundleParams&
设置了最大迭代次数,是否输出优化log日志,设置线程数,最大求解时间,下降策略选取(置信域)

CHECK(StringToTrustRegionStrategyType(params.trust_region_strategy,&options->trust_region_strategy_type));
i.ii SetLinearSolver 设置线性求解器

参数为优化求解器设置Solver::options*,参数对象const BundleParams&
设置线性求解器类型及线程

i.iii SetOrdering 消元顺序设置

参数为数据存储对象BALProblem*,优化求解器设置Solver::options*,参数对象const BundleParams&
第一步:提取数据规模(数量、维度)
第二步:检查若顺序设置为自动,return
第三步:创建个ParameterBlockOrdering类型的对象ordering,用来管理schur消元顺序,在下面按顺序使用 AddElementToGroup 来对变量进行编号从而定义消元顺序把参数码进去,达到排序的目的,进行按序消元,其中设为0先消元,常将路标点设为0
第四步options->linear_solver_ordering.reset(ordering)设置消元顺序

ii. BuildProblem

参数为数据存储对象BALProblem*,要构建的问题对象Problem*, 参数配置对象const BundleParams&
第一步:读出路标相机维度及首位置,观测首位值
第二步:遍历观测数目,添加问题,其中AddResidualBlock()所对应的参数分别为:代价函数(雅克比),损失函数(核函数),待估计参数1,待估计参数2…其中待估计参数均使用数组,维度在求雅克比时模板已填
1. 利用观测数据创建SnavelyReprojectionError对象,使用其静态成员函数create得到CostFunction指针.
2. 判断参数表中核函数形式,定义problem->AddResidualBlock()中所需要的损失函数LossFunction
.常用huber核函数
3. 关联该观测对应的相机和路标点,取出对应的数据值.
4. 使用

problem->AddResidualBlock(cost_function, loss_function, camera, point);
iii. SolveProblem

参数为数据集文件名,参数配置对象
第一步:使用BALProblem读取数据
第二步:存储初始点云文件
第三步:添加噪声
第四步:实例化Problem对象,调用BuildProblem构建问题
第五步:创建求解器选项对象Solver::Options,调用SetSolverOptionsFromFlags配置求解器,设置梯度和两次迭代之间目标函数之差的阈值
第六步:实例化Summary对象以输出迭代结果
第七步:调用solve函数进行优化求解参数为配置器,问题(指针),简报输出对象(指针)

ceres::Solve(options, &problem, &summary);

第八步:将最终求解结果输出为ply文件
可见使用ceres是直接在原始数组上进行操作,无需像g2o通过,先将数据通过复制(映射成矩阵赋值)到节点或边,优化后再从优化器内节点中取出优化后数据复制(memcpy)到BALProblem的对应数组,再生成点云文件.

iiii. main函数

第一步:解析配置命令
第二步:初始化?

 google::InitGoogleLogging(argv[0]);

第三步:执行solveProblem

SolveProblem(params.input.c_str(), params);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值