Lorsque vous utilisez pcl pour extraire des plans dans l'espace du nuage de points, nous utilisons généralement le modèle SACMODEL_PLANE et utilisons l'algorithme de cohérence d'échantillonnage (RANSAC) pour l'extraction. Lorsque l'environnement est plus complexe, nous pouvons utiliser le modèle SACMODEL_NORMAL_PARALLEL_PLANE pour contraindre la direction normale du plan et segmenter plus précisément le nuage de points du plan.
Fonction encapsulée
Paramètres: (nuage de points d'entrée, normal normal, nuage de points plan extrait, nuage de points filtré, paramètres du plan, distance maximale admissible du point au modèle, nombre d'itérations)
void normalPlaneSeg(pcl::PointCloud<pcl::PointXYZ>::Ptr Inputcloud,Eigen::Vector3f axis, pcl::PointCloud<pcl::PointXYZ>::Ptr filtercloud, pcl::PointCloud<pcl::PointXYZ>::Ptr filtercloud1,
pcl::ModelCoefficients::Ptr coefficients, double Threshold, int Iterationscount=1000)
{
typedef pcl::PointXYZ PointT;
//定义一些对象
pcl::NormalEstimation<PointT,pcl::Normal> ne; //法线估计对象
pcl::SACSegmentationFromNormals<PointT,pcl::Normal> seg; //分割对象
pcl::PCDWriter writer; //PCD文件读取对象
pcl::ExtractIndices<PointT>extract; //点提取对象
pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>());
//定义一些变量
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals(new pcl::PointCloud<pcl::Normal>);
pcl::PointCloud<PointT>::Ptr cloud_filtered(new pcl::PointCloud<PointT>);
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2(new pcl::PointCloud<pcl::Normal>);
pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
ne.setSearchMethod(tree);
ne.setInputCloud(Inputcloud);
ne.setKSearch(5);
ne.compute(*cloud_normals);
seg.setOptimizeCoefficients(true); //设置对估计模型优化
seg.setModelType(pcl::SACMODEL_NORMAL_PARALLEL_PLANE);//设置分割模型为带约束的平面
seg.setMethodType(pcl::SAC_RANSAC); //参数估计方法
seg.setNormalDistanceWeight(0.1); //设置表面法线权重系数
seg.setMaxIterations(Iterationscount); //设置迭代的最大次数,默认是10000
seg.setDistanceThreshold(Threshold); //设置内点到模型的距离允许最大值
seg.setInputCloud(Inputcloud);
seg.setInputNormals(cloud_normals);
seg.segment(*inliers, *coefficients);
seg.setAxis(axis);
seg.setEpsAngle(PI / 120);//设置角度误差
extract.setInputCloud(Inputcloud);
extract.setIndices(inliers);
extract.setNegative(false);//设置成true是保存滤波后剩余的点,false是保存在区域内的点
extract.filter(*filtercloud);
extract.setNegative(true);//设置成true是保存滤波后剩余的点,false是保存在区域内的点
extract.filter(*filtercloud1);
}
Des exemples
Extraire la surface supérieure du nuage de points sur le cylindre