PCL分割——区域生长聚簇
基于法向量夹角的区域生长聚簇
通过比较点之间法向量的夹角大小来判断点之间是否处于同一曲面,从而判断点之间是否聚簇。
算法流程
1️⃣ 初始化种子点
选中的点被加入一个称为 seeds(种子点集) 的集合,同时该点也被加入当前区域(Region)。
2️⃣ 遍历种子点
从 seeds 中取出一个种子点,查找该点的所有邻域点(通过 kNN 或半径搜索)。
3️⃣ 法向量角度判断(平滑性约束)
对于每一个邻域点,计算其法向量与当前种子点法向量之间的夹角。
若夹角 小于给定阈值,则认为该邻域点与种子点处于同一平滑表面,将该邻域点加入当前区域。
4️⃣ 曲率判断(是否继续生长)
若该邻域点的曲率 小于曲率阈值,说明该点位于较平坦区域,可作为新的生长起点,将该邻域点加入 seeds(种子点集)。
5️⃣ 更新种子点集并结束条件
当前种子点处理完成后,将其从 seeds 中移除;当 seeds 为空时,说明当前区域已生长完成。
为了减少点云分割得到的区域数量,该算法会优先选择具有较小曲率的点加入seed进行区域划分。
使用示例
pcl::search::Search<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>);
pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimator;
normal_estimator.setSearchMethod (tree);
normal_estimator.setInputCloud (cloud);
normal_estimator.setKSearch (50);
normal_estimator.compute (*normals);
pcl::IndicesPtr indices (new std::vector <int>);
pcl::removeNaNFromPointCloud(*cloud, *indices);
pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg;
reg.setMinClusterSize (50);
reg.setMaxClusterSize (1000000);
reg.setSearchMethod (tree);
reg.setNumberOfNeighbours (30);
reg.setInputCloud (cloud);
reg.setIndices (indices);
reg.setInputNormals (normals);
reg.setSmoothnessThreshold (3.0 / 180.0 * M_PI);
reg.setCurvatureThreshold (1.0);
std::vector <pcl::PointIndices> clusters;
//生成的clusters是一个pcl::PointIndices的集合。存储每个类别对应的点索引。
reg.extract (clusters);
//reg.getColoredCloud()此方法可以返回一份着色的点云 用于渲染
reg.setSmoothnessThreshold (3.0 / 180.0 * M_PI); reg.setCurvatureThreshold (1.0);这两句代码实际上是添加了两个合并条件。当平滑度不满足合并要求时会继续通过曲率判断是否合并。
基于颜色的区域生长聚簇
该算法在思想上与上面那个一样。只不过合并两点的依据从发向量夹角变成了RGB颜色值的相似性。
算法流程
1️⃣ 初始化与种子选择
从点云中选取初始种子点,基于点之间的邻域关系(如 KNN 或半径搜索)准备区域生长所需的数据结构。
2️⃣ 基于颜色的区域生长
以种子点为起始,遍历其邻域点,比较邻域点与当前区域中点的颜色差异;若颜色差异小于给定阈值,则将该邻域点加入当前区域,并作为新的种子继续生长。
3️⃣ 颜色相近区域的合并(第一阶段合并)
初始分割完成后,对相邻的区域进行检查;若两个区域的平均颜色差异较小,则将这两个区域合并,以减少过分割现象。
4️⃣ 小区域合并(第二阶段合并)
检查每个区域所包含的点数;若某个区域的点数小于用户设定的最小阈值,则将该区域与最近的相邻区域合并,以避免产生过小或噪声区域。
使用实例
pcl::IndicesPtr indices (new std::vector <int>);
pcl::removeNaNFromPointCloud (*cloud, *indices);
pcl::RegionGrowingRGB<pcl::PointXYZRGB> reg;
reg.setInputCloud (cloud);
reg.setIndices (indices);
reg.setSearchMethod (tree);
reg.setDistanceThreshold (10);
reg.setPointColorThreshold (6);
reg.setRegionColorThreshold (5);
reg.setMinClusterSize (600);
std::vector <pcl::PointIndices> clusters;
reg.extract (clusters);
该算法支持使用reg.setInputNormals添加法向量信息进行检测,但此处只使用了RGB数据。

浙公网安备 33010602011771号