4000-520-616
欢迎来到免疫在线!(蚂蚁淘生物旗下平台)  请登录 |  免费注册 |  询价篮
主营:原厂直采,平行进口,授权代理(蚂蚁淘为您服务)
咨询热线电话
4000-520-616
当前位置: 首页 > 新闻动态 >
新闻详情
Ceres库,从入门到放弃_工大机器人工作室-CSDN博客_ceres
来自 : CSDN技术社区 发布时间:2021-03-24
int main(int argc, char** argv) { CERES_GFLAGS_NAMESPACE::ParseCommandLineFlags( argc, argv, true); google::InitGoogleLogging(argv[0]); double x1 3.0; double x2 -1.0; double x3 0.0; double x4 1.0; Problem problem; // Add residual terms to the problem using the using the autodiff // wrapper to get the derivatives automatically. The parameters, x1 through // x4, are modified in place. problem.AddResidualBlock(new AutoDiffCostFunction F1, 1, 1, 1 (new F1), NULL, x1, x2); problem.AddResidualBlock(new AutoDiffCostFunction F2, 1, 1, 1 (new F2), NULL, x3, x4); problem.AddResidualBlock(new AutoDiffCostFunction F3, 1, 1, 1 (new F3), NULL, x2, x3); problem.AddResidualBlock(new AutoDiffCostFunction F4, 1, 1, 1 (new F4), NULL, x1, x4); Solver::Options options; options.max_num_iterations 100; options.linear_solver_type ceres::DENSE_QR; options.minimizer_progress_to_stdout true; std::cout Initial x1 x1 , x2 x2 , x3 x3 , x4 x4 // Run the solver! Solver::Summary summary; Solve(options, problem, summary); std::cout summary.FullReport() \\n std::cout Final x1 x1 , x2 x2 , x3 x3 , x4 x4 return 0;}

如果一个函数的参数受到其他多个函数的约束 针对每个函数 分别定义costfunction 然后调用AddResidualBlock添加到目标函数。

四、曲线拟合

我的模板是根据曲线拟合的例子总结的 所以直接套用 可以体会下 那个我留作可选部分的作用。

下面的程序用于拟合y exp ax^2 bx c 。通过opencv的rng产生误差 然后在拟合。

#include iostream #include opencv2/core/core.hpp #include ceres/ceres.h #include chrono using namespace std;// 代价函数的计算模型struct CURVE_FITTING_COST CURVE_FITTING_COST ( double x, double y ) : _x ( x ), _y ( y ) {} // 残差的计算 template typename T  bool operator() ( const T* const abc, // 模型参数 有3维 T* residual ) const // 残差 residual[0] T ( _y ) - ceres::exp ( abc[0]*T ( _x ) *T ( _x ) abc[1]*T ( _x ) abc[2] ); // y-exp(ax^2 bx c) return true; const double _x, _y; // x,y数据int main ( int argc, char** argv ) double a 1.0, b 2.0, c 1.0; // 真实参数值 int N 100; // 数据点 double w_sigma 1.0; // 噪声Sigma值 cv::RNG rng; // OpenCV随机数产生器 double abc[3] {0,0,0}; // abc参数的估计值 vector double x_data, y_data; // 数据 cout generating data: endl; for ( int i i i ) double x i/100.0; x_data.push_back ( x ); y_data.push_back ( exp ( a*x*x b*x c ) rng.gaussian ( w_sigma ) cout x_data[i] y_data[i] endl; // 构建最小二乘问题 ceres::Problem problem; for ( int i i i ) problem.AddResidualBlock ( // 向问题中添加误差项 // 使用自动求导 模板参数 误差类型 输出维度 输入维度 维数要与前面struct中一致 new ceres::AutoDiffCostFunction CURVE_FITTING_COST, 1, 3 (  new CURVE_FITTING_COST ( x_data[i], y_data[i] ) nullptr, // 核函数 这里不使用 为空 abc // 待估计参数 // 配置求解器 ceres::Solver::Options options; // 这里有很多配置项可以填 options.linear_solver_type ceres::DENSE_QR; // 增量方程如何求解 options.minimizer_progress_to_stdout true; // 输出到cout ceres::Solver::Summary summary; // 优化信息 chrono::steady_clock::time_point t1 chrono::steady_clock::now(); ceres::Solve ( options, problem, summary ); // 开始优化 chrono::steady_clock::time_point t2 chrono::steady_clock::now(); chrono::duration double time_used chrono::duration_cast chrono::duration double ( t2-t1 ); cout solve time cost time_used.count() seconds. endl; // 输出结果 cout summary.BriefReport() endl; cout estimated a,b,c  for ( auto a:abc ) cout a  cout endl; return 0;}

这样的函数拟合 对于一些错误的点也会考虑在内 如果存在误差很大的点 会导致整体拟合的效果不好。所以 更加鲁棒 robust 的方法就是使用LossFunction 损失函数。

\"\"

下面就是重点了 敲黑板

五、BundleAdjustment

中文名光束法平差 我记不住 有些人叫做BA问题 简单好记 主要用于SLAM 在给定一组实测图像特征位置及其对应关系的情况下 进行束调整的目标是找到使重投影误差最小的三维点位置和相机参数。该优化问题通常表示为非线性最小二乘问题 其误差为观测到的特征位置与对应的三维点在相机成像平面上投影之差的L2平方模。

模板针孔相机模型。相机使用9个参数进行参数化:3个参数用于旋转 3个参数用于平移 1个参数用于焦距 2个参数用于径向畸变。主点没有建模(即假设位于图像中心)。

关于相机模型的知识点请自行学习回顾。

#include cstdio #include iostream #include ceres/ceres.h #include ceres/rotation.h

本文链接: http://ceres.immuno-online.com/view-709505.html

发布于 : 2021-03-24 阅读(0)