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

Ceres使用

之前用过Ceres,但是只是跑例程,现在来着重学习一下使用流程。

1. 解决的问题

主要解决非线性优化问题。Ceres是一个较为通用的库。
参考链接

2. 如何使用

这个是求解的函数,主要关注这三个参数

CERES_EXPORT void Solve(const Solver::Options& options, Problem* problem, Solver::Summary* summary);

1. options

与优化相关的一些参数配置

2. problem

定义problem
重要的函数

  ResidualBlockId AddResidualBlock(CostFunction* cost_function,LossFunction* loss_function,const std::vector<double*>& parameter_blocks);

其中cost_function是需要我们自己定义的代价函数,拿SLAM14讲中的CURVE_FITTING_COST为例

添加残差项:

    ceres::Problem problem;for(int i=0; i<N; ++i){  //100个点句添加100个误差项//使用自动求导problem.AddResidualBlock(new ceres::AutoDiffCostFunction<CURVE_FITTING_COST, 1, 3>(new CURVE_FITTING_COST(x_data[i], y_data[i])),nullptr,abc  //待估计参数,可在此处给初值);}

其中,AddResidualBlock
@param1ceres::AutoDiffCostFunction是用自动求导的方式,是一个类模板,需要传入参数类型实例化为模板类(类名,输出维度(标量误差,维度1),输入维度(abc三个参数,维度3)),然后传入实际参数来实例化出一个类,(也可以自己求雅克比传给ceres,这里不多说)
@param2 核函数一般不用,传nullptr
@param3 待估计参数(由于非线性优化对初值敏感,所以可以从这里传入待优化变量的初值)

关于残差项的构建:

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, T *residual) const {residual[0] = T(_y) - ceres::exp(abc[0] * T(_x) * T(_x) + abc[1] * T(_x) + abc[2]);return true;}const double _x, _y;
};

重载operator()
@param1 :输入参数,三维待估计参数。
@param2 :输出参数,一维误差。
这个函数就是用输入的参数通过计算,算出残差用于求导。

3. summary

用于保存优化log(日志)

3. 求导方式

3.1 自行求导

求导方式有自行求导和Autodiff
自行求导需要继承ceres::SizedCostFunction,并重载Evaluate()函数自行推导导数计算jacobians,parameters传入的即为待优化参数,
调用:

            CameraLidarFactor *f = new CameraLidarFactor(Rl1_l2, tl1_l2, _z);  //求导方式problem.AddResidualBlock(f, new ceres::HuberLoss(1e-6), &_phi, _t);  //第三部分为待优化参数,可赋初值

具体实现:

class CameraLidarFactor : public ceres::SizedCostFunction<2, 1, 2> {  //第一个是输出维度,phi和t一个1维,一个2维
public:CameraLidarFactor(Matrix2d &Rl1_l2, Vector2d &tl1_l2, Vector2d &z) :  // 待优化的phi,lidar系下的平移Rl1_l2(Rl1_l2), tl1_l2(tl1_l2), z_(z) {}virtual bool Evaluate(double const *const *parameters, double *residuals, double **jacobians) const {double phi_l_lc = parameters[0][0];Matrix2d Rl_lc;  // rot2d_from_yawRl_lc << cos(phi_l_lc), -sin(phi_l_lc),sin(phi_l_lc), cos(phi_l_lc);Vector2d tl_lc(parameters[1][0], parameters[1][1]);Vector2d thc1_hc2 = (-tl_lc + tl1_l2 + Rl1_l2 * tl_lc);  // -(l1)tl1_lc1 + (l1)tl1_l2 + Rl1_l2 * (l2)tl2_lc2Map<Vector2d> residual(residuals);residual = Rl_lc.inverse() * thc1_hc2 - z_;  //(hc1)thc1_hc2' - (hc1)thc1_hc2if (jacobians) {if (jacobians[0]) {Matrix2d Rl_hc_inverse_prime;Rl_hc_inverse_prime << -sin(phi_l_lc), cos(phi_l_lc),  //逆求导-cos(phi_l_lc), -sin(phi_l_lc);Map<Matrix<double, 2, 1>> jacobian_phi(jacobians[0]);jacobian_phi = Rl_hc_inverse_prime * thc1_hc2;}if (jacobians[1]) {Map<Matrix<double, 2, 2, RowMajor>> jacobian_t(jacobians[1]);jacobian_t = Rl_lc.inverse() * (Rl1_l2 - Matrix2d::Identity());}}return true;}Matrix2d Rl1_l2;Vector2d tl1_l2, z_;
};

3.2 Autodiff自动求导

在定义costfunction时选择ceres::AutoDiffCostFunction使用自动求导,求数值导数,需要重载operator()。

**注意:**这里重载operator需要是函数模板,里面所有的数据都要使用模板的数据类型。

调用:

        ceres::CostFunction *cost_function = NULL;cost_function = CamTiltFactor::Create(init_z, image_poses_[i].second.translation());problem.AddResidualBlock(cost_function, new ceres::HuberLoss(1e-5), para_qic);

实现:

struct CamTiltFactor {CamTiltFactor(const double init_z, const Eigen::Vector3d trans) :init_z_(init_z), trans_(trans) {}static ceres::CostFunction *Create(const double init_z, Eigen::Vector3d trans) {return new ceres::AutoDiffCostFunction<CamTiltFactor, 1, 4>(new CamTiltFactor(init_z,  trans));}template<typename _T2>bool operator()(const _T2 *const para_qic, _T2 *residuals) const {//计算residualspara_qic[0]Eigen::Quaternion<_T2> _quat{para_qic[0], para_qic[1], para_qic[2], para_qic[3]};Eigen::Matrix<_T2, 3, 1> tmp_trans_(_T2(trans_.x()), _T2(trans_.y()), _T2(trans_.z()));Eigen::Matrix<_T2, 3, 1> _t_rotated = _quat * tmp_trans_;  //使用重载的乘法residuals[0] = _T2(_t_rotated.z()) - _T2(init_z_);  //残差return true;}Vector3d trans_;double init_z_;
};

另外,当四元数为优化的对象时,需要调用ceres::QuaternionParameterization来消除自由度冗余

    double para_qic[4] = {1, 0, 0, 0};problem.AddParameterBlock(para_qic, 4, new ceres::QuaternionParameterization);

相关文章:

Ceres使用

之前用过Ceres&#xff0c;但是只是跑例程&#xff0c;现在来着重学习一下使用流程。 1. 解决的问题 主要解决非线性优化问题。Ceres是一个较为通用的库。 参考链接 2. 如何使用 这个是求解的函数&#xff0c;主要关注这三个参数 CERES_EXPORT void Solve(const Solver::O…...

深度学习第1天:深度学习入门-Keras与典型神经网络结构

☁️主页 Nowl &#x1f525;专栏《机器学习实战》 《机器学习》 &#x1f4d1;君子坐而论道&#xff0c;少年起而行之 文章目录 神经网络 介绍 结构 基本要素 Keras 介绍 导入 定义网络 模型训练 前馈神经网络 特点 常见类型 代码示例 反馈神经网络 特点 …...

青云科技容器平台与星辰天合存储产品完成兼容性互认证

近日&#xff0c; 北京青云科技股份有限公司&#xff08;以下简称&#xff1a;青云科技&#xff09;的 KubeSphere 企业版容器平台成功完成了与 XSKY星辰天合的企业级分布式统一数据平台 V6&#xff08;简称&#xff1a;XEDP&#xff09;以及天合翔宇分布式存储系统 V6&#xf…...

谈谈基于Redis的分布式锁

目录 前言 基本介绍 演化过程 防死锁 防误删 自动续期 可重入 主从一致 总结 前言 在我们没有了解分布式锁前&#xff0c;使用最多的就是线程锁和进程锁&#xff0c;但他们仅能满足在单机jvm或者同一个操作系统下&#xff0c;才能有效。跨jvm系统&#xff0c;无法…...

逸学java【初级菜鸟篇】10.I/O(输入/输出)

hi&#xff0c;我是逸尘&#xff0c;一起学java吧 目标&#xff08;任务驱动&#xff09; 1.请重点的掌握I/O的。 场景&#xff1a;最近你在企业也想搞一个短视频又想搞一个存储的云盘&#xff0c;你一听回想到自己对于这些存储的基础还不是很清楚&#xff0c;于是回家开始了…...

【Python进阶笔记】md文档笔记第6篇:Python进程和多线程使用(图文和代码)

本文从14大模块展示了python高级用的应用。分别有Linux命令&#xff0c;多任务编程、网络编程、Http协议和静态Web编程、htmlcss、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。 全套md格式笔记和代码自…...

基于Vue+SpringBoot的数字化社区网格管理系统

项目编号&#xff1a; S 042 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S042&#xff0c;文末获取源码。} 项目编号&#xff1a;S042&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 源码 & 项目录屏 二、功能模块三、开发背景四、系统展示五…...

【数据库设计和SQL基础语法】--数据库设计基础--数据建模与ER图

一、数据建模的基本概念 1.1. 数据模型的概念 数据模型是对现实世界中事物及其之间关系的一种抽象表示。它提供了描述数据结构、数据操作、数据约束等的方式&#xff0c;是数据库设计的基础。数据模型帮助我们理解数据之间的关系&#xff0c;提供了一种规范化的方式来组织和存…...

Vue3 设置点击后滚动条移动到固定的位置

需求&#xff1a; 点击不通过按钮&#xff0c;显示红框中表单&#xff0c;且滚动条滚动到底部 &#xff08;显示红框中表单默认不显示&#xff09; <el-button click"onApprovalPass">不通过</el-button> <div class"item" v-if"app…...

外部 prometheus监控k8s集群资源(pod、CPU、service、namespace、deployment等)

prometheus监控k8s集群资源 一&#xff0c;通过CADvisior 监控pod的资源状态1.1 授权外边用户可以访问prometheus接口。1.2 获取token保存1.3 配置prometheus.yml 启动并查看状态1.4 Grafana 导入仪表盘 二&#xff0c;通过kube-state-metrics 监控k8s资源状态2.1 部署 kube-st…...

LLMLingua:集成LlamaIndex,对提示进行压缩,提供大语言模型的高效推理

大型语言模型(llm)的出现刺激了多个领域的创新。但是在思维链(CoT)提示和情境学习(ICL)等策略的驱动下&#xff0c;提示的复杂性不断增加&#xff0c;这给计算带来了挑战。这些冗长的提示需要大量的资源来进行推理&#xff0c;因此需要高效的解决方案&#xff0c;本文将介绍LLM…...

数据资产确权的难点

数据是企业的重要资产之一&#xff0c;但是许多企业对于这项资产在管理上都面临着一些挑战&#xff0c;其中最关键就是数据确权的问题。接下来&#xff0c;将探讨数据资产确权的难点&#xff0c;并提出相应的解决方案&#xff0c;一起来看吧。 首先介绍一下数据资产入表的背景以…...

EMG肌肉电信号处理合集(二)

本文主要展示常见的肌电信号特征的提取说明。使用python 环境下的Pysiology计算库。 目录 1 肌电信号第一次burst的振幅&#xff0c; getAFP 函数 2 肌电信号波长的标准差计算&#xff0c;getDASDV函数 3 肌电信号功率谱频率比例&#xff0c;getFR函数 4 肌电信号直方图…...

2023亚马逊云科技re:Invent引领科技新潮流:云计算与生成式AI共塑未来

2023亚马逊云科技re:Invent引领科技新潮流&#xff1a;云计算与生成式AI共塑未来 历年来&#xff0c;亚马逊云科技re:Invent&#xff0c;不仅是全球云计算从业者的年度狂欢&#xff0c;更是全球云计算领域每年创新发布的关键节点。 2023年亚马逊云科技re:Invent大会在美国拉斯…...

案例018:基于微信小程序的实习记录系统

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…...

视频剪辑技巧:如何高效批量转码MP4视频为MOV格式

在视频剪辑的过程中&#xff0c;经常会遇到将MP4视频转码为MOV格式的情况。这不仅可以更好地编辑视频&#xff0c;还可以提升视频的播放质量和兼容性。对于大量视频文件的转码操作&#xff0c;如何高效地完成批量转码呢&#xff1f;现在一起来看看云炫AI智剪如何智能转码&#…...

node.js获取unsplash图片

1. 在Unsplash的开发者页面注册并创建一个应用程序&#xff0c;以便获取一个API访问密钥&#xff08;即Access Key&#xff09;。 2. 安装axios&#xff1a; npm install axios3. 使用获取到的API密钥进行请求。 示例代码如下&#xff1a; const axios require(axios);con…...

Git远程库操作(GitHub)

GitHub 网址&#xff1a;https://github.com/ 创建远程仓库 远程仓库操作 命令名称作用git remote -v查看当前所有远程地址别名git remote add 别名 远程地址起别名git push 别名 分支推送本地分支上的内容到远程仓库git clone 远程地址将远程仓库的内容克隆到本地git pull 别…...

java计算下一个整10分钟时间点

最近工作上遇到需要固定在整10分钟一个周期调度某个任务&#xff0c;所以需要这样一个功能&#xff0c;记录下 package org.example;import com.google.gson.Gson; import org.apache.commons.lang3.time.DateUtils;import java.io.InputStream; import java.util.Calendar; i…...

力扣刷题篇之排序算法

系列文章目录 前言 本系列是个人力扣刷题汇总&#xff0c;本文是排序算法。刷题顺序按照[力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 - 力扣&#xff08;LeetCode&#xff09; 这个之前写的左神的课程笔记里也有&#xff1a; 左程云算法与数据结构代码汇总之排序&am…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...