点云配准
把一片点云对齐到另一片上,输出 4×4 变换矩阵。算法用 KISS-Matcher 的流程(FPFH + 图剪枝)和 TEASER++ 的鲁棒求解(GNC-TLS + COTE),不需要初始位姿,也不需要装任何东西。
源点云(待配准)
要被移动的那一片。输出的矩阵作用在它身上。
还没加载
目标点云(参考)
保持不动的参考系。
还没加载
配准参数
默认值按点云尺寸自动推算。体素是最关键的旋钮:它同时决定关键点数量、描述子邻域和噪声上界。
两个最近邻太接近时丢掉这个匹配。重复结构(走廊、栅栏)里能砍掉大量错配。
在鲁棒解之后再跑一次最近邻 ICP,通常能把残差再压低一个量级。
变换矩阵 T(源 → 目标)
行优先,p_target = T · p_source。可直接粘贴到「点云坐标系转换」里用。
怎么用
- 源点云放进左边(会被移动),目标点云放进右边(参考系保持不动)。
- 体素边长会自动填好;两片点云重叠区域大、有几何纹理就不用改。
- 点「开始配准」,等结果出来看一眼重合度和 RMSE。
- 要的话下载对齐后的点云,或者把 4×4 矩阵粘到「点云坐标系转换」里继续处理。
算法:KISS-Matcher 的流程 + TEASER++ 的求解器
配准这件事的难点不在「解方程」,而在「对应点里有大量是错的」。逐点最近邻匹配在实测数据里错配率常常过半,直接用最小二乘求解会被离群点带飞到完全错误的位置。所以整条链路的关键是先把错的对应点筛掉,再在剩下的点上求位姿。
- 体素降采样:按体素边长把点云抽稀成关键点,同时把噪声上界定下来(KISS-Matcher 里所有阈值都是体素的倍数)。
- FPFH 33 维描述子:每个关键点用一个局部几何直方图表示,转过来、挪过去,描述子的值不变 —— 这正是它能跨视角匹配的原因。
- 互检匹配 + 比值检验:源到目标、目标到源两个方向都成立才留下,两个最近邻太接近时丢掉。走廊、栅栏这类重复结构里,这一步能砍掉大部分错配。
- 图剪枝(ROBIN 的 max-core):把「距离关系互相一致」的对应点连成图,取最大 k-核。真的对应点彼此之间的距离差只在噪声量级,错误对应几乎不可能同时满足,于是在图上落到低核层被剪掉。
- GNC-TLS 求旋转:在相邻对应点构成的差分(TIM)上做逐步收紧的截断最小二乘,唯一解由 SVD 给出,权重在内外点之间自动拉开。
- COTE 求平移:三个轴各自做一维「区间覆盖最多」的投票,某个轴的离群值不会污染另外两个轴。
- ICP 精修:鲁棒解已经很接近了,再用最近邻 ICP 把残差压到体素量级以下。
这套流程来自 MIT-SPARK 的 KISS-Matcher(参数命名也沿用它:法向半径 3×体素、FPFH 半径 5×体素、剪枝噪声界 1×体素、求解噪声界 0.75×体素)和 TEASER++ 的 GNC-TLS / COTE 求解器。这个页面用 TypeScript 重写了同样的算法并在浏览器里运行 —— 好处是不用下载 WASM、打开就能用;代价是百万点级别的规模还不是它的强项。
参数怎么调
| 参数 | 什么时候改 |
|---|---|
| 体素边长 | 唯一必须理解的旋钮。太小 → 关键点多、慢,且描述子被噪声主导;太大 → 几何细节被抹平,匹配失去区分度。点数多到算不动时,页面会自动加大它并告诉你最终值。 |
| 关键点上限 | 控制计算量。2000~3000 是浏览器里的舒适区。 |
| 对应点上限 | 图剪枝是 O(n²),这个值越大越准但越慢。 |
| 比值检验 | 重复结构多(长走廊、栅栏、货架)时保持开启;场景特征很独特、对应点太少时可以关掉试试。 |
| ICP 精修 | 默认开启。如果你的点云本身噪声很大,ICP 可能把结果往噪声上拉,这时可以关掉对比一下。 |
结果怎么看
- 重合度:对齐后源点云里有多少比例的点在目标点云的 1.5 倍体素内。低于 60% 基本可以认为没配上。
- RMSE:这些点的平均最近邻距离。两片点云的体素格本来就错开,所以 RMSE 的下限就是体素量级,不必追求 0。
- 内点数:鲁棒求解器最后认可了多少对对应点。它和「剪枝后」的比值反映了数据有多干净。
- 旋转 / 平移:分解出来的直观量。旋转接近 0、平移接近 0 说明两片点云本来就在同一个坐标系里。
常见情况
| 现象 | 通常是这个原因 |
|---|---|
| 重合度很低、矩阵看着完全不对 | 两片点云没有足够重叠,或者尺度差太多(毫米 vs 米) |
| 对应点很少(< 50) | 体素太大把细节抹平了,或者场景本身太光滑 |
| 结果是个 180° 翻转 | 场景有旋转对称性(正方形房间、圆柱体);用裁剪工具先去掉对称部分 |
| 每次跑结果都在跳 | 内点太少,说明数据本身不支持全局配准;先做粗对齐或者换用带初始位姿的方法 |
| 页面卡了十几秒 | 关键点在 3000 以上,主线程满负荷;减少关键点上限或者加大体素 |
为什么坚持本地计算:标定和配准用的点云经常带客户现场坐标、未公开的场地数据。这个工具没有后端,文件不会离开你的浏览器。代价是计算能力受限于你的机器 —— 也正因如此,参数默认值都往「能在几秒内跑完」的方向调。