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

Ceres Solver中 SetParameterization函数的完整详解

1. 函数作用

SetParameterization 用于设置参数块(parameter block)的局部参数化方式
在 Ceres 中,优化变量通常是一个实数向量(double*),默认情况下直接在欧式空间中进行加减更新。
但对于某些参数(如四元数、旋转矩阵、SE(3) 位姿等),它们存在流形(manifold)约束,不能直接用普通加法更新。

SetParameterization 就是用来告诉 Ceres 如何在局部更新这些参数,即:

  • 从全局参数空间映射到局部优化空间(Local Parameterization)
  • 保持参数合法性(例如四元数始终单位化)

2. 函数原型

bool Problem::SetParameterization(double* values,LocalParameterization* local_parameterization
);

参数说明

  • values
    指向参数块数据的指针(在 AddParameterBlockAddResidualBlock 时注册过的那块内存)。

  • local_parameterization
    指向一个继承自 LocalParameterization 的对象,用于定义局部更新规则。
    常用的现成类:

    • ceres::IdentityParameterization(默认,加法更新)
    • ceres::QuaternionParameterization(保持四元数单位化)
    • ceres::HomogeneousVectorParameterization(保持齐次向量单位化)
    • 自定义派生类(实现任意流形更新规则)

3. 使用步骤

  1. 创建问题

    ceres::Problem problem;
    
  2. 注册参数块

    problem.AddParameterBlock(parameter_ptr, size);
    
  3. 设置局部参数化

    problem.SetParameterization(parameter_ptr,new ceres::QuaternionParameterization());
    
  4. 添加残差块

    problem.AddResidualBlock(cost_function, loss_function, parameter_ptr);
    
  5. 求解

    ceres::Solver::Options options;
    ceres::Solver::Summary summary;
    ceres::Solve(options, &problem, &summary);
    

4. 代码示例

四元数优化(保持归一化)

#include <ceres/ceres.h>
#include <ceres/rotation.h>
#include <iostream>// 一个简单的残差:假设目标是四元数 q 接近 [1,0,0,0]
struct QuaternionResidual {template<typename T>bool operator()(const T* const q, T* residual) const {residual[0] = q[0] - T(1.0);residual[1] = q[1] - T(0.0);residual[2] = q[2] - T(0.0);residual[3] = q[3] - T(0.0);return true;}
};int main() {double q[4] = {0.35, 0.2, 0.3, 0.1}; // 非单位化四元数ceres::Problem problem;ceres::CostFunction* cost_function =new ceres::AutoDiffCostFunction<QuaternionResidual, 4, 4>(new QuaternionResidual);problem.AddParameterBlock(q, 4);// 设置局部参数化为四元数流形problem.SetParameterization(q, new ceres::QuaternionParameterization());problem.AddResidualBlock(cost_function, nullptr, q);ceres::Solver::Options options;options.minimizer_progress_to_stdout = true;ceres::Solver::Summary summary;ceres::Solve(options, &problem, &summary);std::cout << "Final quaternion: "<< q[0] << " " << q[1] << " " << q[2] << " " << q[3] << "\n";return 0;
}

5. 关键注意事项

  1. 参数化对象的生命周期

    • SetParameterization 会接管你传入的 LocalParameterization* 的生命周期,Ceres 会在 Problem 析构时自动释放,不要手动 delete。
  2. 维度匹配

    • 局部参数化的 GlobalSize() 必须等于参数块的大小;
    • LocalSize() 是优化变量在局部空间的维度(可能更小),例如四元数 GlobalSize=4LocalSize=3
  3. 同一参数块只能设置一次

    • 对同一个指针重复调用会出错。
  4. 流形合法性

    • Plus() 函数中必须保持参数合法(例如归一化四元数)。
  5. 避免在 SetParameterization 之后直接修改原始数据

    • 尤其是修改后不再满足流形约束,可能导致求解过程异常。

6. 高级用法

  1. 自定义局部参数化

    class MyParameterization : public ceres::LocalParameterization {
    public:virtual bool Plus(const double* x, const double* delta, double* x_plus_delta) const {// 自定义更新规则// x: 当前全局参数// delta: 局部增量return true;}virtual bool ComputeJacobian(const double* x, double* jacobian) const {// 定义局部到全局的雅可比return true;}virtual int GlobalSize() const { return 4; }virtual int LocalSize() const { return 3; }
    };
    
  2. 固定部分维度(部分参数化)
    Ceres 提供 SubsetParameterization,可以固定参数中的某些分量不参与优化。

    std::vector<int> constant_idx = {0, 1}; // 固定前两个分量
    problem.SetParameterization(ptr,new ceres::SubsetParameterization(5, constant_idx));
    
  3. 组合参数化
    使用 ProductParameterization 将多个参数化方式组合,例如 SE3 = Quaternion × Translation


http://www.lryc.cn/news/622219.html

相关文章:

  • MySQL视图:虚拟表的强大用途与限制
  • Effective C++ 条款43:学习处理模板化基类内的名称
  • 农药化肥行业的 “智能化拐点”:边缘计算网关如何破解生产效率困局?
  • P4069 [SDOI2016] 游戏 Solution
  • 使用 Let’s Encrypt 免费申请泛域名 SSL 证书,并实现自动续期
  • Python匿名函数的具体用法
  • 蓝桥杯 二叉树
  • 企业级时序数据库选型指南:从传统架构向智能时序数据管理的转型之路
  • Java: Spring前端传递列表和数组限制大小256问题
  • ​Visual Studio 2013.5 ULTIMATE 中文版怎么安装?iso镜像详细步骤
  • [优选算法专题二滑动窗口——无重复字符的最长子串]
  • 介绍TCP的拥塞控制
  • 【Go语言-Day 36】构建专业命令行工具:`flag` 包入门与实战
  • 用Qt自带工具windeployqt快速打包程序
  • 龙蜥邀您参加 AICon 全球人工智能开发与应用大会,探索 AI 应用边界
  • 2020 GPT3 原文 Language Models are Few-Shot Learners 精选注解
  • [Chat-LangChain] 会话图(LangGraph) | 大语言模型(LLM)
  • JAVA 关键字
  • 清除 pnpm 缓存,解决不同源安装依赖包失败的问题
  • 银河麒麟服务器jar包部署自启动配置
  • 如何在 Ubuntu 24.04 Noble LTS 上安装 Apache 服务器
  • 第十八讲:哈希2
  • Navicat 询问 AI | 轻松修复 SQL 错误
  • vector接口模拟实现及其原理
  • linux程序编译笔记
  • 软件重构的破与立:模式方法创新设计与工程实践
  • 达梦数据库使用控制台disql执行脚本
  • QML实现数据可视化
  • Nginx蜘蛛请求智能分流:精准识别爬虫并转发SEO渲染服务
  • redis-保姆级配置详解