C++学习笔记—g2o库—ICP
这个例子解决的是一个常见的 3D 重建或配准问题:我们有两组对应的三维点云(或者说,已知点之间的匹配关系),并且已经有了一个初始的、可能不太精确的相对位姿估计(旋转 R 和平移 t),我们希望通过优化来获得一个更精确的相对位姿。 与 Bundle Adjustment 的关键区别: BA 通常处理的是 3D 点到 2D 图像点的投影关系。 这个例子处理的是 3D 点到 3D 点 的直接变换关系。 这个特定的例子只优化位姿,而不优化三维点的坐标 (尽管也可以扩展为同时优化点坐标)。 1. 问题描述 假设我们有两组三维点: pts1: 第一组三维点的坐标(在坐标系 1 中)。 pts2: 第二组三维点的坐标(在坐标系 2 中)。 我们知道 pts1[i] 和 pts2[i] 是对应的点。我们还有一个从坐标系 2 变换到坐标系 1 的初始位姿估计 T_12=(R,t)T\_{12} = (R, t)T_12=(R,t)。 目标是:优化位姿 T_12T\_{12}T_12,使得将 pts2 中的每个点 p_2,i\mathbf{p}\_{2,i}p_2,i 通过优化后的位姿...
C++学习笔记—g2o库—BA
1. 问题描述 我们有一个相机,它在某个未知的位置和姿态(合称位姿)下拍摄了一张照片。我们知道: 一些三维空间点的坐标 (points_3d)。 这些三维点在相机拍摄的照片上对应的二维像素坐标 (points_2d)。 相机的内部参数(焦距、主点),通常表示为一个内参矩阵 K。 相机位姿的一个初始估计值(旋转矩阵 R 和平移向量 t)。 由于三维点坐标的测量、二维点观测以及初始位姿估计都可能存在误差,直接将三维点通过初始位姿和内参投影到图像平面,得到的二维坐标通常不会精确地等于观测到的二维坐标。 目标: 同时优化调整相机的位姿 (R, t) 和 三维点的空间坐标 (points_3d),使得所有三维点在优化后的位姿下,根据相机内参投影到图像平面上的重投影坐标与观测到的二维坐标 (points_2d) 之间的误差(重投影误差) 的总和最小。 这本质上是一个大规模的非线性最小二乘优化问题。 2. 思考过程:如何用图优化解决? 我们将 BA 问题转化为 g2o 的图模型: 顶点 (Vertex)...
C++学习笔记—g2o库—曲线拟合
1. 问题描述 我们有一系列二维数据点 (xi,yi)(x_i, y_i)(xi,yi),我们相信这些数据点是由一个指数模型生成的,具体形式为: y=exp(ax2+bx+c)y = \exp(ax^2 + bx + c) y=exp(ax2+bx+c) 然而,我们的观测值 yiy_iyi 包含噪声。我们的目标是:根据这些带有噪声的观测数据 (xi,yi)(x_i, y_i)(xi,yi),估计出最可能生成这些数据的模型参数 (a,b,c)(a, b, c)(a,b,c) 的值。 这本质上是一个优化问题:寻找一组参数 (a,b,c)(a, b, c)(a,b,c),使得模型预测值 exp(axi2+bxi+c)\exp(ax_i^2 + bx_i + c)exp(axi2+bxi+c) 与实际观测值 yiy_iyi 之间的总误差最小(通常是最小化误差的平方和)。 2. 思考:如何用图优化解决? 我们要将这个问题"翻译"成 g2o 的语言——图。一个图由 顶点 (Vertices) 和 边 (Edges) 组成。 顶点...
C++学习笔记—Ceres库
1. 安装 略 2. 问题定义 以 y=exp(ax2+bx+c)y = \exp \left( {a{x}^{2} + {bx} + c}\right)y=exp(ax2+bx+c) 为例 我们现在拥有一系列的观测值 x x1x_1x1 x2x_2x2 … xnx_nxn y y1y_1y1 y2y_2y2 … yny_nyn 目标是用函数 y=exp(ax2+bx+c)y = \exp(ax^2 + bx + c)y=exp(ax2+bx+c) 拟合这些数据点,确定参数 aaa、bbb 和 ccc 的最佳值 在迭代的某一步,假设我们有参数的当前估计值 aka_kak、bkb_kbk 和 ckc_kck。 对于每个数据点 xix_ixi,我们可以计算模型预测值 :y^i\hat{y}_iy^i y^i=exp(akxi2+bkxi+ck)\hat{y}_i = \exp(a_k x_i^2 + b_k x_i +...
C++学习笔记—cmake的新旧方法
CMake新旧方法对比详解 一、include_directories() vs target_include_directories() 这两者的核心区别在于作用域(Scope): 1. include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 …]) 作用域:目录级别 作用: 将指定的目录添加到当前CMakeLists.txt文件以及所有在它之后处理的子目录的头文件搜索路径中 影响: 在调用后定义的所有目标都会将这些目录添加到它们的include路径中 特点: 类似于"全局"设置(在当前目录及子目录范围内) 问题: 不够精确,可能导致目标获得不必要的包含路径 2. target_include_directories(<target> [SYSTEM] [AFTER|BEFORE] <INTERFACE|PUBLIC|PRIVATE> [items1…] [<INTERFACE|PUBLIC|PRIVATE> [items2…]...
C++学习笔记—find原理—以ceres为例子的实操
1. 更新 locate 数据库(必做!) 操作: 打开终端,运行 sudo updatedb 原因: 确保 locate 的数据库包含你刚刚安装的新库的文件信息,否则后续步骤可能找不到任何内容 2. 初步定位:查找核心配置文件 (Config.cmake) 操作: 运行以下命令 1locate -i 'config.cmake' | grep -i...
C++学习笔记—find原理—以opencv为例子的实操
更新 locate 数据库 (必做!) 操作: 打开终端,运行 sudo updatedb。 原因: 确保 locate 的数据库包含你刚刚安装的新库的文件信息。否则后续步骤可能什么也找不到。 初步定位:查找核心配置文件 (Config.cmake) 操作: 运行以下命令 123456789101112131415161718192021222324252627282930locate -i 'config.cmake' | grep -i 'opencv'# 结果为~ ❯ locate -i 'config.cmake' | grep -i...
C++学习笔记—find原理
如何在CMake中找到并链接新安装的库 目标 在安装新库后,找出在CMake中find_package所需的精确包名(包括大小写),并了解如何正确链接该库(优先使用现代CMake目标)。 操作步骤 1. 更新locate数据库(必做!) 操作: 打开终端,运行sudo updatedb 原因: 确保locate的数据库包含你刚刚安装的新库的文件信息 注意: 如果跳过此步骤,后续步骤可能找不到任何结果 2. 初步定位:查找核心配置文件(Config.cmake) 操作: 运行以下命令(替换库名关键词):1locate -i 'config.cmake' | grep -i '库名关键词' 目的: 查找包含config.cmake(不区分大小写)且路径中包含指定库名关键词的文件 分析结果:...
C++学习笔记—CMake2
CMake 学习笔记:Greeter 项目从可执行文件到库的演进 本笔记旨在演示一个 C++ 项目如何使用 CMake 从一个简单的、所有代码编译成单一可执行文件的结构,演进为一个更模块化、更专业的“库 + 可执行文件”的结构。 第一阶段:Greeter 作为单一可执行文件 这是最直接的入门级项目组织方式,适用于小型项目或快速原型开发。 1. 文件结构 假设我们的项目目录结构如下: 1234567greeter_project_executable/├── CMakeLists.txt├── include/│ └── greeter.h # Greeter 类的头文件└── src/ ├── greeter.cpp # Greeter 类的实现 └── main.cpp # 主程序入口 2. C++ 代码 include/greeter.h: 1234567891011#ifndef GREETER_H#define GREETER_H#include <string>class Greeter...
C++学习笔记—CMake
1. 最小可行的 CMakeLists.txt 思考: 我需要告诉 CMake 什么? 它需要知道最低兼容的 CMake 版本是多少?(cmake_minimum_required) 我的项目叫什么名字?(project) 会自动定义一些变量,如 PROJECT_NAME:值为 “GreeterApp” GreeterApp_SOURCE_DIR 或 PROJECT_SOURCE_DIR:项目源代码根目录 GreeterApp_BINARY_DIR 或 PROJECT_BINARY_DIR:构建目录 我想生成什么?(一个可执行文件?一个库?)(add_executable 或 add_library) 这个生成目标需要哪些源文件?(add_executable 或 add_library 的参数) 123456789101112131415# 1. 指定 CMake 最低版本要求# Ubuntu 22.04 自带的 CMake 版本通常较高 (如 3.22+),但设置一个稍低的版本(如 3.16)可以增加兼容性。# 这确保了我们使用的 CMake...