Ceres Solver 非线性优化库

  • 1. Ceres Solver
  • 2. 下载安装
  • 3. 简易例程
  • 4. 环境运行
  • 5. 非线性拟合

1. Ceres Solver

Ceres solver 是谷歌开发的一款用于非线性优化的库
在 谷歌的开源激光雷达SLAM项目Cartographer 中被大量使用

使用Ceres求解非线性优化问题,一共分为四个部分:

  1. 构建 代价函数cost fuction,也就是寻优的目标式
  2. 通过代价函数构建 待求解的优化问题
  3. 配置求解器参数
  4. 求解问题

Ceres主要用于求解无约束或者有界约束的最小二乘问题
这个概念可以用以下表达式表示:

任务就是找到一组满足约束 lllj≤x≤x≤xj≤u≤u≤uj的xxx1,⋯,xxxk, 使得优化目标函数取值最小

  • xxx1,⋯,xxxk 优化参数,被称为参数块,它们的取值就是寻找的解
  • lllj,uuuj 第jjj个优化参数xxxj的下界和上界
  • ρρρi(∥f(∥f(∥fi (x(x(x1,⋯,xxxk)∥)∥)∥2))) 残差项,其中fffi(⋅)(⋅)(⋅)是代价函数,ρρρi(⋅)(⋅)(⋅)则是关于代价函数平方的核函数
    核函数存在的意义主要是为了降低野点对于解的影响

2. 下载安装

使用以下命令安装依赖

sudo apt-get install cmake libgoogle-glog-dev libgflags-dev libatlas-base-dev libeigen3-dev libsuitesparse-dev

下载源码,推荐用国内源

git clone https://gitcode.net/mirrors/ceres-solver/ceres-solver.git

开始编译

mkdir ceres-bin
cd ceres-bin/
cmake ../ceres-solver
make -j3
sudo make install

测试一下

bin/simple_bundle_adjuster ../ceres-solver-2.0.0/data/problem-16-22106-pre.txt


3. 简易例程

Ceres官网教程给出的例程中,求解的问题是求xxx使得 12\frac{1}{2}21​ ∗(10−x)* (10−x)∗(10−x)2 取到最小值

代码如下:

#include <iostream>
#include <ceres/ceres.h>using namespace std;
using namespace ceres;/* 第一步:构建代价函数,利用仿函数对()进行重载 */
struct CostFunctor
{template <typename T>bool operator()(const T *const x, T *residual) const{residual[0] = T(10.0) - x[0];return true;}
};/* 主函数 */
int main(int argc, char **argv)
{google::InitGoogleLogging(argv[0]);/* 寻优参数x的初始值,为5.0 */double initial_x = 5.0;double x = initial_x;/* 第二步:构建寻优问题 */Problem problem;/* 使用自动求导,将之前的代价函数结构体传入,第一个1是输出维度,即残差的维度,第二个1是输入维度,即待寻优参数x的维度。 */CostFunction *cost_function = new AutoDiffCostFunction<CostFunctor, 1, 1>(new CostFunctor);/* 向问题中添加误差项,本问题比较简单,添加一个就行。 */problem.AddResidualBlock(cost_function, NULL, &x);/* 第三步:配置求解器 */Solver::Options options;options.linear_solver_type = ceres::DENSE_QR; /* 配置增量方程的解法 */options.minimizer_progress_to_stdout = true;  /* 配置输出到cout */Solver::Summary summary;                      /* 定义优化信息 *//* 第四步:运行求解器 */Solve(options, &problem, &summary);/* 输出优化的简要信息 */std::cout << summary.BriefReport() << "\n";/* 输出最终的结果信息 */std::cout << "x : " << initial_x << " -> " << x << "\n";return 0;
}

4. 环境运行

在与源码和编译文件夹同级路径再新增测试文件夹ceres-examples

$ mkdir ceres-examples
$ ls
# ceres-bin  ceres-examples  ceres-solver
$ cd ceres-examples

文件以example.cpp为例,新建文件复制上述代码

再新建CMakeLists.txt文件

cmake_minimum_required(VERSION 2.8)
project(ceres-examples)find_package(Ceres REQUIRED)
include_directories(${CERES_INCLUDE_DIRS})add_executable(example example.cpp)
target_link_libraries(example ${CERES_LIBRARIES})

然后编译并执行文件

$ cmake ../ceres-examples/
$ make
$ ./example


最终解为10使得 12\frac{1}{2}21​ ∗(10−x)* (10−x)∗(10−x)2 取到最小值


5. 非线性拟合

拟合非线性函数的曲线: y=ey=ey=e3x2+2x+1

#include <iostream>
#include <ceres/ceres.h>
#include <time.h> using namespace std;
using namespace ceres;/* 构建代价函数结构体,abc为待优化参数,residual为残差。*/
struct CostFunctor
{CostFunctor(double x, double y) : _x(x), _y(y) {}template <typename T>bool operator()(const T *const abc, T *residual) const{residual[0] = _y - exp(abc[0] * _x * _x + abc[1] * _x + abc[2]);return true;}const double _x, _y;
};/* 主函数 */
int main()
{/* 参数初始化设置,abc初始化为0,噪声 */double a = 3, b = 2, c = 1;double abc[3] = {0, 0, 0};/* 设置rand()产生随机数时的随机数种子 */srand((int)time(0));/* 生成待拟合曲线的数据散点 */vector<double> x_data, y_data;for (int i = 0; i < 1000; i++){double x = i / 1000.0;x_data.push_back(x);y_data.push_back(exp(a * x * x + b * x + c) + (rand() % 11 - 5) / 10.0);}/* 第二步:构建寻优问题 */Problem problem;/* 遍历所有数据点,添加AddResidualBlock */for (int i = 0; i < 1000; i++){problem.AddResidualBlock(new AutoDiffCostFunction<CostFunctor, 1, 3>(new CostFunctor(x_data[i], y_data[i])),nullptr, /* 不使用核函数 */abc);    /* 待优化参数 */}/* 第三步:配置求解器 */Solver::Options options;options.linear_solver_type = DENSE_QR;options.minimizer_progress_to_stdout = true;Solver::Summary summary;/* 第四步:运行求解器 */Solve(options, &problem, &summary);/* 输出最终的结果信息 */cout << "a= " << abc[0] << endl;cout << "b= " << abc[1] << endl;cout << "c= " << abc[2] << endl;return 0;
}

参考上节编辑文件和编译,执行效果如下:


求出来和原始参数很接近


谢谢!

Ceres Solver 非线性优化库相关推荐

  1. Ceres Solver: 高效的非线性优化库(二)实战篇

    Ceres Solver: 高效的非线性优化库(二)实战篇 接上篇: Ceres Solver: 高效的非线性优化库(一) 如何求导 Ceres Solver提供了一种自动求导的方案,上一篇我们已经看 ...

  2. 非线性优化库Ceres问题记录

    项目场景: 非线性优化库Ceres中的log_severity.h文件中提示: #error : ERROR macro is defined. Define GLOG_NO_ABBREVIATED_ ...

  3. 在windows系统中使用Ceres非线性优化库:(一)安装Ceres库

    (一)安装Ceres库                         1.用vcpkg安装Ceres库                 1.1.安装vcpkg 1.2.安装Ceres 1.3.配置C ...

  4. 非线性优化库Ceres学习笔记7(鲁棒的曲线拟合)

    现在假设给定的数据有一些异常值,即我们有一些不服从噪声模型的点.如果我们使用上面的代码来拟合这些数据,我们将得到如下所示的拟合. 在这个时候需要应用损失函数(Loss function)来对异常数据进 ...

  5. Ceres Solver:Terminating: Residual and Jacobian evaluation failed

    文章目录 前言 一.Ceres-Solver 二.解决方法 总结 前言 使用ceres-solver库求解非线性优化问题时,打印summary.message时出现报错: [trust_region_ ...

  6. Ceres非线性优库入门介绍

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 一.背景知识 Ceres是一款非线性优化库,广泛的应用于SLAM问题中的BA问题等求解,但并不局限于S ...

  7. Ceres Solver从零开始手把手教学使用

    目录 一 .简介 二.安装 三.介绍 四.Hello Word! 五.导数 1 数值导数 2解析求导 六.实践 Powell函数 一 .简介 笔者已经半年没有更新新的内容了,最近学习视觉SLAM的过程 ...

  8. 【环境配置】ceres solver安装

    1. 安装 github地址 # CMake sudo apt-get install cmake # google-glog + gflags sudo apt-get install libgoo ...

  9. Ceres Solver Document学习笔记

    Ceres Solver Document学习笔记 Ceres Solver Document学习笔记 1. 基本概念 2. 基本方法 2.1 CostFunction 2.2 AutoDiffCos ...

最新文章

  1. JiBX1.2 处理XML
  2. 苹果手机(ios)拍照上传图片旋转90度问题---java后台处理
  3. 将本地SHH文件导入SourceTree配置
  4. ASP.NET EntityFrameworkCore code first 多对多设计
  5. 使用Java调用以WSDL形式发布的web service
  6. 计算机基础知识二进步,大学计算机基础学习知识练习进步题(含规范标准答案).doc...
  7. CSS+jQuery/JavaScript图片切换播放
  8. 安卓seekbar 怎么判断正负_厦门湖里区佳丽花园马桶掉东西了疏通下水怎么收费...
  9. Django之templates模板
  10. python threading 两种创建方式
  11. 毕设日志——RCNN
  12. SAP License:供应链管理和ERP的关系?
  13. 注意了,这些数值计算的坑千万别踩!
  14. C++读写ini配置文件
  15. MulT: An End-to-End Multitask Learning Transformer 多任务共享注意力
  16. 工作多少年,在哪个行业,可以拿到年薪50万+
  17. DFS/BFS+思维 HDOJ 5325 Crazy Bobo
  18. MySQL本天早上8点到明早8点_早上8点是什么时辰
  19. 从语言之争到年龄焦虑
  20. 霹雳吧啦Wz语义分割学习笔记P3

热门文章

  1. @dynamic 模拟NSManagedObject类的内部实现,AFN的非常规用法
  2. 截取含HTML标签的字符串
  3. HR谈网络工程师求职与职业规划
  4. jvm学习笔记(1)——java虚拟机内存区域
  5. pytorch学习笔记(4):tensorboard可视化
  6. 如何在没有数组和string字符串的条件下输入时间(去时间的分号)
  7. ie自动获取无效_经常用浏览器自动登录忘记了密码?教你一键查看网页星号密码...
  8. 正则表达式JavaScript版本回顾笔记背诵版本
  9. nginx配置多个站点的方法
  10. perl中替换文本一例