Ao usar o pcl para extrair planos no espaço da nuvem de pontos, geralmente usamos o modelo SACMODEL_PLANE e usamos o algoritmo RANSAC (Sampling Consistency Algorit) para extração. Quando o ambiente é mais complexo, podemos usar o modelo SACMODEL_NORMAL_PARALLEL_PLANE para restringir a direção normal do plano e segmentar com mais precisão a nuvem de pontos do plano.
Função encapsulada
Parâmetros: (nuvem de pontos de entrada, normal normal, nuvem de pontos planos extraídos, nuvem de pontos filtrados, parâmetros de planos, distância máxima permitida do ponto ao modelo, número de iterações)
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);
}
Exemplos
Extraia a superfície superior da nuvem de pontos no cilindro