在接的小项目中,有遇到基于工业结构间的配准工作,发现可能之前对这方面只是单纯的了解,但是实战经验较少,之前都一直做点云的目标检测。
配准方法尝试了PCA+ICP 配准,FPFH+ICP配准,NDT配准发现效果都不是特别好。发现有个ISS特征没用过,使用后发现对于结构件很有效果。于是研究了下,也在这里记录下,希望对大家有帮助。
目录
ISS特征提取算法
ISS特征提取(Intrinsic Shape Signatures) 是一种用于 三维点云 的关键点检测方法,主要提取点云中几何结构稳定和显著的特征点。ISS 算法的核心思想是找到具有高局部几何显著性和稳定性 的点,通常用于三维点云配准、目标识别和建模等应用。
特征点类型
ISS 算法提取的是在局部邻域中具有较大几何变化(显著性)的点。这些点通常是:
- 曲率变化较大 的点(例如角点、边缘点)。
- 结构突出的点,比如物体表面的尖角、边缘等区域。
特征点特性
- ISS 特征点具有 局部几何稳定性,即在不同的视角、尺度下,它们的位置和显著性是稳定的,能够重复检测出来。
- 稳定性通常是通过计算邻域协方差矩阵的特征值来衡量的。
ISS特征提取算法流程
-
构建点的局部邻域
- 选定一个点,并在其周围以指定半径 rrr 搜索邻域内的点。
-
计算协方差矩阵
- 在局部邻域内,计算邻域点的 协方差矩阵:
-
- 其中,
是邻域内的点,
是局部邻域点的质心。
-
特征值分解
- 对协方差矩阵 进行 特征值分解,得到三个特征值 λ1,λ2,λ3(
)。
- 这些特征值表示局部点云的主方向和几何变化的强度。
- 对协方差矩阵 进行 特征值分解,得到三个特征值 λ1,λ2,λ3(
-
显著性计算
- 使用特征值来衡量局部显著性,通常定义如下:
- 当显著性较高时,表明该点在局部邻域中存在较大的几何变化,是一个特征点。
-
特征点筛选
- 通过设定阈值(如显著性阈值和邻域半径),筛选出具有高显著性且稳定的特征点。
- 为了保证点云的均匀分布,通常会进行 非最大抑制 处理,去除邻近区域内的冗余点。
小结
其实基于个人理解,ISS算法计算邻域的协方差,然后进行特征值分解。特征值主要的是表达领域内的在主方向,次主方向以及最小主方向的数据的方差变化(离散程度),也就是说当方差等于0表示在对应的方向上没有什么变化。
特征值关系 | 几何形态 | 特征点类型 |
---|---|---|
平面形态 | 平面区域(法向量方向) | |
线性形态 | 棱边、直线特征点 | |
角点/突变区域 | 角点、边缘交叉点 | |
均匀分布的点云区域 | 球面或曲面区域 |
:描述局部点云的主要扩展方向。
:描述次要扩展方向。
:描述最小扩展方向,接近 0 时,表示点云分布是平面的。
实践
ISS算法使用PCL自带的API,ISSKeypoint3D进行关键点提取。
// --------------------------ISS关键点提取----------------------------
pcl::StopWatch watcher;
pcl::ISSKeypoint3D<pcl::PointXYZ, pcl::PointXYZ> iss;
pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints(
new pcl::PointCloud<pcl::PointXYZ>());
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(
new pcl::search::KdTree<pcl::PointXYZ>());
iss.setInputCloud(cloud_in_box);
iss.setSearchMethod(tree);
iss.setNumberOfThreads(4); // 初始化调度器并设置要使用的线程数
iss.setSalientRadius(0.3f); // 设置用于计算协方差矩阵的球邻域半径
iss.setNonMaxRadius(0.01f); // 设置非极大值抑制应用算法的半径
iss.setThreshold21(0.99); // 设定第二个和第一个特征值之比的上限
iss.setThreshold32(0.99); // 设定第三个和第二个特征值之比的上限
iss.setMinNeighbors(4); // 在应用非极大值抑制算法时,设置必须找到的最小邻居数
下列点云图,是项目中的图一个托盘点云,目的是想把前表面关键点检测出来,从检测效果上看,可以把
可以看到点数也从3119 减少到112.
从结果上看,通过ISS进行关键点提取,关键点的点云分布也是具有原始点云的几何特征的。这对于后面对于有强结构性的结构件,用ISS进行特征点匹配计算初始变换矩阵,可以提高后续ICP的配准精度。