SLAM 面试题汇总


  • Description:SLAM 面试常见短问题集 — 视差/深度、特征点法 vs 直接法、单目尺度漂移、绑架问题、闭环检测、评估指标 (RPE/ATE/RMSE)、点云平面提取等约 17 题
  • My Notion Note ID:K2E-A-S3
  • Created:2023-04-10
  • Updated:2026-06-03
  • License转载欢迎:请署名 Yu Zhang 并链回 yuzhang.io 原文

Table of Contents


A. 几何与测量

A1. 视差与深度的关系

双目立体匹配的基础公式:

dB=fZZ=fBd\frac{d}{B} = \frac{f}{Z} \quad \Rightarrow \quad Z = \frac{f B}{d}
  • dd = 视差 (parallax),单位 pixel
  • BB = 基线 (baseline),左右相机光心距离
  • ff = 焦距,单位 pixel
  • ZZ = 深度

推论 (见 三角化 §6 不确定性):

σZZ2fBσd\sigma_Z \propto \frac{Z^2}{f B} \sigma_d

深度精度随深度平方退化。固定相机 → 想测远处准 → 必须加大基线

A2. 单目相机的投影模型与畸变模型

投影模型 (针孔):

[uv1]=K1Z[XYZ]=1Z[fx0cx0fycy001][XYZ]\begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = K \cdot \frac{1}{Z} \begin{bmatrix} X \\ Y \\ Z \end{bmatrix} = \frac{1}{Z} \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} X \\ Y \\ Z \end{bmatrix}

畸变模型 (Brown-Conrady):

径向畸变 (k1,k2,k3k_1, k_2, k_3):

xdist=x(1+k1r2+k2r4+k3r6)x_{\text{dist}} = x (1 + k_1 r^2 + k_2 r^4 + k_3 r^6)

切向畸变 (p1,p2p_1, p_2):

xdist=x+2p1xy+p2(r2+2x2)x_{\text{dist}} = x + 2 p_1 xy + p_2 (r^2 + 2x^2)

OpenCV 标定输出 5 个系数 (k1,k2,p1,p2,k3)(k_1, k_2, p_1, p_2, k_3)。鱼眼相机用 等距投影模型 + 4 个系数 (cv::fisheye::*)。

A3. 双线性插值

子像素值的标准插值方法:

I(u,v)=(1α)(1β)I(u,v)+α(1β)I(u,v)I(u, v) = (1 - \alpha)(1 - \beta) \, I(\lfloor u \rfloor, \lfloor v \rfloor) + \alpha (1 - \beta) \, I(\lceil u \rceil, \lfloor v \rfloor) +(1α)βI(u,v)+αβI(u,v)+ (1 - \alpha) \beta \, I(\lfloor u \rfloor, \lceil v \rceil) + \alpha \beta \, I(\lceil u \rceil, \lceil v \rceil)

其中 α=uu\alpha = u - \lfloor u \rfloor, β=vv\beta = v - \lfloor v \rfloor

核心思想:4 个邻近像素按反距离权重加权。SLAM 里光流跟踪、KLT、直接法都用得到。

A4. Symmetric Epipolar Distance

衡量一对匹配点对极几何一致性的指标。给定 F 矩阵和匹配点 p1,p2p_1, p_2

dsym(p1,p2;F)=(p2TFp1)2(Fp1)x2+(Fp1)y2+(p2TFp1)2(FTp2)x2+(FTp2)y2d_{\text{sym}}(p_1, p_2; F) = \frac{(p_2^T F p_1)^2}{(Fp_1)_x^2 + (Fp_1)_y^2} + \frac{(p_2^T F p_1)^2}{(F^T p_2)_x^2 + (F^T p_2)_y^2}
  • 几何意义:p2p_2 到极线 Fp1Fp_1 的距离平方 + p1p_1 到极线 FTp2F^T p_2 的距离平方
  • 比简单 p2TFp1|p_2^T F p_1| 更对称,常用于 RANSAC 内点判定

B. 算法

B1. 特征点法 vs 直接法

维度 特征点法 直接法
代表系统 ORB-SLAM, VINS-Mono DSO, LSD-SLAM, SVO
代价函数 重投影误差 光度误差
数据关联 描述子匹配 像素灰度直接对齐
不变性 旋转/尺度 (描述子保证) 仅小位移有效
优点 鲁棒,运动快也能跟 速度快 (省描述子),弱纹理可用
缺点 特征少时失效;提取慢 易受光照影响;运动必须慢;非凸
地图 稀疏 稀疏 / 半稠密 / 稠密

B2. 边缘检测算子

经典三步:滤波 → 增强 → 检测

算子 思路 特点
Sobel 一阶差分模板 (水平 + 垂直) 简单,对噪声中等敏感
Laplacian 二阶差分 (各向同性) 对噪声敏感
Canny 高斯平滑 → Sobel 梯度 → NMS → 双阈值滞后 最常用,质量最好

OpenCV: cv::Canny, cv::Sobel, cv::Laplacian

B3. 激光雷达运动畸变去除

问题:单次激光扫描时长 ~100 ms,扫描过程中传感器持续运动 → 不同方位的点云在不同位姿采集 → 直接拼起来是扭曲的。

两种思路

纯估计法 (无里程计辅助)

迭代估位姿:

  1. 寻找当前帧内对应点
  2. ICP / 极大似然估计 R, t
  3. 用解出的位姿修正点云
  4. 迭代直到收敛

里程计辅助法 (工程主流)

  1. 已知扫描起止时间 ts,tet_s, t_e
  2. 维护一个里程计位姿队列 (IMU/轮速/光流,按时间排好)
  3. 对每个激光点 pip_i (有自己的时间戳 tit_i):
    • 在队列里查 tit_i 时刻的位姿 TiT_i
    • pip_iTiT_i 系变换到 TsT_s 系 (扫描起始位姿)
  4. 重组成无畸变的"伪同步"帧

工程上:LOAM, FAST-LIO 等 LIO 系统都用 IMU 内插法 + 高频积分实现。

B4. 点云平面提取

方法 思路
区域生长 (Region Growing) 从最小曲率点起,沿法向一致的邻居扩展
RANSAC 平面模型 随机抽 3 点拟合平面 → 内点统计
凹包 (Alpha-Shape) 边界提取 先求凸包 → 按 α 半径挖凹 (删除长于 α 的边) → 得到点云边界轮廓
基于 Delaunay 三角网 三角剖分 + 拓扑分析
DBSCAN + 平面拟合 聚类 + 子集平面拟合
学习方法 PointNet, PointNet++ 等深度分割

区域生长 详细:

  1. 按曲率升序排点 (从最平坦区域开始)
  2. 选最低曲率点作种子,加入种子队列
  3. 取队列首点 → 搜邻居 → 法向夹角小于阈值的邻居加入区域
  4. 邻居中曲率低于阈值的也加入种子队列
  5. 重复直到种子队列空

PCL 库提供现成实现 (pcl::RegionGrowing)。

B5. 俯视图变换 IPM

Inverse Perspective Mapping:给定相机和地面平面的相对关系,把图像逆透视变换为俯视图。

流程:

  1. 灰度化 → 减少计算量
  2. 滤波 (高斯) → 去噪
  3. 边缘检测 (Canny) → 找直线 (车道线)
  4. 霍夫变换 检测 4 个交点 (或预先用标定/IMU 知道地面平面在相机坐标系下的方程)
  5. 算单应矩阵 HHH=K(R+1dtNT)K1H = K (R + \frac{1}{d} t N^T) K^{-1} (推导见 F/E/H 矩阵 §4 单应矩阵;与该篇符号约定一致。标准 Hartley-Zisserman / OpenCV decomposeHomographyMat 在其约定下写作 1dtNT-\frac{1}{d}tN^T — 正负号仅随 tt 方向 / 法向 NN / 映射方向的约定而变,并非矛盾)
  6. cv::warpPerspective 应用 HH 得俯视图

自动驾驶中 BEV 感知的几何 baseline。

C. SLAM 系统对比

C1. 单目尺度漂移如何产生

  • 根源:单目视觉尺度不可观:把世界等比例放大缩小,所有图像观测不变
  • 初始化 时用三角化确定一个相对尺度 (基于第一段平移的"猜想"长度)
  • 运行中:每帧都重新三角化新地图点 → 尺度依赖前一帧的尺度 → 数值误差累积 → 尺度连续漂移
  • 修正:通过回环检测 + Sim(3) 优化纠正 — 这就是 几何变换层级 §3 相似变换的核心 SLAM 应用

C2. 绑架问题

Kidnapping problem:跟踪过程中机器人位姿突变 (被人为搬动 / 跟踪丢失) → 系统当前位姿估计完全错误。

两种情况:

初始化绑架 (尚未建立跟踪)

  • 蒙特卡洛定位 (MCL) / 粒子滤波全图撒粒子
  • 随里程信息逐步收敛到正确位姿
  • 粒子滤波 §7 SLAM 中的应用

跟踪丢失后绑架

绑架前已有位姿估计,但跟踪失败:

  • 重定位 (Relocalization):用词袋 (DBoW) 找历史相似关键帧 → PnP 求位姿
  • 候补传感器辅助 (GPS, WiFi, 地磁)
  • ORB-SLAM 2/3 的 Relocalization 模块就是这个

C3. RGB-D SLAM vs RGB SLAM

维度 RGB SLAM (单目) RGB-D SLAM
尺度 不可观,需回环修正 深度直接可观,无尺度漂移
初始化 需运动 + 三角化 (纯旋转 / 平面退化) 单帧即可
地图 稀疏点云 (除非用直接法/学习方法) 自然得到稠密地图
远处精度 视差很小,深度差 深度传感器有效距离 (~5 m) 外退化
代表系统 ORB-SLAM 1, DSO KinectFusion, ElasticFusion, BAD-SLAM
典型场景 室外、AR、长距离 室内、机械臂、家用机器人

C4. Local Map vs 滑窗法

两种 SLAM 后端优化的代表性策略:

维度 Local Map (ORB-SLAM) 滑窗法 (VINS-Mono)
维护对象 当前帧 + 共视关键帧 + 其地图点 最近 N 帧 (N ~ 10) + 对应路标
优化变量 关键帧位姿 + 局部地图点 滑窗内所有帧位姿 + 路标 + 速度 + bias
边缘化 不显式边缘化 (老关键帧"沉淀") Schur 补显式边缘化,保留先验信息
后端框架 g2o 因子图 Ceres + 手工管理边缘化项
计算量 中等 (共视图剪枝) 严格控制 (窗口固定)
适合 视觉 SLAM VIO (高频 IMU 需要快速优化)

C5. ORB-SLAM 的缺点

  1. 特征提取速度:ORB 比 SIFT 快但仍是 CPU 瓶颈;嵌入式平台 (Jetson, Apple Silicon 之前) 难实时
  2. 地图稀疏:只保留 ORB 特征点位置,无法直接用于避障 / 稠密重建
  3. 动态物体敏感:默认假设静态场景,行人/车辆出现时跟踪劣化 (DynaSLAM, DS-SLAM 等针对解决)
  4. 纹理弱场景:白墙、无特征工厂环境直接挂掉 (直接法系统好得多)
  5. 大尺度漂移:没有 IMU/GPS 融合时长距离会累积;ORB-SLAM 3 引入 IMU 缓解

C6. 闭环检测常用方法

系统 闭环检测策略
ORB-SLAM 2/3 词袋模型 (DBoW2/3) 筛选候选帧 → 几何验证 + Sim(3) 求解
LSD-SLAM 基于视差/共视关系找候选 → 双向 Sim(3) 跟踪验证,马氏距离阈值
学习方法 NetVLAD, MixVPR, AnyLoc → 全局描述子近邻搜索
激光 SLAM Scan Context (列移位匹配处理朝向,部分旋转鲁棒;Scan Context++ 才是频域旋转不变) / SGLC (语义图)

通用三步:候选筛选 (快速但有假阳) → 几何验证 (精确但慢) → 后端融合 (Sim(3) / 位姿图优化)

C7. 室内 SLAM vs 自动驾驶 SLAM

(高翔在哔哩哔哩讲座的归纳整理;参考链接见 References)

维度 室内 SLAM 自动驾驶 SLAM
平台 机器人/AR/扫地机 乘用车/卡车
运动范围 小 (单房间到楼宇) 大 (城市到城际,km 量级)
运动模式 任意 6 DOF (扫地机 3 DOF) 准 2D + Ackerman 约束 (转弯有约束)
传感器 RGB-D / 单目 + IMU / 2D 激光 多线激光 + 多目相机 + GNSS/RTK + 高精地图 + IMU
回环密度 高 (室内闭环频繁) 低 (长直线行驶很少自然回环)
动态物体 中等 (人、宠物) 高 (其他车辆、行人)
光照 受控 (室内灯) 强变化 (白天、夜间、隧道、阴影)
典型系统 ORB-SLAM 3, RTAB-Map, ElasticFusion LOAM/LIO-SAM, FAST-LIO, 高精地图定位
关键挑战 弱纹理墙面、镜面反射 长距离漂移、动态物体、传感器同步

C8. 紧耦合 vs 松耦合

多传感器融合的两种架构:

松耦合 (Loosely Coupled)

各传感器独立处理 → 输出位姿 → 后端再融合

  • 视觉 SLAM 算自己的位姿,IMU 算自己的预测位姿,KF 把两者按权重融合
  • 代表系统:VIO 早期工作,部分商用方案
  • 优点:模块解耦,易实现;某个传感器失效不会拖垮整个系统
  • 缺点:丢信息 (各模块内部约束未充分利用);时间同步要求高

紧耦合 (Tightly Coupled)

各传感器的原始观测共同进入一个优化问题

  • 视觉的重投影残差 + IMU 的预积分残差 + 轮速残差 → 联合 BA / KF
  • 代表系统:VINS-Mono/Fusion, ORB-SLAM 3 VI, OKVIS, FAST-LIO
  • 优点:信息利用最充分,精度最高
  • 缺点:实现复杂;某传感器异常可能污染整个状态

工程选择

现代主流 SLAM 几乎全用紧耦合 (除非传感器接口受限)。松耦合作为 fallback 仍然出现在工业级系统中。

C9. EKF vs BA / 滤波 vs 优化

SLAM 后端的两大范式:

维度 EKF (滤波) BA (优化)
状态表达 当前状态 + 协方差矩阵 所有历史状态 (或滑窗内)
计算复杂度 每帧 O(n2)O(n^2) — n 是 landmark 数 朴素单次 O((m+n)3)O((m{+}n)^3) (m=相机, n=路标);Schur 补消点后降至 O(m3)O(m^3),稀疏求解可近 O(m)O(m)
回环 难处理 (信息丢失) 自然加入约束
重线性化 一次线性化 (易发散) 反复迭代 (更准)
代表系统 MSCKF, ROVIO ORB-SLAM, VINS, COLMAP
历史 SLAM 早期主流 (1990s-2010s) 因子图框架兴起后成为主流 (2010s+)

核心区别:滤波只保留当前状态,信息一旦边缘化就无法回头;优化保留全状态,可反复线性化和加约束。

代价:优化的计算量大;但 Schur 补 + 稀疏求解器把它降到可实时。

C10. 经典视觉 SLAM 框架速查表

传感器 + 方法 分类:

系统 传感器 方法 特点
MonoSLAM (2003) 单目 EKF + 稀疏 最早实时单目 SLAM (ICCV 2003;期刊版 PAMI 2007)
PTAM (2007) 单目 关键帧 + BA (建图/跟踪并行) 开创双线程结构
DTAM (2011) 单目 稠密直接法 GPU 求稠密地图
KinectFusion (2011) RGB-D TSDF + Point-to-Plane ICP RGB-D 室内重建标杆
LSD-SLAM (2014) 单目 半稠密直接法 直接法路线代表
ORB-SLAM 1/2/3 (2015-21) 单目 / 双目 / RGB-D / + IMU 特征点法 + 关键帧 BA + 词袋回环 最广泛的 VSLAM 框架
SVO (2014) 单目 / + IMU 半直接法 + 深度滤波器 快、轻
DSO (2017) 单目 光度 BA + 滑窗 直接法 SOTA
OKVIS (2015) 双目 + IMU 紧耦合滑窗优化 早期 VIO 经典
MSCKF (2007) 单目 + IMU EKF 紧耦合 苹果 ARKit 据称用类似架构 (未官方确认)
ROVIO (2017) 单目 + IMU 迭代 EKF + 直接法 光度块匹配 + IMU
VINS-Mono/Fusion (2018-19) 单目/+ IMU/+ 双目/+ GPS 紧耦合 BA + 滑窗 港科机器人组开源
LOAM / LIO-SAM / FAST-LIO 激光 / + IMU 直接特征 + 紧耦合 激光 LIO 主流
R²/R³LIVE (2021-22) 激光 + 视觉 + IMU 多传感器紧耦合 港大 Mars Lab

演化趋势:滤波 → 优化 → 紧耦合多传感器;特征点 → 直接法 + 学习特征;稀疏 → 稠密 + 神经辐射场。

D. 评估与工程

D1. RPE / ATE / RMSE

SLAM 轨迹评估的三类指标:

ATE (Absolute Trajectory Error)

估计轨迹和真值轨迹全局对齐后的逐点欧氏距离:

ATEi=p^ipi\text{ATE}_i = \| \hat{p}_i - p_i \|
  • 衡量全局一致性 (有漂移的轨迹 ATE 会随时间增大)
  • 常用 ATE-RMSE = (1/N)ATEi2\sqrt{(1/N) \sum \text{ATE}_i^2}
  • 工具:evo (evo_ape), rpg_trajectory_evaluation

RPE (Relative Pose Error)

两个时刻间相对位姿的误差:

RPEi=log((T^i1T^i+Δ)1(Ti1Ti+Δ))\text{RPE}_i = \| \log\left( (\hat{T}_i^{-1} \hat{T}_{i+\Delta})^{-1} (T_i^{-1} T_{i+\Delta}) \right) \|
  • 衡量局部一致性 (短时间内的漂移率)
  • Δ\Delta 取 1 m / 1 s 等,反映里程计性能
  • ATE 测全局,RPE 测局部

RMSE (Root Mean Square Error)

通用统计指标:对一组误差求二次平均:

RMSE=1Niei2\text{RMSE} = \sqrt{\frac{1}{N} \sum_i e_i^2}

ATE 和 RPE 都可以求 RMSE,是它们的具体形式之一。

D2. BA Jacobian 维度

问题:10 个相机同时看到 100 个路标点,BA 优化的 Jacobian 矩阵多少维?

分析

  • 单个误差是 2D 重投影误差 (像素 u,vu, v)
  • 误差对相机位姿 (6 DOF) 的偏导:2×62 \times 6
  • 误差对路标点 (3 DOF) 的偏导:2×32 \times 3
  • 10 个相机各看到 100 点 → 总观测数 = 10×100=100010 \times 100 = 1000
  • 总行数 = 1000×2=20001000 \times 2 = 2000
  • 总列数 = 10×6+100×3=60+300=36010 \times 6 + 100 \times 3 = 60 + 300 = 360

Jacobian 维度 = 2000×3602000 \times 360,但是稀疏的:每行只有 6 + 3 = 9 个非零块 (一个相机 + 一个点)。

Schur 补利用这种结构:把路标变量边缘化掉,先解 6×66 \times 6 的相机块 (此时变成 60×6060 \times 60 的小系统),再回代解路标块。这就是 BA 能扩展到大规模 (千相机 + 万点) 的关键。

D3. g2o 类结构

g2o (General Graph Optimization) 是 SLAM 因子图优化的常用 C++ 框架。

核心类继承关系

HyperGraph (抽象超图)
  └── OptimizableGraph (可优化图)
        └── SparseOptimizer (实际用的稀疏优化器)

HyperGraph::Vertex (顶点抽象)
  └── BaseVertex<dim, T>  (固定维度 + 类型,泛型基类)
        └── VertexSE3, VertexPointXYZ, ... (具体实现)

HyperGraph::Edge (边抽象)
  └── BaseUnaryEdge<dim, MeasType, VertexType>  (一元边,如先验)
  └── BaseBinaryEdge<dim, MeasType, V1, V2>  (二元边,如 PnP / BA)
  └── BaseMultiEdge<dim, MeasType>  (多元边,少见)
        └── EdgeSE3, EdgeProjectXYZ2UV, ... (具体实现)

典型 BA 代码骨架

SparseOptimizer optimizer;
// 1. 添加顶点 (相机 SE3 + 路标 XYZ)
optimizer.addVertex(camera_vertex);
optimizer.addVertex(landmark_vertex);
// 2. 添加边 (观测约束)
optimizer.addEdge(reprojection_edge);
// 3. 初始化求解器 (Cholesky / Schur 补)
optimizer.setAlgorithm(new OptimizationAlgorithmLevenberg(...));
// 4. 优化
optimizer.initializeOptimization();
optimizer.optimize(num_iterations);

对比

  • Ceres:Google 出品,模板更现代,支持自动微分
  • GTSAM:因子图视角更清晰,支持 iSAM2 增量优化
  • g2o:最早开源,文档欠缺,但 ORB-SLAM 等老系统沿用

D4. 3D 地图点的存储与参数化

问题:SLAM 中地图点的几种参数化方式各有什么优缺点?

参数化 维度 优缺点 典型系统
3D Euclidean (X,Y,Z)(X, Y, Z) 3 直观;但远点 ZZ \to \infty 不可表示 ORB-SLAM
齐次坐标 (X,Y,Z,W)(X, Y, Z, W) 4 (1 自由度冗余) 可表示无穷远点;BA 中需特殊处理 一些 SfM 系统
逆深度 (u,v,1/Z)(u, v, 1/Z) 3 远点稳定 (1/Z01/Z \to 0);高斯近似更准;锚帧依赖 DSO, SVO, MSCKF 早期
方位 + 逆深度 (θ,ϕ,1/Z)(\theta, \phi, 1/Z) 3 等价于齐次但参数化更光滑 Civera 等
2D 直线 4 (Plücker) 线特征 SLAM (PL-SLAM, PL-VIO) 见 PL-VIO 论文

工程上:ORB-SLAM 系列用 3D Euclidean (远点直接剔除);DSO/SVO 用逆深度 (适合直接法);VINS-Mono 早期用逆深度 + 锚帧机制,后期改成混合策略。

D5. BA 中地图点为何收敛慢

现象:BA 优化时相机位姿迅速稳定,但部分地图点 (尤其远处的) 收敛很慢甚至发散。

原因

  1. 几何约束弱:远处地图点的视差小 → 重投影误差对深度变化不敏感 → 雅可比小 → 增量小
  2. 窄基线:多帧观测但位姿变化小,三角化条件差
  3. 初值差:DLT 三角化对噪声敏感,远点尤其
  4. 测量噪声:像素噪声对应到深度上的不确定性按 σZZ2/B\sigma_Z \propto Z^2/B 放大 (见 三角化 §6 不确定性)
  5. 外点拉扯:错误匹配点把地图点带偏

对策

  • 逆深度参数化:数值上让远点更稳
  • 筛掉低视差点:ORB-SLAM 要求至少 1° 视差
  • 鲁棒核函数 (Huber) 降低外点权重
  • 多次观测后才"成熟":SVO 深度滤波器思路
  • 固定可信地图点:仅优化新加入或不确定点

D6. IMU-相机外参标定

问题:求 Tcb=(Rcb,tcb)T_{cb} = (R_{cb}, t_{cb}) — 从 IMU body frame 到 camera frame 的刚体变换。

离线标定 (实验室)

  • Kalibr (Furgale et al. 2013):公认标准。Aprilgrid 标定板 + 摄像机 + IMU 同时记录数据 → 基于因子图的批量优化
  • 输入:相机内参 + 标定板尺寸 + 相机时间戳 + IMU 数据
  • 输出:相机内参 (可选)、相机间外参、IMU-相机外参、相机-IMU 时间偏移

在线标定 / 自标定

  • VINS-Mono/Fusion 启动时估初始外参;运行中如果观测充分继续更新
  • OpenVINS 把外参作为待估状态加入 MSCKF
  • 工程上:通常离线标定一次得粗值 → 在线缓慢优化

标定的可观性

外参 6 DOF:

  • 旋转部分 — 在大多数运动下可观
  • 平移部分 — 需要充足的旋转运动 (纯平移下不可观)
  • 时间偏移 — 需要高频运动激励

D7. ORB-SLAM 的四叉树特征均匀化

问题:原始 FAST 角点检测会在纹理丰富区域聚集大量特征点,纹理弱区域几乎没点 → 不利于位姿估计 (信息分布偏)。

ORB-SLAM 的解决:四叉树 (quadtree) 递归划分图像。

算法

1. 把整张图作为初始节点,已检测的 FAST 角点放进去
2. 维护节点队列,未达到目标特征数前循环:
   a. 取出节点中包含角点最多的那个
   b. 把它一分为四 (左上/右上/左下/右下)
   c. 把角点按位置分到子节点
   d. 删除空子节点
3. 当节点数 ≥ 目标特征数 K 时停止
4. 在每个最终节点内,保留响应值最大的那个角点

效果:图像被划分成大小自适应的网格 (信息密集区网格小、稀疏区网格大),最终每格保留一个角点 → 整张图角点分布均匀。

优势

  • 信息覆盖均匀 → 提高位姿估计鲁棒性
  • 减少特征冗余 (聚集的角点几乎共线,对 PnP 增益小)
  • 实现简单 (O(nlogn)O(n \log n))

D8. 二值图求最大连通域

经典图像处理题。

算法 1: 两次扫描法 (Two-Pass)

第一遍 (从上到下,从左到右):
    对每个白像素 p:
        检查 p 的上邻居和左邻居:
            若都为背景 → 给 p 一个新标签
            若只有一个有标签 → 复用该标签
            若两个都有标签且相同 → 复用
            若两个都有标签但不同 → 复用其一,记录两标签等价
        用并查集 (Union-Find) 维护等价关系

第二遍:
    把每个标签替换为它的等价类代表 (并查集 find)

复杂度 O(Nα(N))O(N \cdot \alpha(N))O(N)O(N)

算法 2: 种子填充 (Flood Fill)

DFS / BFS 从未访问的白像素开始扩展:

labels = zeros
current_label = 0
for each pixel p in image:
    if p is white and labels[p] == 0:
        current_label += 1
        queue = [p]
        while queue not empty:
            q = queue.pop()
            labels[q] = current_label
            for neighbor in 4-connected(q):
                if neighbor is white and labels[neighbor] == 0:
                    queue.push(neighbor)

求最大连通域

跑完任一算法后,计数每个 label 的像素数 → 取最大

OpenCV: cv::connectedComponentsWithStats 一行搞定 (内部用 Two-Pass),输出每个连通域的像素数。

D9. GPS + IMU 融合到 cm 级地图

问题:给消费级 GPS (米级误差) + 战术级 IMU,如何得到 cm 级精度的轨迹/地图?

单纯 GPS + IMU 难以做到 cm 级

  • 消费级 GPS 误差 ~5-10 m (C/A 码单点定位)
  • 战术级 IMU 零偏稳定性 ~1°/h,短时间可外推但长期发散
  • 直接松耦合 KF 融合也只能到亚米级,不够 cm

真正能做到 cm 级的几条路径

1. RTK-GPS (Real-Time Kinematic)

  • 基站 + 流动站 + 实时差分 + 载波相位
  • 开阔天空下 cm 级 (典型 1-3 cm 水平, 5 cm 垂直)
  • 城市峡谷/隧道严重退化
  • 必要时配 IMU 做 RTK 失效时段的桥接

2. GPS / IMU + 视觉 / 激光紧耦合

  • 在 RTK 基础上加 VIO 或 LIO,弥补 GPS 多路径 / 信号丢失
  • 典型组合:RTK-GNSS + 战术 IMU + LiDAR + 高精地图匹配
  • 代表系统:百度 Apollo, Mobileye REM, Tesla FSD (无 LiDAR)

3. PPK (Post-Processed Kinematic)

  • 离线后处理 — 数据记录后用基站后处理软件解算
  • 比 RTK 精度更高 (后向滤波 + 双向平滑)
  • 测绘/无人机航测主流

4. 高精地图匹配 (HD Map Localization)

  • 预制 cm 级精度的高精地图 (车道线、路标、建筑边缘)
  • 实时把传感器观测匹配到地图 → 位姿
  • 不要求实时 RTK;地图建设成本高
  • 代表:Apollo, Autoware, Waymo

关键工程要点

  • 时间同步:各传感器时间戳必须 sub-ms 对齐 (PTP / PPS)
  • 传感器外参标定:见 D6
  • 状态估计:因子图 + 紧耦合 (GTSAM, Ceres 都支持)
  • 失效检测:RTK fix → float → autonomous 的状态切换;GPS 多路径检测

简单回答:纯 GPS+IMU 到不了 cm,必须靠 RTK 或高精地图。

References