首页 > 其他分享 >【学习随笔】2022.9.20 Ceres

【学习随笔】2022.9.20 Ceres

时间:2022-09-20 16:23:24浏览次数:90  
标签:ceres 20 abc chrono double Ceres 2022.9 1.0 data

代码来源为 SLAM 14讲 ch6 

 1 #include <iostream>
 2 #include <opencv2/core/core.hpp>
 3 #include <ceres/ceres.h>
 4 #include <chrono>
 5 
 6 using namespace std;
 7 
 8 // STEP1.代价函数的计算模型 此处为 Functor 具体概念可见底端链接
 9 struct CURVE_FITTING_COST {
10   CURVE_FITTING_COST(double x, double y) : _x(x), _y(y) {}
11 
12   // 残差的计算
13   template<typename T>
14   bool operator()(
15     const T *const abc, // 模型参数,有3维
16     T *residual) const {
17     residual[0] = T(_y) - ceres::exp(abc[0] * T(_x) * T(_x) + abc[1] * T(_x) + abc[2]); // y-exp(ax^2+bx+c)
18     return true;
19   }
20 
21   const double _x, _y;    // x,y数据
22 };
23 
24 int main(int argc, char **argv) {
25   double ar = 1.0, br = 2.0, cr = 1.0;         // 真实参数值
26   double ae = 2.0, be = -1.0, ce = 5.0;        // 估计参数值
27   int N = 100;                                 // 数据点
28   double w_sigma = 1.0;                        // 噪声Sigma值
29   double inv_sigma = 1.0 / w_sigma;
30   cv::RNG rng;                                 // OpenCV随机数产生器
31 
32   vector<double> x_data, y_data;      // 生成具有噪声的数据
33   for (int i = 0; i < N; i++) {
34     double x = i / 100.0;
35     x_data.push_back(x);
36     y_data.push_back(exp(ar * x * x + br * x + cr) + rng.gaussian(w_sigma * w_sigma));
37   }
38 
39   double abc[3] = {ae, be, ce};
40 
41   // STEP2.构建最小二乘问题
42   ceres::Problem problem;
43   for (int i = 0; i < N; i++) {
44     problem.AddResidualBlock(     // 向问题中添加误差项
45       // 使用自动求导,模板参数:①误差类型②输出维度[residual]③输入维度[参数块abc] 最多支持10个独立变量,维数要与前面struct中一致
46       new ceres::AutoDiffCostFunction<CURVE_FITTING_COST, 1, 3>(
47         new CURVE_FITTING_COST(x_data[i], y_data[i])
48       ),
49       nullptr,            // 核函数,这里不使用,为空
50       abc                 // 待估计参数
51     );
52   }
53 
54   // STEP3.配置求解器
55   ceres::Solver::Options options;     // 这里有很多配置项可以填
56   options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;  // 增量方程如何求解
57   options.minimizer_progress_to_stdout = true;   // 输出到cout
58 
59   ceres::Solver::Summary summary;                // 优化信息
60   chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
61   ceres::Solve(options, &problem, &summary);  // 开始优化
62   chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
63   chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2 - t1);
64   cout << "solve time cost = " << time_used.count() << " seconds. " << endl;
65 
66   // 输出结果
67   cout << summary.BriefReport() << endl;
68   cout << "estimated a,b,c = ";
69   for (auto a:abc) cout << a << " ";
70   cout << endl;
71 
72   return 0;
73 }

 


 

# 相关参考链接

关于ceres官方文档笔记参考 -> [Ceres Solver 官方教程学习笔记(十一)——非线性最小二乘法建模Modeling Non-linear Least Squares (上)_小政哥的博客-CSDN博客_ceres solver]

关于仿函数的理解参考 -> [https://www.cnblogs.com/decade-dnbc66/p/5347088.html]

关于explicit关键字参考 -> [https://www.cnblogs.com/rednodel/p/9299251.html]

 

标签:ceres,20,abc,chrono,double,Ceres,2022.9,1.0,data
From: https://www.cnblogs.com/isaac0617/p/16710962.html

相关文章