Ceres-Solver
欢迎访问我的博客首页。
Ceres-Solver
- 1. 安装 Ceres-Solver
- 2. 求解 ICP
- 3. 参考
1. 安装 Ceres-Solver
安装 Ceres-Solver 有点麻烦,因为它的依赖较多。按照顺序依次安装下面的库,选中 BUILD_SHARED_LIBS:
- gflags。
- gtest。
- glog。依赖 gflags 和 gtest。
- lapack。会安装 lapack 和 blas。出现 multiple definition of `_gfortran_concat_string’ 错误时,参考它的 issues/305。
- suitesparse。该安装包中有一个编译好了的 lapack_windows 文件夹。先点击 cmake-gui 的 configure,出现 LAPACK_DIR,然后把这个目录设置为上面我们自己编译的 lapack,最后删除 lapack_windows 文件夹。会同时安装 amd、btf、camd、ccolamd、colamd、cholmod、cxsparse、klu、ldl、umfpack、spqr、suitesparseconfig。INCLUDE 目录选这些库的 .h 文件所在目录,库文件选择它们的 .a 文件。编译时不要选择 METIS,否则需要先安装 GKlib。
- Eigen。在官网下载或从官网去 gitlab 都可以下载。
- ceres-solver。按照需要设置上面的依赖路径。
2. 求解 ICP
Ceres-Solver 有三种求导方式,这里使用最简单的自动求导。本文的例子参照 A-LOAM。使用 ceres-solver 求解位姿时,旋转矩阵用四元数 Eigen::Quaternion 表示,平移向量用矩阵 Eigen::Matrix 表示。
- 定义代价函数类。代价函数类的类名是随意的,但它必须有一个 模板类型 的 括号运算符 重载函数。
class Function {public:Function(Eigen::Vector3d _point_a, Eigen::Vector3d _point_b) {point_a = _point_a;point_b = _point_b;}template<typename T>bool operator()(const T* para_q, const T* para_t, T* residual) const {Eigen::Matrix<T, 3, 1> matrix_a{ T(point_a.x()), T(point_a.y()) ,T(point_a.z()) };Eigen::Matrix<T, 3, 1> matrix_b{ T(point_b.x()), T(point_b.y()) ,T(point_b.z()) };Eigen::Quaternion<T> rotation{ para_q[3],para_q[0], para_q[1], para_q[2] };Eigen::Matrix<T, 3, 1> translation{ para_t[0],para_t[1],para_t[2] };Eigen::Matrix<T, 3, 1> temp = rotation * matrix_a + translation;residual[0] = temp[0] - matrix_b[0];residual[1] = temp[1] - matrix_b[1];residual[2] = temp[2] - matrix_b[2];return true;}private:Eigen::Vector3d point_a;Eigen::Vector3d point_b;
};
可以看出,该代价函数类的构造函数接收一个观测值 point_a 和一个实际值 point_b。重载函数的参数分布是旋转矩阵、平移向量、误差。在重载函数体内,利用观测值 point_a、旋转矩阵、平移向量得到测量值 temp,然后把测量值与实际值的误差赋值给重载函数的第三个参数。
- 创建 ceres 代价函数对象。
ceres::CostFunction* create(Eigen::Vector3d point_a, Eigen::Vector3d point_b) {Function* function = new Function(point_a, point_b);return new ceres::AutoDiffCostFunction<Function, 3, 4, 3>(function);
}
首先使用 new 操作符创建一个我们刚才定义的代价函数类的对象。这是一个函数对象,因为它定义了调用运算符。然后用指针作为参数创建 ceres::AutoDiffCostFunction 对象。注意此时的 4 个模板参数:
- Function:我们刚才定义的代价函数类的类名。
- 第一个 3:Function 类的重载操作符函数的最后一个参数的维度,即,误差的维度。因为我们在 Function 类的重载函数体的最后部分计算的误差有三个维度,所以这个模板参数须是 3。
- 4:Function 类的重载操作符函数的第一个参数的维度。
- 第二个 3:Function 类的重载操作符函数的第二个参数的维度。
- 使用 ceres 进行非线性优化:
#include <iostream>
#include <cmath>
#include <iomanip>
#include <Eigen/Core>
#include <Eigen/Eigen>
#include <Eigen/Geometry>
#include <ceres/ceres.h>
using namespace std;int main() {cout << setiosflags(ios::fixed) << setiosflags(ios::right) << setprecision(2);// 1.待优化的参数。double para_q[4] = { 0,0,0,1 };double para_t[3] = { 0,0,0 };// 2.定义问题及损失函数。ceres::Problem::Options problem_options;ceres::Problem problem(problem_options);ceres::LossFunction* loss_function = new ceres::HuberLoss(0.1);// 3.添加优化对象。ceres::LocalParameterization* q_parameterization = new ceres::EigenQuaternionParameterization();problem.AddParameterBlock(para_q, 4, q_parameterization);problem.AddParameterBlock(para_t, 3);// 4.添加观测对象及代价函数。vector<Eigen::Vector3d> points_a = { {-4,2,1},{1,2,3},{1,3,2},{2,1,1},{-1,4,2},{7,0,3} };vector<Eigen::Vector3d> points_b = { {2,3,1},{2,-2,3},{3,-2,2},{1,-3,1},{4,0,2},{0,-8,3} };for (size_t i = 0; i < points_a.size(); i++) {ceres::CostFunction* cost_function = create(points_a[i], points_b[i]);problem.AddResidualBlock(cost_function, loss_function, para_q, para_t);}// 5.设置参数并求解。ceres::Solver::Options options;options.linear_solver_type = ceres::DENSE_QR;options.max_num_iterations = 10;options.minimizer_progress_to_stdout = false;ceres::Solver::Summary summary;ceres::Solve(options, &problem, &summary);cout << summary.BriefReport() << endl;cout << para_q[0] << " " << para_q[1] << " " << para_q[2] << " " << para_q[3] << endl;cout << para_t[0] << " " << para_t[1] << " " << para_t[2] << endl;
}
3. 参考
- Ceres-Solver 下载,github。
- Ceres-Solver 安装,CSDN。
- Ceres-Solver 编译错误 “(”:“::”右边的非法标记,CSDN。
- Ceres-Solver 求导,博客园。
Ceres-Solver相关推荐
- Ceres Solver Document学习笔记
Ceres Solver Document学习笔记 Ceres Solver Document学习笔记 1. 基本概念 2. 基本方法 2.1 CostFunction 2.2 AutoDiffCos ...
- Ceres Solver 非线性优化库
Ceres Solver 非线性优化库 1. Ceres Solver 2. 下载安装 3. 简易例程 4. 环境运行 5. 非线性拟合 1. Ceres Solver Ceres solver 是谷 ...
- Ceres Solver安装
先是ceres solver的依赖安装 # CMake sudo apt-get install cmake # google-glog + gflags sudo apt-get install l ...
- Ceres Solver: 高效的非线性优化库(二)实战篇
Ceres Solver: 高效的非线性优化库(二)实战篇 接上篇: Ceres Solver: 高效的非线性优化库(一) 如何求导 Ceres Solver提供了一种自动求导的方案,上一篇我们已经看 ...
- Ceres Solver从零开始手把手教学使用
目录 一 .简介 二.安装 三.介绍 四.Hello Word! 五.导数 1 数值导数 2解析求导 六.实践 Powell函数 一 .简介 笔者已经半年没有更新新的内容了,最近学习视觉SLAM的过程 ...
- 【环境配置】ceres solver安装
1. 安装 github地址 # CMake sudo apt-get install cmake # google-glog + gflags sudo apt-get install libgoo ...
- Ceres Solver安装及bug解决
Ceres Solver安装与入门使用 安装教程:http://www.ceres-solver.org/installation.html 点击下载最新的稳定版 解压.编译 .测试.安装 1.Lin ...
- Ceres Solver:Terminating: Residual and Jacobian evaluation failed
文章目录 前言 一.Ceres-Solver 二.解决方法 总结 前言 使用ceres-solver库求解非线性优化问题时,打印summary.message时出现报错: [trust_region_ ...
- Ceres Solver 官方教程学习笔记(十二)——非线性最小二乘法建模Modeling Non-linear Least Squares (下)
这一部分主要是最后的Problem比较重要. 带条件的代价函数ConditionedCostFunction 这个类使用户可以在使用封装好的代价函数的同时,对残差值加入一定的条件限制.举个例子,现在已 ...
- Ceres solver安装与测试
官方安装教程 点击下载最新的稳定版 解压.编译 .测试.安装 tar zxf ceres-solver-2.1.0.tar.gz mkdir ceres-bin cd ceres-bin cmake ...
最新文章
- Ascend Pytorch算子功能验证
- L2-002. 链表去重
- .NET业务实体类验证组件Fluent Validation
- 简单几步解决企业USB端口隐患
- 关于update set from where
- Qt/E中的键盘设备管理
- php实现tail,Linux-如何用php实现Linux下的tail -f命令?
- 【Python-pywt】 小波变化库—Pywavelets 学习笔记
- 图解:SQL Server SSIS包和job的部署攻略
- 抛弃鼠标的神器——Vimium
- [LUOGU] P2024 食物链
- .NET中Redis安装部署及使用方法简介附-开源Redis操作辅助类
- Java第十次作业 1502 马 帅
- Java 找到并返回一组字符串中第一个不为空的字符串
- MATLAB工具箱下载地址
- html5 密码强度,前端开发判断输入密码强度
- Fortran 95简单教程(二)
- VM虚拟机安装及安装Windows系统
- eclipse osgi_Eclipse通过提议的OSGi容器Kura支持M2M产品组合
- 伯乐发卡网系统修复版源码
热门文章
- lg-1 x 怎么算_【言情】魔鬼的体温 by 藤萝为枝 敏感自卑男主x治愈天使女主 我凭美食成为国家宝藏by 十尾兔...
- Android开发学习之路III-服务器技术篇
- 嵌入式论坛展示微控制器、工具、软件、物联网、连接性、安全性
- java文件一行一行读取_Java代码中如何一行一行的读取文本文件呢?
- spark报错:java.io.IOException: Filesystem closed
- connection closed
- chr python用法_使用Python内建chr, ord实现的简单的加/解密
- python写整数逆位运算_整数逆位运算
- c++画蛋糕_生日蛋糕--C++
- 是什么让物联网放慢脚步?