想象你是一家新开业商场的安全巡逻机器人“小安”。商场刚开张,还没有任何施工图纸。小安被推进入口的那一刻,必须同时完成两件事:一边用摄像头扫描走廊、立柱和门面,在脑中绘制一份商场地图;一边根据自己走过的路径,确认自己此刻站在地图上的哪个位置。这听起来像个死循环——要定位就得有地图,要有地图就得先知道自己站在哪里。这个“先有鸡还是先有蛋”的难题,正是 AR(增强现实)最核心的跟踪技术之一:SLAM(同步定位与建图)。 商场运营方还有两个辅助方案。一是提前在关键位置粘贴“定位贴纸”(标记),小安只要扫到一张贴纸,就能立刻判断自己到了哪个区域,又快又稳;二是当小安想把虚拟展示柜“放”到真实地板上时,得先找出哪块地面是平的、能站稳——这就是平面检测。手机里的 ARKit、ARCore 正是把小安的“找路 + 认路 + 找桌面”三样本领封装成了现成 API,让开发者不必从零编写定位算法。读完这篇文章,你会理解 AR 应用回答“我在哪、在看什么、把虚拟物体放哪”三大问题的完整套路。

岗位关联

学习 AR 跟踪(SLAM、标记与平面检测),你将掌握空间计算最底层的“定位—建图—放置”链路。这对从事 AR/VR 应用开发、空间计算产品设计或视觉算法优化的 AI 从业者来说,是理解整个 AR 技术栈的第一把钥匙。

目录
  1. 可视化演示
  2. SLAM 核心原理:一边画地图一边找自己
  3. SLAM 工作流程:摸黑巡场的四步心法
  4. 标记跟踪原理:商场的定位贴纸
  5. 平面检测机制:给虚拟家具找一张桌子
  6. ARKit 与 ARCore:把本领打包成工具箱
  7. 6自由度位姿:六个数字定全局
  8. 应用与优化:从逛商场到开工干活
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

SLAM 核心原理:一边画地图一边找自己

小安被蒙着眼送进商场。它每走一步,只能靠摄像头辨认墙面纹理和柱子轮廓来感知周围,可它想画一张准确的商场地图,就得知道自己在哪;想知道自己在哪,又得先有一张准确的地图。SLAM(Simultaneous Localization and Mapping,同步定位与建图)的设计哲学正是:不逃避这个循环,而是用概率的方式同时求解,让“位置猜测”和“地图猜测”互相纠正,在走动中逐步收敛。

把这一步翻译成数学语言:SLAM 求解的是一个联合后验概率——在已知所有观测和运动指令的条件下,机器人的整条轨迹和整张地图同时最可信。真实系统无法精确计算这个分布,于是用扩展卡尔曼滤波(EKF)或图优化(Factor Graph)做近似:EKF 用高斯分布逐步传递不确定性,图优化则把历史所有观测建成一张“约束图”批量调整。

所以小安并不需要一进场就先拿到图纸。它只需把“我刚才大概走了几步、看到了什么”不断叠加进概率框架——每走一步,地图和位置同步修正一点。就像人在暗屋里摸黑前行:摸到一把椅子,既更新了“椅子在哪”的记忆,也更新了“我在哪”的判断。

P(x1:t,m∣z1:t,u1:t)\displaystyle P(x_{1:t}, m \mid z_{1:t}, u_{1:t})
这个公式说明“定位”和“建图”在概率上是一体的:估计地图时以轨迹为条件,估计轨迹时以地图为条件,两者交替精化。这正是 SLAM 区别于“先建图再定位”的核心设计。
  1. 下标 1t:表示从第 1 时刻到第 t 时刻的连续序列,而不是某一帧快照——SLAM 的本质是利用整个历史来消除单帧误差。
    x1:t={x1,x2,…,xt}\displaystyle x_{1:t} = \{ x_1, x_2, \ldots, x_t \}
  2. x 轨迹小安每个时刻的六自由度位姿(位置加朝向),是公式里待求的主角。
    xt=[x,y,z,roll,pitch,yaw]x_t = [x, y, z, \text{roll}, \text{pitch}, \text{yaw}]
  3. m 地图商场里所有立柱、门牌等路标点的三维坐标集合,构成环境模型。
    m={m1,m2,…,mN},mi∈R3m = \{ m_1, m_2, \ldots, m_N \}, \quad m_i \in \mathbb{R}^3
  4. z 观测小安的眼睛(相机)每帧检测到的特征点在图像中的像素位置。
    zt={zt,1,zt,2,…},zt,i=[u,v]⊤z_t = \{ z_{t,1}, z_{t,2}, \ldots \}, \quad z_{t,i} = [u, v]^\top
  5. u 控制输入小安“这一脚迈了多远、朝哪个方向”,来自惯性传感器或光流估计。
    ut=[Δx,Δy,Δθ]⊤u_t = [\Delta x, \Delta y, \Delta \theta]^\top
  6. 后验概率 P给定所有观测与控制之后,轨迹和地图的联合可信度,值越大代表估计越靠谱。

SLAM 工作流程:摸黑巡场的四步心法

小安在商场里巡场的具体动作可以拆成四步。第一步是认出特征点:柱子上的花纹、招牌的边角,这些在图像里对比度鲜明、容易追踪的“锚点”;第二步是帧间匹配:判断这一帧里的某个特征点和上一帧的哪个点是同一个,就像黑暗中摸到同一张桌角;第三步是位姿估计:用匹配关系反推自己这两帧之间怎么移动的;第四步是回环检测:当小安绕了一圈回到入口,发现记忆里的门廊和当前画面没对齐,就把积累的偏移一次性压平。

技术上,位姿估计是一个典型的非线性最小二乘问题,也叫光束法平差(Bundle Adjustment)。小安每换一个姿势,就预估“我若站在这里,应该看到门牌在那个像素位置”,然后和真实照片比对,反复微调直到预测和实际对不上为止。

每次“预测—比较—修正”的循环闭合,小安对世界的感知就精确一分;而回环检测则是它的“终极大招”:绕场一周回到起点,用首尾呼应的场景把整个商场地图重新对齐,消除长时间行走累积的漂移误差。

x^=arg⁡min⁡x∑i=1N∥hi(x)−zi∥2\displaystyle \hat{x} = \mathop{\arg\min}_{x} \sum_{i=1}^{N} \| h_i(x) - z_i \|^2
通俗地讲:在茫茫多的候选位姿里,挑一个能让“我预计看到的世界”与“相机真正拍到的世界”整体偏差最小的答案。偏差越小,跟踪越稳。
  1. 预测模型 h_i(x)按当前猜测的位姿 x,把第 i 个路标的三维坐标投影到图像上得到的预测像素位置,相当于小安“脑补”的画面。
    hi(x)=π(T(x)⋅Mi)\displaystyle h_i(x) = \pi( T(x) \cdot M_i )
  2. 实际观测 z_i相机真实拍到的该路标像素坐标,是“亲眼所见”的证据。
    zi=[ui,vi]⊤z_i = [u_i, v_i]^\top
  3. 平方范数预测像素与实际像素之间的几何差距,衡量“猜得准不准”的距离计。
    ∥hi(x)−zi∥2\displaystyle \| h_i(x) - z_i \|^2
  4. argmin 最优估计在所有可能位姿中挑出使总误差最小的那一个,是“最优猜测”的数学表达。
    x^=arg⁡min⁡x(⋯ )\displaystyle \hat{x} = \mathop{\arg\min}_{x} (\cdots)
  5. 求和 Σ把当前帧所有被观察到的特征点的误差都累加起来,让单个误匹配的坏影响被全局稀释。

标记跟踪原理:商场的定位贴纸

SLAM 是“蒙眼摸黑建地图”,标记跟踪则是“读贴纸认路”。商场运营方提前在柱子、柜台和通道口贴上特制的“定位贴纸”——它们不是普通二维码,而是专为视觉定位设计的矩阵标记(如 ARToolKit、ArUco 标记),内部编码了唯一 ID 和精确角点图案。小安只要在画面里认出一张贴纸,就相当于拿到了一个“已知坐标的路标”:因为贴纸贴在哪、朝向如何,在部署时早就记录在案。

标记跟踪最迷人的地方在于“即时注册”:不需要像 SLAM 那样花时间建图,看到即定位。它的几何本质是把标记平面上的一个点映射到图像像素,需要的是一个 3×3 的单应矩阵(Homography)H。标记的四个角点在标记坐标系下的坐标是已知的,在图像里的坐标是检测出来的,这四组对应点足以解出 H,再从 H 中分解出相机相对标记的六自由度位姿。

贴纸就是“已知地图上的锚点”。它的缺点是商场得事先张贴、不能覆盖整个空间;优点是快、准、稳,而且所有设备看到同一张贴纸就共享同一个坐标系——这在多人协作 AR、工业巡检和展馆导览里非常实用。SLAM 与标记跟踪不是替代关系,而是互补关系。

[uv1]∼H[XY1],H=K [ r1  r2  t ]\displaystyle\begin{bmatrix} u \\ v \\ 1 \end{bmatrix}\sim\mathbf{H}\begin{bmatrix} X \\ Y \\ 1 \end{bmatrix},\qquad\mathbf{H} = \mathbf{K} \, [\, \mathbf{r}_1 \; \mathbf{r}_2 \; \mathbf{t} \,]
约等号表示“相差一个尺度因子”:单应矩阵允许整体缩放而不改变几何意义。解出 H 后,拆出旋转列向量 r₁、r₂ 和平移向量 t,就得到了 AR 需要的相机位姿。
  1. 齐次像素坐标标记角点在相机图像里的像素位置,由检测算法从画面中提取。
    [u,v,1]⊤\displaystyle [u, v, 1]^\top
  2. 平面坐标角点在标记自身坐标系下的坐标——因为图案是预定义好的,这四个点的位置是“已知答案”。
    [X,Y,1]⊤\displaystyle [X, Y, 1]^\top
  3. 约等于(尺度)像素坐标与平面坐标之间差一个未知缩放因子,不影响后续位姿分解。
    ∼\displaystyle \sim
  4. 单应矩阵 H沟通“标记平面”与“相机图像”两个平面之间投影关系的 3×3 矩阵,是标记跟踪的核心枢纽。
    H∈R3×3\displaystyle \mathbf{H} \in \mathbb{R}^{3 \times 3}
  5. 内参 K相机焦距、光心等固有属性,出厂前标定好,代表“这只眼睛长什么样”。
    K=[fx0cx0fycy001]\displaystyle \mathbf{K} = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}
  6. 外参分解r₁、r₂ 是旋转矩阵的两列,t 是平移,合起来正好是小安相对贴纸的位置与朝向。

平面检测机制:给虚拟家具找一张桌子

假设小安现在要把一个虚拟展示柜“放到”商场中庭的地板上。它不能随手一放——万一那里是台阶或斜坡,虚拟柜子就会“穿模”或悬空。真实生活里,我们放咖啡杯前会先扫一眼桌面:哪块区域足够平、足够大、能站稳。平面检测(Plane Detection)就是把这个人类直觉翻译给机器。

手机或 AR 眼镜先通过深度传感器(如 LiDAR)或多视角立体视觉,得到场景中大量三维点,这些点构成“点云”。平面检测的目标,就是从这堆杂乱的点里找出一块平整区域,并用一个数学平面来描述它。判断“足够平整”的方法是:所有内点到这个平面的距离平方和最小。这个优化问题的解,恰好由点云协方差矩阵的 SVD(奇异值分解)给出——最小奇异值对应的特征向量就是平面法向量 n。

得到平面后,系统把法向量 n 与重力方向(由 IMU 提供)比较:若两者平行,就是水平面(地面、桌面);若垂直,就是竖直面(墙面、门面)。AR 引擎随后在平面上建立一个“锚点”(Anchor),虚拟展示柜就被钉在这个锚点上,随着小安走动和转身保持稳定的空间位置。

n⋅p+d=0,min⁡n,d∑i=1N(n⋅pi+d)2s.t.∥n∥=1\displaystyle\mathbf{n} \cdot \mathbf{p} + d = 0,\qquad\min_{\mathbf{n}, d} \sum_{i=1}^{N} \left( \mathbf{n} \cdot \mathbf{p}_i + d \right)^2\quad \text{s.t.} \quad \| \mathbf{n} \| = 1
第一个式子是一般平面方程:n 是法向量,d 是平面到原点的距离;第二个式子是拟合准则:让所有点尽量贴近平面。约束 ||n||=1 防止“法向量为零”的平凡解。
  1. 法向量 n垂直于点云拟合平面的单位向量,它同时决定了平面是“躺着”还是“站着”。
    n=[nx,ny,nz]⊤,∥n∥=1\displaystyle \mathbf{n} = [n_x, n_y, n_z]^\top, \quad \|\mathbf{n}\| = 1
  2. 点云点 p_i深度传感器测到的物理表面上某个三维点,是平面检测的原始原料。
    pi=[xi,yi,zi]⊤\displaystyle p_i = [x_i, y_i, z_i]^\top
  3. 截距 d平面到世界坐标系原点的带符号距离,配合 n 唯一确定一个平面。
    d=− n⋅pˉ\displaystyle d = -\, \mathbf{n} \cdot \bar{p}
  4. 约束条件规定法向量长度为 1,使目标函数存在唯一非零解,也能保证距离计算有物理意义。
    ∥n∥=1\displaystyle \| \mathbf{n} \| = 1
  5. 误差平方和每个点到平面的垂直距离平方累加,衡量“这块区域到底有多平”。

ARKit 与 ARCore:把本领打包成工具箱

小安的“找路 + 认路 + 找桌面”三样本领,被苹果和谷歌分别装进了两个官方工具箱:ARKit(iOS)和 ARCore(Android)。这两个框架把 SLAM 跟踪、标记识别、平面检测、环境光估计和锚点管理全部封装成几行 API。开发者不需要自己写特征点提取、不需要自己解单应矩阵,只需要声明“我要检测水平面”,然后在回调里拿到锚点,把 3D 模型挂上去即可。

两大平台的能力几乎一一对应:ARKit 的 World Tracking 对应 ARCore 的 Motion Tracking,本质上都是“单目相机 + IMU”的视觉惯性 SLAM;ARKit 的 Image Anchors 对应 ARCore 的 Augmented Images,实现标记跟踪;两者都支持水平面和竖直面检测。跨平台开发通常借助 Unity 的 AR Foundation 或其他跨平台方案,一套代码同时输出到 iOS 和 Android。框架每帧输出的核心成果,是一张相机位姿矩阵 T,它把虚拟物体的世界坐标变换到相机坐标系:

工具箱虽好用,但开发者仍需理解底层原理:为什么低光下虚拟物体漂移?为什么快速移动时杯子“飞走”?这些问题的答案藏在 SLAM 的特征点和位姿优化里。框架封装的是能力,不是思维豁免权。

[XcYcZc1]=Twc−1[XwYwZw1]\displaystyle\begin{bmatrix} X_c \\ Y_c \\ Z_c \\ 1 \end{bmatrix}=T_{wc}^{-1}\begin{bmatrix} X_w \\ Y_w \\ Z_w \\ 1 \end{bmatrix}
渲染引擎拿到这张矩阵后,把桌子上的虚拟咖啡杯从“世界坐标”搬到“相机坐标”,再经过投影就显示在屏幕正确位置。SLAM 每帧输出新矩阵,杯子就稳稳“粘”在桌面上。
  1. 齐次坐标普通三维点末尾补一个 1,变成四维向量,让平移也能用矩阵乘法统一表达。
    [X,Y,Z,1]⊤\displaystyle [X, Y, Z, 1]^\top
  2. 相机位姿逆矩阵SLAM 估计的是“世界到相机”的变换,求逆后恰好把世界点搬到相机坐标系。
    Twc−1=[R⊤−R⊤t01]\displaystyle T_{wc}^{-1} = \begin{bmatrix} R^\top & -R^\top t \\ 0 & 1 \end{bmatrix}
  3. 世界坐标虚拟物体锚点在全球(或会话)坐标系里的位置,由平面锚点提供。
    Pw=[Xw,Yw,Zw,1]⊤\displaystyle P_w = [X_w, Y_w, Z_w, 1]^\top
  4. 相机坐标以相机光心为原点、光轴为 z 轴的坐标系下的坐标,是渲染管线的标准输入。
    Pc=[Xc,Yc,Zc,1]⊤\displaystyle P_c = [X_c, Y_c, Z_c, 1]^\top
  5. 逐帧刷新SLAM 每帧估计出新位姿,矩阵随之更新——这正是“跟踪”二字的动态含义。

6自由度位姿:六个数字定全局

“小安在哪”这个问题,其实包含两个子问题:在哪个位置(坐标),面朝哪个方向(朝向)。两个子问题加起来,正好是六个自由度数——3 个平移自由度(x、y、z)加上 3 个旋转自由度(roll 横滚、pitch 俯仰、yaw 偏航),缩写为 6DOF(Six Degrees of Freedom)。任何刚性物体在空间中的位置和朝向,都需要这六个数字才能唯一确定。

4×4 齐次变换矩阵是描述六自由度位姿的“标准容器”:左上角是 3×3 旋转矩阵 R 编码三个旋转角,右上角是 3×1 平移向量 t 编码三个位移,最后一行固定为 [0 0 0 1]。旋转矩阵虽然是 9 个数字,但受“正交 + 行列式为 1”约束,实际独立参数只有 3 个;加上平移的 3 个,正好 6 个独立数字,不多不少。

SLAM、标记跟踪和平面检测最终都要汇入这六个数字:SLAM 输出的是相机在世界里的六自由度位姿,标记跟踪输出的也是相机相对贴纸的六自由度位姿,平面锚点则存储了平面在世界里的六自由度位置。虚实能不能严丝合缝地对齐,全看这六个数字准不准。

T=[r11r12r13txr21r22r23tyr31r32r33tz0001]\displaystyle\mathbf{T} =\begin{bmatrix}r_{11} & r_{12} & r_{13} & t_x \\r_{21} & r_{22} & r_{23} & t_y \\r_{31} & r_{32} & r_{33} & t_z \\0 & 0 & 0 & 1\end{bmatrix}
简单理解:这张 4×4 矩阵就是小安在三维世界里的“身份证”。旋转负责回答“脸朝哪、头歪没歪”,平移负责回答“站在哪、离多远”。
  1. 旋转矩阵 R3×3 正交矩阵,行列式为 1,编码 roll、pitch、yaw 三个旋转角。
    R=Rz(yaw) Ry(pitch) Rx(roll)\displaystyle \mathbf{R} = \mathbf{R}_z(\text{yaw}) \, \mathbf{R}_y(\text{pitch}) \, \mathbf{R}_x(\text{roll})
  2. 平移向量 t设备(相机)相对世界坐标系原点的三维位移。
    t=[tx,ty,tz]⊤t = [t_x, t_y, t_z]^\top
  3. 齐次行 [0 0 0 1]矩阵的固定底盘结构,让旋转和平移能统一写成一次矩阵乘法,方便连乘。
    [0  0  0  1]\displaystyle [0 \; 0 \; 0 \; 1]
  4. 矩阵乘法变换点用 T 乘以一个齐次三维点,一次性完成“旋转 + 平移”。
    P′=T⋅P\displaystyle P' = \mathbf{T} \cdot P
  5. 六个独立自由度9 个旋转元素受正交约束缩减为 3,加 3 个平移元素,合计 6 个有效数字。

应用与优化:从逛商场到开工干活

当小安在商场里练就的“找路、认路、找桌面”的本领走出商场,就变成了今天各种 AR 应用的基础。在家装 App 里,用户举起手机对准客厅,平面检测找到地面,虚拟沙发就“站”在地板上;在仓储物流中,AR 眼镜读取货架上的标记完成瞬时注册,再靠 SLAM 持续跟踪,在地面绘制导航箭头;在机器人领域,扫地机和配送机器人用同样的视觉/激光 SLAM 技术构建户型图并实时定位——AR 与机器人共享同一套空间计算内核。

任何跟踪系统都会出错,所以工程上必须有一个“质量仪表盘”来衡量跟踪靠不靠谱。最常用的指标是重投影误差(Reprojection Error):把地图里的三维特征点按当前位姿投影回图像,再和真实检测到的像素位置比较。两者偏差小,说明跟踪质量高;偏差大,说明位姿估计可能在“放飞自我”。

鲁棒性策略是工程落地的最后一道防线。低光照会让特征点变少,白墙等无纹理区域让匹配无从下手,快速甩动手机产生运动模糊,地面重复花纹造成匹配歧义——这些都需要 IMU 融合、回环检测、多传感器冗余来兜底。小安从“能在商场逛”到“在各种刁钻环境里都能干活”,靠的正是这一整套监控与补救机制。

\displaystyleE = \frac{1}{N} \sum_{i=1}^{N} \left\| z_i - \pi(\mathbf{T} \cdot P_i) \right\|^2
重投影误差就是“脑补画面与真实画面的像素差距平均值”。当 E 超过阈值,AR 引擎会暂停渲染虚拟物体或触发重新定位,而不是把错误画面硬画出来。
  1. 相机投影函数 π把三维点映射到像素坐标的数学相机模型,内参 K 参与其中。
    π(Pc)=[fxXcZc+cx,  fyYcZc+cy]⊤\displaystyle \pi(P_c) = \left[ f_x \frac{X_c}{Z_c} + c_x, \; f_y \frac{Y_c}{Z_c} + c_y \right]^\top
  2. 位姿变换 T·P_i把地图中的第 i 个三维特征点按当前位姿变换到相机坐标系。
    Pc=T⋅Pi\displaystyle P_c = \mathbf{T} \cdot P_i
  3. 真实观测 z_i相机图像里实际检测到的该特征点像素,是“事实”。
    zi=[ui,vi]⊤\displaystyle z_i = [u_i, v_i]^\top
  4. 误差均值 E把 N 个特征点的像素偏差平方后取平均,得到单帧跟踪质量得分。
    E=1N∑i=1N∥⋅∥2\displaystyle E = \frac{1}{N} \sum_{i=1}^{N} \| \cdot \|^2
  5. 阈值判决E 超过安全线说明跟踪丢失或漂移严重,系统转入兜底策略(冻结渲染、重新定位)。

AI 应用场景

AR 家装与虚拟陈列

阶段:平面检测 + 锚点注册

解决的问题:传统家居购买无法预知家具尺寸、颜色与自家空间是否匹配。AR 应用通过平面检测识别地板和桌面,沿重力方向放置等比例 3D 模型;SLAM 持续跟踪相机位姿,保证用户绕圈查看时沙发纹丝不动。相比“凭感觉想象”和“画图量尺”,AR 把决策成本降到零。

具体案例:用户在客厅举起手机,ARCore 在 1 秒内检测出水平地面,返回锚点;虚拟双人沙发出现在地毯中央,用户边走边看各角度,最终确认尺寸风格合适再下单。

仓储 AR 拣货导航

阶段:标记跟踪 + SLAM 实时定位

解决的问题:大型仓库拣货员找货耗时且易出错。在货架关键位置粘贴标记,AR 眼镜读取标记完成瞬时注册,建立共享坐标系;随后依靠 SLAM 连续跟踪,在视野中绘制地面导航箭头,并叠加目标货架的货位信息,把“找”的过程变成“跟”的过程。

具体案例:某电商仓配中心为拣货员配备 AR 眼镜后,拣货效率提升约 25%,错拣率显著下降;新员工培训时间从两周缩短到两天。

机器人室内自主导航

阶段:SLAM 定位建图 + 平面检测

解决的问题:室内没有 GPS 信号,扫地机器人或配送机器人必须先回答“我在哪”。机器人使用激光或视觉 SLAM 构建户型图同时定位自身,平面检测辅助识别门槛、地毯边界和桌面区域,让清扫路径规划更合理。

具体案例:家用扫地机器人沿墙扫描完成建图,App 端显示可编辑的房间分区图;用户圈出“厨房”区域,机器人据此规划重点清扫路线。

Python 演示

python53 行
import numpy as np  def generate_plane_points(n=200, w=4.0, h=3.0, noise=0.03, outlier_ratio=0.05, seed=42):    """模拟深度相机在桌面上测得的点云:平面点加少量离群噪声。"""    rng = np.random.default_rng(seed)    xs = rng.uniform(-w / 2, w / 2, n)    ys = rng.uniform(-h / 2, h / 2, n)    zs = rng.normal(0, noise, n)    points = np.stack([xs, ys, zs], axis=1)    outlier_n = int(n * outlier_ratio)    idx = rng.choice(n, outlier_n, replace=False)    points[idx] += rng.normal(0, 0.3, (outlier_n, 3))    return points  def fit_plane_svd(points):    """用 SVD 最小二乘拟合平面,返回法向量与截距。"""    centroid = points.mean(axis=0)    _, _, vt = np.linalg.svd(points - centroid)    normal = vt[-1]    d = -np.dot(normal, centroid)    return normal, d  def fit_plane_ransac(points, iters=300, threshold=0.05, seed=0):    """RANSAC 剔除离群点后拟合平面,返回平面参数与内点掩码。"""    rng = np.random.default_rng(seed)    best_mask = np.zeros(len(points), dtype=bool)    for _ in range(iters):        idx = rng.choice(len(points), 3, replace=False)        normal, d = fit_plane_svd(points[idx])        dist = np.abs(points @ normal + d)        mask = dist < threshold        if mask.sum() > best_mask.sum():            best_mask = mask    normal, d = fit_plane_svd(points[best_mask])    return normal, d, best_mask  def place_virtual_object(normal, d, obj_size=0.25):    """把虚拟物体的锚点放在桌面正上方 obj_size 处。"""    anchor = -d * normal    return anchor + normal * obj_size  if __name__ == "__main__":    points = generate_plane_points()    normal, d, mask = fit_plane_ransac(points)    anchor = place_virtual_object(normal, d)    print("检测到平面: %.3f x + %.3f y + %.3f z + %.3f = 0" % (normal[0], normal[1], normal[2], d))    print("内点数:", int(mask.sum()), "/", len(points))    print("虚拟物体锚点:", np.round(anchor, 3))
目的:用 RANSAC + SVD 从带噪声的点云中检测水平桌面,并计算虚拟物体的放置锚点——这是 ARCore/ARKit 平面检测的核心数学原型。
  1. points - centroid把点云平移到质心,让 SVD 能分离出“法向量方向”与“平面内方向”。
  2. vt[-1]SVD 分解后,最小奇异值对应的右奇异向量就是平面法向量,这是最小二乘平面拟合的经典结论。
  3. rng.choice(len(points), 3, replace=False)RANSAC 每次随机抽 3 个点确定一个候选平面,像“三个点支起一块板”。
  4. points @ normal + d向量化计算所有点到候选平面的带符号距离,一次矩阵乘法完成批量投票。
  5. mask.sum() > best_mask.sum()保留内点最多的一次采样,逐步逼近“最像桌面”的平面。
  6. anchor + normal * obj_size沿法线把锚点抬升 obj_size,虚拟物体才刚好“站在”桌面上而不是陷进去。

常见误区

误区我一直以为 SLAM 的“建图”是第一步,得先把整个环境扫描建模好,然后才能谈定位,就像手机导航要先下载离线地图一样。

正解SLAM 的定位与建图是同时进行的,没有先后之分。设备一开始对地图一无所知,它靠概率框架让地图估计和位姿估计互相约束、交替精化。就像小安蒙眼探索商场,每走一步都在同时更新地图和位置。关键区分是:已知地图时的定位叫“纯定位”(如标记跟踪),未知地图时的定位才叫 SLAM。

为何常见:日常导航软件确实是“先有地图再定位”,“同步”这个同时性概念违背大多数人的直觉。

误区现在 AR 都宣传“无标记 6DOF 跟踪”,标记跟踪还要贴贴纸,又丑又麻烦,肯定会被 SLAM 完全淘汰。

正解SLAM 在弱纹理、重复纹理场景下容易漂移;标记是已知图案,角点精度可达亚像素级,几十毫秒就能完成位姿求解,而且天然支持多设备共享同一坐标系。在工业维修、展馆导览、产线定位等受控场景中,标记跟踪依然是高性价比选择。两者是互补关系,不是替代关系。

为何常见:厂商宣传总强调“无标记”更酷,忽略了标记在稳定性和共享坐标系上的工程优势。

误区平面检测嘛,应该就是相机在画面里找一块颜色均匀的区域,比如一面白墙,然后判定它是平面。

正解平面检测基于三维点云——来自深度传感器或立体视觉,算法拟合的是空间中点的几何平面(平面方程 n·p+d=0),衡量的是点到平面的距离残差,而不是图像颜色。一张画满涂鸦的桌面只要几何平整照样能被检测为平面;一面纯白但凹凸不平的墙反而检测不出来。

为何常见:AR 引擎把检测结果画成带边缘高亮的半透明区域,看起来像“图像分割”,让人误以为依据是颜色或纹理。

误区框架都封装好了,我只要设置 planeDetection = .horizontal 然后写 UI 就行,完全不需要懂 SLAM、单应矩阵这些底层知识。

正解框架确实降低了门槛,但调试、优化和避坑离不开底层认知:为什么低光照下虚拟物体漂移?为什么平面会“滑动”?锚点应该在什么时机创建?如何用重投影误差判断跟踪是否可靠?这些都需要理解 SLAM 特征点、平面拟合和位姿优化的原理。框架是封装的 API,不是思维豁免权。

为何常见:现代 SDK 的 API 设计极其友好,几行代码就能跑通 Demo,掩盖了背后的算法复杂度,让人产生“调包即可”的错觉。

面试题

Q1. SLAM 中的 S 代表哪个英文单词?

单选题 · easy

  • A.Simultaneous← 正确答案
  • B.Sequential
  • C.Synthesized
  • D.Sensational

答案:A。SLAM 全称是 Simultaneous Localization and Mapping,即同步定位与建图。S 强调“同时”,核心是让定位与建图在概率框架里互相纠错。Sequential(顺序)、Synthesized(合成)、Sensational(轰动)都不是这里的原意。

Q2. 标记跟踪相比 SLAM 的最大优势是什么?

单选题 · easy

  • A.无需预先地图且鲁棒性强← 正确答案
  • B.需要复杂点云拟合算法
  • C.必须依赖无线网络定位
  • D.完全替代平面检测技术

答案:A。标记是已知图案,看到标记就相当于拿到“固定路标”,无需像 SLAM 那样边探索边建图,因此启动快、鲁棒、计算量小。点云拟合是平面检测的手段,标记跟踪不依赖无线网络,也不能替代平面检测——它们解决的是不同问题。

Q3. 平面检测中判断检测面是水平还是垂直,主要依据是什么?

单选题 · mid

  • A.平面颜色的深浅
  • B.法向量与重力夹角← 正确答案
  • C.平面反射光的强弱
  • D.检测到平面的面积

答案:B。平面法向量 n 是平面方程的核心输出。将 n 与 IMU 提供的重力方向比较:两者近平行则为水平面(地面/桌面),近垂直则为竖直面(墙面)。颜色、反射光强度、面积都不是几何层面的判定依据。

Q4. 标记跟踪中,由标记四个已知角点解出的是哪个矩阵?

单选题 · mid

  • A.本质矩阵 E
  • B.单应矩阵 H← 正确答案
  • C.基础矩阵 F
  • D.协方差矩阵 Σ

答案:B。标记是平面图案,平面到图像的映射用 3×3 单应矩阵 H 描述,四个角点给出四组对应点即可解出 H,再分解出相机位姿。本质矩阵 E 和基础矩阵 F 属于双目对极几何,适用于非平面点的多视角约束,而不是单个平面到单目图像。

Q5. SLAM 工作流程通常包含以下哪些环节?

多选题 · mid

  • A.特征提取与帧间匹配← 正确答案
  • B.位姿优化与回环检测← 正确答案
  • C.写入云端历史数据库
  • D.实时渲染虚拟三维模型

答案:AB。SLAM 的标准流程是:特征提取 → 帧间匹配 → 位姿优化(光束法平差)→ 回环检测修正漂移。写入云端数据库是可选后端功能,实时渲染虚拟模型属于 AR 渲染管线,两者都不是 SLAM 跟踪的必要环节。

Q6. ARKit 和 ARCore 的核心作用是什么?

单选题 · easy

  • A.渲染 3D 模型材质的离线烘焙
  • B.封装跟踪与平面检测能力← 正确答案
  • C.替代操作系统管理应用程序内存
  • D.为手机生成触觉反馈信号

答案:B。ARKit 与 ARCore 把 SLAM 跟踪、标记识别、平面检测、环境光估计、锚点管理封装成 API,开发者直接调用即可构建 AR 应用。它们不负责离线材质烘焙、系统内存管理或触觉反馈,那些属于渲染引擎、操作系统和硬件层的职责。

Q7. 关于 SLAM 的“鸡生蛋”难题,以下说法正确的有?

多选题 · hard

  • A.定位需要地图,建图需要位姿← 正确答案
  • B.概率框架可同时估计两者← 正确答案
  • C.已知地图时退化为纯定位问题← 正确答案
  • D.标记跟踪是典型的 SLAM 解法

答案:ABC。SLAM 的难点正是定位与建图互相依赖,EKF 和图优化用概率方法同时估计两者;若地图已知,问题就简化为纯定位(如标记跟踪),故 C 正确。标记跟踪假设地图(贴纸位置)已知,不属于“同步建图+定位”的 SLAM,D 错误。

Q8. 六自由度位姿中“六”指的是什么?

单选题 · mid

  • A.六个摄像头协同工作
  • B.三个平移自由度加三个旋转← 正确答案
  • C.六条回环检测的执行路径
  • D.六个关键帧参与全局优化

答案:B。6DOF = 3 个平移自由度(x、y、z)+ 3 个旋转自由度(roll、pitch、yaw),正好描述一个刚体在三维空间中的位置和朝向。它与摄像头数量、回环路径数量、关键帧数量没有关系。

Q9. 以下哪些情况会降低视觉 SLAM 的跟踪稳定性?

多选题 · hard

  • A.低光照导致特征点减少← 正确答案
  • B.白墙等无纹理区域较多← 正确答案
  • C.快速甩动手机产生模糊← 正确答案
  • D.地面存在大量重复花纹← 正确答案

答案:ABCD。低光照使特征点稀少,白墙无纹理导致帧间匹配失败,快速运动造成运动模糊,重复花纹(如方格地砖)造成匹配歧义——这四者都是视觉 SLAM 的经典难题。工程上通常用 IMU 融合、回环检测、特征点质量筛选等策略应对。

Q10. 标记平面上一点 P=[X,Y,1]ᵀ 映射到图像像素 p=[u,v,1]ᵀ,正确的数学关系是?

单选题 · extreme

  • A.p = K·R·P,K 为相机内参
  • B.p ∼ H·P,H 为单应矩阵← 正确答案
  • C.p = E·P,E 为本质矩阵
  • D.p = F·P,F 为基础矩阵

答案:B。平面到平面的映射用单应矩阵 H,且相差一个尺度因子;H=K[r₁ r₂ t],可分解出相机相对标记的位姿。选项 A 的 K·R 只含旋转不含平移,选项 C、D 的 E、F 属于对极几何的非平面点约束,均不适用于“单目相机观察单个平面标记”的场景。