29基于PCL的点云平⾯分割拟合算法技术路线(针对有噪声的点
云数据)
0 引⾔
最近项⽬中⽤到了基于PCL开发的基于平⾯的点云和CAD模型的配准算法,点云平⾯提取采⽤的算法如下。
1 基于PCL的点云平⾯分割拟合算法
story什么意思
2 参数及其意义介绍
(1)点云下采样
1. 参数:leafsize
2. 意义:Voxel Grid的leafsize参数,物理意义是下采样⽹格的⼤⼩,直接影响处理后点云密集程度,并对后期各种算法的处理速度产⽣直接影响。
3. 值越⼤,点云密度越低,处理速度越快;值越⼩,点云密度越⾼,处理速度越慢。通常保持这个值,使得其他的与点数有关的参数可以⽐较稳定⽽不作⼤的改动。
ringer 4. 对应的代码:
PointCloudPtr cloud(new pointCloud);
ParameterReader pd(ParameterFilePath);
double leafsize = Data("leafsize"));
pcl::VoxelGrid<PointT> sor;
sor.tInputCloud(CRTP::cloud_org);
sor.tLeafSize(leafsize, leafsize, leafsize);
英语六级分数分布
sor.filter(*cloud);
(2)点云法线估计
1. 参数:Karch
2. 意义:估计法线时邻域内点的个数
3. 值越⼩,对点云的轮廓描述越精细;值越⼤,对点云的轮廓描述越粗糙。
4. 对应的代码:
ParameterReader pd(ParameterFilePath);
pcl::NormalEstimation<PointT, pcl::Normal> ne;
pcl::PointCloud<pcl::Normal>::Ptr mynormals(new pcl::PointCloud<pcl::Normal>);
pcl::arch::KdTree<PointT>::Ptr tree(new pcl::arch::KdTree<PointT>);
tree->tInputCloud(cloud_filter);
ne.tInputCloud(cloud_filter);
ne.tSearchMethod(tree);
ne.tKSearch(Data("Karch")));
投诉信英文ne.compute(*mynormals);
(3)RegionGrowing⽣长聚类算法对可能是平⾯的点云进⾏分割
算法步骤:
1. 算法⾸先计算所有点的曲率值,并将曲率最⼩的点作为种⼦(eds),开始进⾏⽣长
2. 以法线夹⾓阈值(Angle threshold)作为判断标准,对邻域内的点进⾏遍历判断,符合条件则加⼊当前点集,不符合则reject,并加⼊reject点集
3. 以曲率阈值(Curvature threshold)作为判断标准,将邻域内符合条件的点加⼊到种⼦队列中
numb
dain 4. 移除当前种⼦
5. 如果当前种⼦队列空了,表明当前⼦区域分割停⽌,遍历其他种⼦区域,直到停⽌整个点云均被遍历完为⽌⽣长
参数分析:
1. 参数:MinClusterSize(最⼩聚类点云数⽬),MaxClusterSize(最⼤聚类点云数据)
NumberOfNeighbours(寻找种⼦ed点最近的点判断是否为同类),SmoothnessThreshold(聚类的法线夹⾓阈值)
CurvatureThreshold(聚类的曲率阈值,可以直观地将圆柱⾯等区别开)
2. 对应的代码
ParameterReader pd(ParameterFilePath);
pcl::RegionGrowing<PointT, pcl::Normal> reg;
pcl::arch::KdTree<PointT>::Ptr tree(new pcl::arch::KdTree<PointT>);
reg.tMinClusterSize(Data("MinClusterSize")));
reg.tMaxClusterSize(Data("MaxClusterSize")));
reg.tSearchMethod(tree);
reg.tNumberOfNeighbours(Data("NumberOfNeighbours")));
reg.tInputCloud(CloudFilter);
reg.tInputNormals(Normals);
reg.tSmoothnessThreshold(Data("SmoothnessThreshold")) / 180.0 * M_PI);
reg.tCurvatureThreshold(Data("CurvatureThreshold")));
std::vector <pcl::PointIndices> clusters;
/* wk 添加:可视化调试 */
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_gmented(new pcl::PointCloud<pcl::PointXYZRGB>());
cloud_gmented = ColoredCloud();
pcl::visualization::CloudViewer viewer("Cluster viewer");
viewer.showCloud(cloud_gmented);
while (!viewer.wasStopped())
{
}
/* wk 添加:可视化调试 */
(4)SACSegmentation 利⽤RANSAC算法对平⾯点云进⾏分割并拟合
1. 参数:MaxIterations(最⼤迭代次数),threshold(距离阈值,判断点是否为当前拟合平⾯的内点,理论上该值越⼤平⾯越粗糙)
2. 代码
/*RanSAC拟合平⾯,并将平⾯内点分割出来*/
pcl::SACSegmentation<PointT> g;
pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
g.tOptimizeCoefficients(true);
g.tModelType(pcl::SACMODEL_PLANE);
g.tMethodType(pcl::SAC_RANSAC);
g.tMaxIterations(Data("Maxci")));
儿童节英文
g.tDistanceThreshold(Data("threshold")));
g.tInputCloud(cloud);
<(*inliers, *coefficients);
// 分割内点,另存
pcl::ExtractIndices<PointT> extract;
PointCloudPtr cloud_plane(new pointCloud);
extract.tInputCloud(cloud);杨必
自我介绍英语作文带翻译extract.tIndices(inliers);
extract.tNegative(fal);
extract.filter(*cloud_plane);布兰妮经典歌曲
3 部分效果图展⽰
(1)原图
(2)RegionGrowing分割效果图
4 算法的局限性
区域⽣长算法分割平⾯步骤及问题分析:针对分辨率低、扫描质量⽐较差的点云,如图所⽰,算法⽆法将破碎、扭曲的⼤块区域识别为平⾯区域,只能将这部分点判断为⾮平⾯点集舍弃掉。
区域⽣长算法通常在分割细节处⽐较平滑的平⾯点云时,具有相当的优势。但是在处理“波纹”状点云时,就没什么优势了。⽽实际扫描点云的细节部位很多时候是如上图所⽰的,为了将曲率较⼩的曲⾯区别开,⽽调低平滑及曲率阈值时,这类从⼤视⾓上看明显是平⾯的点云会被rejected,从⽽导致分割失效。如下图所⽰,RegionGrowing更适合处理接近理想点云的这类点云,⽽不适合处理波动起伏状的、扫描精度较差的点云。