欢迎访问我的博客首页。


Ceres-Solver

  • 1. 安装 Ceres-Solver
  • 2. 求解 ICP
  • 3. 参考

1. 安装 Ceres-Solver


  安装 Ceres-Solver 有点麻烦,因为它的依赖较多。按照顺序依次安装下面的库,选中 BUILD_SHARED_LIBS:

  1. gflags。
  2. gtest。
  3. glog。依赖 gflags 和 gtest。
  4. lapack。会安装 lapack 和 blas。出现 multiple definition of `_gfortran_concat_string’ 错误时,参考它的 issues/305。
  5. 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。
  6. Eigen。在官网下载或从官网去 gitlab 都可以下载。
  7. ceres-solver。按照需要设置上面的依赖路径。

2. 求解 ICP


  Ceres-Solver 有三种求导方式,这里使用最简单的自动求导。本文的例子参照 A-LOAM。使用 ceres-solver 求解位姿时,旋转矩阵用四元数 Eigen::Quaternion 表示,平移向量用矩阵 Eigen::Matrix 表示。

  1. 定义代价函数类。代价函数类的类名是随意的,但它必须有一个 模板类型括号运算符 重载函数。
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,然后把测量值与实际值的误差赋值给重载函数的第三个参数。

  1. 创建 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 类的重载操作符函数的第二个参数的维度。
  1. 使用 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. 参考


  1. Ceres-Solver 下载,github。
  2. Ceres-Solver 安装,CSDN。
  3. Ceres-Solver 编译错误 “(”:“::”右边的非法标记,CSDN。
  4. Ceres-Solver 求导,博客园。

Ceres-Solver相关推荐

  1. Ceres Solver Document学习笔记

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

  2. Ceres Solver 非线性优化库

    Ceres Solver 非线性优化库 1. Ceres Solver 2. 下载安装 3. 简易例程 4. 环境运行 5. 非线性拟合 1. Ceres Solver Ceres solver 是谷 ...

  3. Ceres Solver安装

    先是ceres solver的依赖安装 # CMake sudo apt-get install cmake # google-glog + gflags sudo apt-get install l ...

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

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

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

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

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

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

  7. Ceres Solver安装及bug解决

    Ceres Solver安装与入门使用 安装教程:http://www.ceres-solver.org/installation.html 点击下载最新的稳定版 解压.编译 .测试.安装 1.Lin ...

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

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

  9. Ceres Solver 官方教程学习笔记(十二)——非线性最小二乘法建模Modeling Non-linear Least Squares (下)

    这一部分主要是最后的Problem比较重要. 带条件的代价函数ConditionedCostFunction 这个类使用户可以在使用封装好的代价函数的同时,对残差值加入一定的条件限制.举个例子,现在已 ...

  10. Ceres solver安装与测试

    官方安装教程 点击下载最新的稳定版 解压.编译 .测试.安装 tar zxf ceres-solver-2.1.0.tar.gz mkdir ceres-bin cd ceres-bin cmake ...

最新文章

  1. Ascend Pytorch算子功能验证
  2. L2-002. 链表去重
  3. .NET业务实体类验证组件Fluent Validation
  4. 简单几步解决企业USB端口隐患
  5. 关于update set from where
  6. Qt/E中的键盘设备管理
  7. php实现tail,Linux-如何用php实现Linux下的tail -f命令?
  8. 【Python-pywt】 小波变化库—Pywavelets 学习笔记
  9. 图解:SQL Server SSIS包和job的部署攻略
  10. 抛弃鼠标的神器——Vimium
  11. [LUOGU] P2024 食物链
  12. .NET中Redis安装部署及使用方法简介附-开源Redis操作辅助类
  13. Java第十次作业 1502 马 帅
  14. Java 找到并返回一组字符串中第一个不为空的字符串
  15. MATLAB工具箱下载地址
  16. html5 密码强度,前端开发判断输入密码强度
  17. Fortran 95简单教程(二)
  18. VM虚拟机安装及安装Windows系统
  19. eclipse osgi_Eclipse通过提议的OSGi容器Kura支持M2M产品组合
  20. 伯乐发卡网系统修复版源码

热门文章

  1. lg-1 x 怎么算_【言情】魔鬼的体温 by 藤萝为枝 敏感自卑男主x治愈天使女主 我凭美食成为国家宝藏by 十尾兔...
  2. Android开发学习之路III-服务器技术篇
  3. 嵌入式论坛展示微控制器、工具、软件、物联网、连接性、安全性
  4. java文件一行一行读取_Java代码中如何一行一行的读取文本文件呢?
  5. spark报错:java.io.IOException: Filesystem closed
  6. connection closed
  7. chr python用法_使用Python内建chr, ord实现的简单的加/解密
  8. python写整数逆位运算_整数逆位运算
  9. c++画蛋糕_生日蛋糕--C++
  10. 是什么让物联网放慢脚步?