M-detector 动态物体聚类与跟踪:体素聚类、地面估计与 OOBB 包围盒原理一篇讲透
2026/8/27 15:48:47 网站建设 项目流程

M-detector 动态物体聚类与跟踪:体素聚类、地面估计与 OOBB 包围盒原理一篇讲透

【免费下载链接】M-detector项目地址: https://gitcode.com/gh_mirrors/md/M-detector

M-detector 是一款基于 LiDAR 点云流的动态物体检测算法,它能逐个点对判断运动状态,延迟仅几微秒。本文带你从原理层面看懂它的三大核心模块:体素聚类地面估计OOBB 有向包围盒如何实现动态物体的聚类与跟踪。

一、M-detector 是做什么的 🚗

M-detector 由香港大学 MARS 实验室开发,核心思路基于遮挡原理:当激光雷达观测到某处的深度在短时间窗口内发生变化,说明有物体正在遮挡或被遮挡,从而判定该点属于运动物体(如车辆、行人)。

它的典型工作流是:

  1. 动态点筛选:基于多帧深度图(DepthMap)对每个点做运动判定,源码见 DynObjFilter.h;
  2. 体素聚类:把动态点合并成一个个物体级簇;
  3. 地面估计与去除:剔除被误判为动态的地面点;
  4. OOBB 包围盒估计:为每个物体给出带朝向的最小包围盒,支撑跟踪与预测。

后三步集中在 DynObjCluster.cpp 的DynObjCluster类中实现,下面逐一拆解。

二、体素聚类:把散点变成物体 📦

1. 为什么用体素而不是 KD-Tree DBSCAN

传统做法是 KD-Tree + DBSCAN(代码中保留了GetClusterResult分支,DynObjCluster.cpp),但逐点建索引开销大。M-detector 改用体素网格聚类:将空间划分为Voxel_revolusion(默认 0.3 m)的立方体格子,动态点直接落格,再按 26 邻域连通生长出簇,复杂度接近线性,适合嵌入式实时部署。

核心入口是GetClusterResult_voxel(DynObjCluster.cpp),内部调用VOXEL_CLUSTER(voxel_cluster.h)构建全局体素地图umap并提取voxel_clusters

2. 点分配与簇过滤

PubClusterResult_voxel(DynObjCluster.cpp)完成了两件事:

  • 包围盒初值:统计每个簇占据的最小/最大体素坐标,生成初始 AABB(轴对齐包围盒),仅保留在至少两个维度上尺寸超过体素大小的簇,过滤噪声碎片;
  • 原始点回填:遍历本帧原始点,按体素归属分配到"簇内点、簇外地面扩展点、框内填充点"三类体素地图(umap/umap_ground/umap_insidebox),并更新每个点的动态标签dyn_tag

此外还有两道质量关:

  • isolate_remove(DynObjCluster.cpp):对簇内部再做一次小范围体素聚类,只保留最大子簇,剔除离群孤立点;
  • 可信度检查:若簇的"原始点占比"低于thrustable_thresold(默认 0.3),说明大部分是填充点而非真实动态点,整个簇会被丢弃。

三、地面估计:把误报的地面点踢出去 🗺️

运动车辆底部会压到雷达的"地面回波",若不去除,聚类结果会拖出一条长长的尾巴。M-detector 在簇外扩展的体素(umap_ground)中做地面平面拟合

  1. 分块拟合ground_estimate(DynObjCluster.cpp)把候选地面点分成若干小块,对每块用esti_plane(基于列主元 QR 分解的最小二乘平面拟合,DynObjCluster.cpp)求平面,要求平面法向与车体系 Z 轴夹角小于 30°(保证是"接近水平"的平面);
  2. 择优投票:统计每块平面在全点集中的贴合点数,取覆盖最多的平面,要求支持点数超过 20% 或 500 点才认定地面成立;
  3. 区域生长event_extend(DynObjCluster.cpp)从地面体素出发做 6 邻域生长,把邻近且"法向不平行于地面"的体素并入物体——这正好能找回被车身遮挡、投影到地面的车底点;
  4. 地面去除ground_remove(DynObjCluster.cpp)把到平面距离小于 0.1 m 的点标记为静态,剔除出簇。

四、OOBB 包围盒:给物体一个带朝向的"盒子" 📐

轴对齐框(AABB)无法表达车辆朝向。M-detector 的oobb_estimate(DynObjCluster.cpp)用法向直方图投票求主方向:

  1. 法向采样:对簇内每个点数足够(≥5)的体素拟合平面法向;
  2. 等距面积圆盘分箱EA_disk(EA_disk.h)把法向从球面坐标投影到圆盘并分环分扇区,避免球面采样密度不均;
  3. 加权投票:每个扇区的得分为sqrt(点数) / |法向 z 分量|累加,sqrt抑制大簇体素的过度影响,1/z放大接近水平面的体素权重(更贴合"长条状车辆侧面"假设),取得分最高的两个扇区作为主方向与辅助方向;
  4. 构建旋转矩阵 R:若地面估计成功,则第一列直接取地面法向(保证盒子"站"在地面上),否则用主方向并对齐世界 Z 轴;
  5. 投影求极值:把簇内所有点变换到 R 坐标系下取 min/max,得到带朝向的 OOBB 最小/最大点,写入bbox_t结构体(DynObjCluster.h)。

输出的bbox_t同时携带中心位姿、点索引、地面点与 OOBB 参数,可直接用于 RViz 可视化、轨迹预测和下游 IoU 评估(见 cal_recall_multi.cpp)。

五、如何配置与上手运行 🚀

  • 参数配置:不同数据集的雷达参数(深度图分辨率、遮挡阈值、cluster_Voxel_revolusioncluster_thrustable_thresold等)位于 config/kitti/kitti0.yaml、config/nuscenes/nuscenes0.yaml、config/waymo/waymo0.yaml、config/avia/avia0.yaml;
  • 启动文件launch/detector_kitti.launch等数据集专属 launch,配合里程计节点回放 bag 即可运行;
  • 依赖:Ubuntu ≥ 18.04、ROS ≥ Melodic、PCL ≥ 1.8、Eigen ≥ 3.3.4 与 TBB(CMakeLists.txt 中需修改 TBB 路径)。

六、总结

M-detector 的动态物体聚类与跟踪链路可以概括为一句话:体素聚类负责"聚",地面估计负责"净",OOBB 负责"框"。三者均以体素网格为公共数据结构,充分利用 GPU/CPU 并行(std::execution::par),在嵌入式平台上实现了毫秒级的物体级检测与跟踪——这正是它能做到"逐点、微秒级延迟"动态检测的关键工程基础。

【免费下载链接】M-detector项目地址: https://gitcode.com/gh_mirrors/md/M-detector

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询