当前位置: 首页 > news >正文

SLAM 基于C++优化库Ceres的曲线拟合

这个程序使用C++开源优化库Ceres拟合一个较为复杂的非线性函数。

真实的函数模型是:

代码里给的真实值a=1,b=2,c=1,

把abc代入函数模型得到具体的模型:

f(x)加入随机噪声后生成了散点图.

下面的图片同时绘制了真实曲线和散点图。

程序会根据散点图的数据拟合出a,b,c.

这是绘制出来的拟合曲线:

这是程序输出的优化报告:

从这个优化报告的第三列cost_change可以看出来,第7次迭代cost的变化量是0.00011,已经满足Ceres预设的精度要求了,就终止迭代了。

下面是优化结果的列表对比:

代码:

#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 ar = 1.0, br = 2.0, cr = 1.0; // 真实参数值 double ae = 2.0, be = -1.0, ce = 5.0; // 估计参数值 int N = 100; // 数据点 double w_sigma = 1.0; // 噪声Sigma值 double inv_sigma = 1.0 / w_sigma; cv::RNG rng; // OpenCV随机数产生器 vector<double> x_data, y_data; // 数据 for (int i = 0; i < N; i++) { double x = i / 100.0; x_data.push_back(x); y_data.push_back(exp(ar * x * x + br * x + cr) + rng.gaussian(w_sigma * w_sigma)); } double abc[3] = {ae, be, ce}; // 构建最小二乘问题 ceres::Problem problem; for (int i = 0; i < N; 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_NORMAL_CHOLESKY; // 增量方程如何求解 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; }

参考:高翔《视觉SLAM十四讲》

http://www.jsqmd.com/news/1186258/

相关文章:

  • 2026年高精达代理日本Nakanishi E3000系列电动高速主轴 正规采购渠道盘点 - 资讯报道
  • 2026泰兴暴雨多发!楼顶阳光房阳台窗边漏水如何彻底解决? - 宅安选房屋修缮
  • AI代理进程隔离架构:突破上下文窗口限制的工程实践
  • Flutter---CustomScrollView的UI项目(2)
  • Cesium OGC- tms服务教程
  • 2026 东莞黄金上门回收 全城当天上门 - 奢侈品回收评测
  • ZeroTermux:Android设备上的终极Linux终端环境解决方案
  • 2026年7月最新济南雷达官方售后联系电话与客户服务中心网点地址 - 亨得利钟表维修中心
  • hot100 岛屿数量(200)
  • RedisFullCheck 企业级部署:大规模 Redis 环境数据一致性监控方案
  • 设计工具大集合:gh_mirrors/we/web-dev-resources助你打造专业UI界面 [特殊字符]
  • 如何快速上手PaintingLight:10分钟安装与基础使用教程
  • 亿企代账口碑怎么样?看亿企赢合作机构怎么说 - 热点速览
  • 滑动窗口算法解析:无重复字符最长子串的优化实现
  • Unity URP屏幕空间描边实战:7大技巧实现高性能卡通渲染
  • 专业级Godot RPG游戏开发:从零构建回合制战斗系统的完整指南
  • 2026最新版Skyline Console功能盘点:支持多语言与自定义主题的现代仪表盘
  • CuckooSQL架构解密:Apache Arrow+LLVM如何打造极速SQL引擎
  • tech.ml.dataset实战:5个真实场景展示如何高效处理百万级数据
  • 2026吉州黄金变现指南:认准这几家“大盘价”回收店,无折旧无套路,当场到账! - 铂衡汇黄金珠宝
  • Clawdbot本地化AI Agent架构解析与实践指南
  • AI 模型成本战:企业账单从月费百万到精打细算的生存指南
  • 扩散模型PyTorch实战:从DDPM原理到图像生成完整指南
  • 劳力士官方直营售后维修网点|官方网站权威公布(2026年7月最新) - 劳力士官方维修中心
  • 深入解析llama-nv-embed-reasoning-3b架构:双向注意力机制如何提升推理能力
  • 2026 上海围挡租赁围挡销售商家测评,市政工地围挡租售机构深度实测 - LYL仔仔
  • Xel常见问题解答:解决原生Web应用开发中的30个典型问题
  • 2026年河北边坡防护网厂家挑选攻略 旭涛边坡等优质企业盘点 - 资讯报道
  • 预测型AI偏见审计:从数据到决策的全流程公平性保障
  • YOLOv8道路坑洼检测实战:从数据标注到工程部署完整指南