视觉十四讲:第六讲_ceres非线性优化
使用Ceres求解非线性优化问题,一共分为三个部分:
1、 第一部分:构建cost fuction,即代价函数,也就是寻优的目标式。这个部分需要使用仿函数(functor)这一技巧来实现,做法是定义一个cost function的结构体,在结构体内重载()运算符。
2、 第二部分:通过代价函数构建待求解的优化问题。
3、 第三部分:配置求解器参数并求解问题,这个步骤就是设置方程怎么求解、求解过程是否输出等,然后调用一下Solve方法
#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.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;
}
cmakelists.txt:
cmake_minimum_required(VERSION 2.8)
project(gaussnewton)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
find_package(Ceres REQUIRED)
include_directories(${CERES_INCLUDE_DIRS})
include_directories("/usr/include/eigen3")
set(SOURCE_FILES main.cpp)
add_executable(gaussnewton ${SOURCE_FILES})
target_link_libraries(gaussnewton ${OpenCV_LIBS})
target_link_libraries(gaussnewton ${CERES_LIBRARIES})
视觉十四讲:第六讲_ceres非线性优化的更多相关文章
- ros系统21讲—前六讲
课程介绍(第一讲) linux介绍安装(第二讲) linux的基础操作(第三讲) ROS中语言c++与python介绍(第四讲) 安装ROS系统(第五讲) 第一个: sudo sh -c echo d ...
- 高翔《视觉SLAM十四讲》从理论到实践
目录 第1讲 前言:本书讲什么:如何使用本书: 第2讲 初始SLAM:引子-小萝卜的例子:经典视觉SLAM框架:SLAM问题的数学表述:实践-编程基础: 第3讲 三维空间刚体运动 旋转矩阵:实践-Ei ...
- 视觉slam学习之路(一)看高翔十四讲所遇到的问题
目前实验室做机器人,主要分三个方向,定位导航,建图,图像识别,之前做的也是做了下Qt上位机,后面又弄红外识别,因为这学期上课也没怎么花时间在项目,然后导师让我们确定一个方向来,便于以后发论文什么. ...
- 浅读《视觉SLAM十四讲:从理论到实践》--操作1--初识SLAM
下载<视觉SLAM十四讲:从理论到实践>源码:https://github.com/gaoxiang12/slambook 第二讲:初识SLAM 2.4.2 Hello SLAM(书本P2 ...
- 第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理
第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字 ...
- 高博-《视觉SLAM十四讲》
0 讲座 (1)SLAM定义 对比雷达传感器和视觉传感器的优缺点(主要介绍视觉SLAM) 单目:不知道尺度信息 双目:知道尺度信息,但测量范围根据预定的基线相关 RGBD:知道深度信息,但是深度信息对 ...
- 《视觉SLAM十四讲》第2讲
目录 一 视觉SLAM中的传感器 二 经典视觉SLAM框架 三 SLAM问题的数学表述 注:原创不易,转载请务必注明原作者和出处,感谢支持! 本讲主要内容: (1) 视觉SLAM中的传感器 (2) 经 ...
- 《视觉SLAM十四讲》第1讲
目录 一 视觉SLAM 注:原创不易,转载请务必注明原作者和出处,感谢支持! 一 视觉SLAM 什么是视觉SLAM? SLAM是Simultaneous Localization and Mappin ...
- 视觉slam十四讲第七章课后习题6
版权声明:本文为博主原创文章,转载请注明出处: http://www.cnblogs.com/newneul/p/8545450.html 6.在PnP优化中,将第一个相机的观测也考虑进来,程序应如何 ...
- 视觉slam十四讲第七章课后习题7
版权声明:本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/newneul/p/8544369.html 7.题目要求:在ICP程序中,将空间点也作为优化变量考虑进来 ...
随机推荐
- Go语言核心36讲38
到目前为止,我们已经一起陆陆续续地学完了Go语言中那些最重要也最有特色的概念.语法和编程方式.我对于它们非常喜爱,简直可以用如数家珍来形容了. 在开始今天的内容之前,我先来做一个简单的总结. Go语言 ...
- KubeEdge快速上手与社区贡献实践
1.KubeEdge的架构特点与优势 持久化 云端组件,EdgeController,设备抽象API,CSI Driver,Admission WebHook 边缘组件,EdgeHub,MetaMan ...
- 【转载】【Word】项目编号应用样式后出现黑框的解决方案
本文中的宏代码来自: https://www.zhihu.com/question/38985919 Word使用项目编号后,出现黑框,如下图所示: 网上大多数解决方案在重新打开文档后,依然还是有黑框 ...
- CH32V307以太网(芯片内部10M)-针对新固件的Lib库
沁恒的CH32V307网络库在前段时间做了一个更新,相对于以前的Lib,主要的功能没有什么特别大的变化,但是底层的一些操作仔细看的话,还是不少的区别的. 首先,官方提供的例程,工程结构以及头文件优一些 ...
- 实现简单的csv文件上传和bootstrap表格的下载
一.写一个简单的页面并发送文件 引入bootstrap.js,jQuery.js等,具体的网页就不细写了,很简单. 加入input框,button控件,进度条.如下: <li class=&qu ...
- 痞子衡嵌入式:MCUBootUtility v4.0发布,开始支持MCX啦
-- 痞子衡维护的 NXP-MCUBootUtility 工具距离上一个大版本(v3.5.0)发布过去 9 个月了,这一次痞子衡为大家带来了版本升级 v4.0.0,这个版本主要有两个重要更新需要跟大家 ...
- ffmpeg常用操作
音频常用操作 常见的ffmpeg音频参数 常用参数解释: - i 表示input,即输入文件 - f 表示format,即输出格式 - vn 表示vedio not,即输出不包含视频 - ar 设定采 ...
- python31 网络并发编程方法
同步与异步 用来表达任务的提交方式 同步 提交完任务之后原地等待任务的返回结果 期间不做任何事 异步 提交完任务之后不原地等待任务的返回结果 直接去做其他事 有结果自动通知 阻塞与非阻塞 用来表达任务 ...
- C组合方案
递归实现组合型枚举 从 1∼n 这 n 个整数中随机选出 m 个,输出所有可能的选择方案. 输入格式 两个整数 n,m ,在同一行用空格隔开. 输出格式 按照从小到大的顺序输出所有方案,每行 1 个. ...
- 10分钟做好 Bootstrap Blazor 的表格组件导出 Excel/Word/Html/Pdf
上篇: Bootstrap Blazor 实战 通用导入导出服务(Table组件) 1.新建工程 新建工程b14table dotnet new blazorserver -o b14table 将项 ...