• Ceres安装以及使用


    优化库——ceres(一)快速概览_雨luo凡城的博客-CSDN博客_ceres优化

    通过上面这篇博客了解,代价函数,残差块,损失函数,待优化变量的定义,以及求解的问题模型

    网上说ceres的教程丰富,实际上说清楚的没什么。


    一. 安装


    二. 使用

    2.1 cmake包含

    1. find_package(Ceres REQUIRED)
    2. include_directories(${CERES_INCLUDE_DIRS})
    3. target_link_libraries(TestCeres ${CERES_LIBRARIES})

    2.2 正式使用

    添加待优化变量范围:

    1. // Set the lower/upper bound for the parameter with position "index".
    2. void SetParameterLowerBound(double* values, int index, double lower_bound);
    3. void SetParameterUpperBound(double* values, int index, double upper_bound);

    具体的使用方法参加2.2.1节中的注释。不使用就是无约束。

    2.2.1 自动求导

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. // target:求 y = 10 - x 的最小值
    6. // (1). 问题转换
    7. // min (10 - x)^2
    8. // x
    9. // (2). 提取出 代价函数,残差块,损失函数
    10. // 代价函数:10 - x
    11. // 残差块:(10-x)^2 (只有一个残差块,外面没有套核函数)
    12. // 损失函数:(10-x)^2
    13. // [2]. 对于ceres,构造代价函数
    14. // [2.1] 找出代价函数的组成:待优化变量 和 其他数据(通过构造函数传入,不是必须有的)
    15. // x 无
    16. // [2.2] 对于ceres,operator 有两个必备参数, 最后必须返回true
    17. struct myFunctor
    18. {
    19. myFunctor(){};
    20. template<typename T>
    21. bool operator()(const T* varsToBeOptimized, T* residual) const
    22. {
    23. residual[0] = varsToBeOptimized[0] - T(10.0);
    24. return true;
    25. }
    26. };
    27. int main()
    28. {
    29. double x = 30;
    30. // [1]. 构建优化问题
    31. ceres::Problem myProblem;
    32. // [2]. 构造代价函数(仿函数)(见上)
    33. // [3]. 实例化代价函数 , 自动求导
    34. // 第一个1是残差维数,第二个1是待优化变量维数
    35. ceres::CostFunction* myFun = new ceres::AutoDiffCostFunction1, 1>(new myFunctor());
    36. // [4]. 添加残差块构造损失函数
    37. myProblem.AddResidualBlock(myFun, NULL, &x);
    38. myProblem.SetParameterLowerBound(&x, 0, 15);
    39. myProblem.SetParameterUpperBound(&x, 0, 40);
    40. // [5]. 配置求解器
    41. ceres::Solver::Options options;
    42. // 用于求解A*dx=b,通过稠密QR分解进行
    43. options.linear_solver_type = ceres::DENSE_QR;
    44. options.minimizer_progress_to_stdout = true;
    45. ceres::Solver::Summary summary;
    46. chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
    47. ceres::Solve(options, &myProblem, &summary);
    48. chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
    49. chrono::duration<double> time_used = chrono::duration_castdouble>>(t2 - t1);
    50. cout << "cost: " << time_used.count() << "seconds" << endl;
    51. cout << summary.BriefReport() << endl;
    52. cout << "estimated x: " << x << endl;
    53. return 0;
    54. }

    注意cmake文件要包含如下内容才能正确编译,因为chrono输入c++11

    1. cmake_minimum_required(VERSION 3.23)
    2. set(CMAKE_CXX_FLAGS "-std=c++11")
    3. project(TestCeres)
    4. add_executable(TestCeres main.cpp)
    5. find_package(Ceres REQUIRED)
    6. include_directories(${CERES_INCLUDE_DIRS})
    7. target_link_libraries(TestCeres ${CERES_LIBRARIES})

    2.2.2 解析求导

    1. #include"ceresPractice.h"
    2. // ""从当前文件搜索
    3. // <>从系统路径搜索
    4. //TODO: public ceres::SizedCostFunction<4, 4> 这一部分要注意参数的意义
    5. // TODO:通过继承SizedCostFunction类,就显式地指定了残差的个数,和参数块的个数,以及参数块内参数的个数
    6. class myAnalyCostFunctor: public ceres::SizedCostFunction<4, 4>
    7. {
    8. // TODO: 在写完标题头之后,该写一个构造函数
    9. public:
    10. myAnalyCostFunctor(){}
    11. // virtual ~myAnalyCostFunctor(){}
    12. // TODO: 遵循行优先,c++, 一个参数块占一行,一个参数块对应的偏导占一行
    13. virtual bool Ev
  • 相关阅读:
    04_第四章 XML_Tomcat_HTTP
    19、wpf之事件转命令实现MVVM架构
    1530_AURIX_TriCore内核架构_通用寄存器以及系统寄存器
    Arnold置乱
    nginx系列第二篇:nginx源码调试
    【android Framework 探究】android 13 aosp编译全记录
    Junit5 + YAML 轻松实现参数化和数据驱动(一)
    面试题:什么是this.$nextTick
    外设驱动库开发笔记44:DDC114 ADC驱动
    vue3项目实战的请求接口问题(一)跨域问题+解决方法
  • 原文地址:https://blog.csdn.net/qq_43526137/article/details/127080769