《PCL点云库学习VS2010(X64)》Part 14 PCL1.72(VTK6.2.0)点云分割(Point Cloud Segmentation)

本文主要是介绍《PCL点云库学习VS2010(X64)》Part 14 PCL1.72(VTK6.2.0)点云分割(Point Cloud Segmentation),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Part 14 PCL1.72(VTK6.2.0)点云分割(Point Cloud Segmentation)


1、Plane Model Segmentation

cpp:

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/search/kdtree.h>
#include <pcl/filters/passthrough.h>
#include <pcl/filters/extract_indices.h>int main(int argc, char** argv)
{pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_source (new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_target (new pcl::PointCloud<pcl::PointXYZ>);// check argumentsif(argc != 2) {std::cout << "ERROR: the number of arguments is illegal!" << std::endl;return -1;}// load pcd fileif(pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud_source)==-1) {std::cout << "load source failed!" << std::endl;return -1;}std::cout << "source loaded!" << std::endl;// pass through filter to get the certain fieldpcl::PointCloud<pcl::PointXYZ>::Ptr cloud_source_filtered(new pcl::PointCloud<pcl::PointXYZ>);pcl::PassThrough<pcl::PointXYZ> pt;pt.setInputCloud(cloud_source);pt.setFilterFieldName("y");pt.setFilterLimits(-0.1, 0.6);pt.filter(*cloud_source_filtered);// segmentationpcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);pcl::PointIndices::Ptr inliers (new pcl::PointIndices);pcl::SACSegmentation<pcl::PointXYZ> sac;sac.setInputCloud(cloud_source_filtered);    // cloud_source_filtered 为提取桌子表面 cloud_source 为提取地面sac.setMethodType(pcl::SAC_RANSAC);//set sample method SAC_RANSACsac.setModelType(pcl::SACMODEL_PLANE);sac.setDistanceThreshold(0.01);sac.setMaxIterations(100);sac.setProbability(0.95);sac.segment(*inliers, *coefficients);// extract the certain fieldpcl::ExtractIndices<pcl::PointXYZ> ei;ei.setIndices(inliers);ei.setInputCloud(cloud_source_filtered);    // cloud_source_filtered 为提取桌子表面 cloud_source 为提取地面ei.filter(*cloud_target);std::cout << *coefficients << std::endl;// displaypcl::visualization::PCLVisualizer p;pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> tgt_h (cloud_target, 255, 0, 0);p.setWindowName("cloud_target-目标数据-桌面");p.addPointCloud(cloud_target, tgt_h, "target");p.spinOnce();pcl::visualization::PCLVisualizer p2;pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> src_h (cloud_source, 0, 255, 0);p2.setWindowName("cloud_source-原始数据");p2.addPointCloud(cloud_source, src_h, "source");p2.spinOnce();//no spin()pcl::visualization::PCLVisualizer p3;pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> src_f(cloud_source_filtered, 0, 0, 255);p3.setWindowName("cloud_source_filtered-桌子表面");p3.addPointCloud(cloud_source_filtered, src_f, "cloud_source_filtered");p3.spin();return 0;
}

运行

注意点:

  1. inline void setModelType (int model) 所提取目标模型的属性(平面、球、圆柱等等),这个示例中主要是提取平面。
  2. inline voidsetMethodType (int method)采样方法(RANSAC、LMedS)等,具体的方式可以参考教程,此处选随机一致性采样。
  3. SACMODEL_PLANE - 用于确定平面模型。平面的四个系数是Hessian的正常形态:[normal_x normal_y normal_z D]
    * SACMODEL_LINE - 用于确定线模型。该行的6个系数是由一个点上线,并线的方向:[point_on_line.x point_on_line.y point_on_line.z line_direction.x line_direction.y line_direction.z]
    * SACMODEL_CIRCLE2D - 用于确定一个2d圆。其圆心和半径的圆的三个系数:[center.x center.y半径]
    * SACMODEL_CIRCLE3D - 尚未实现
    * SACMODEL_SPHERE - 用于确定球体。球体的四个系数由3D的圆心和半径为:[center.x center.y center.z半径]
    * SACMODEL_CYLINDER - 用于确定圆柱。圆柱模型的七个系数由点上的轴,轴的方向,半径,因为:[point_on_axis.x point_on_axis.y point_on_axis.z axis_direction.x axis_direction.y axis_direction.z半径]
    * SACMODEL_CONE - 尚未实现
    * SACMODEL_TORUS - 尚未实现
    * SACMODEL_PARALLEL_LINE - 确定一个给定轴的平行线的模型,在一个指定的最大角偏差。该生产线的系数类似SACMODEL_LINE。
    * SACMODEL_PERPENDICULAR_PLANE - 为确定用户指定的轴垂直的平面内一个指定的最大角偏差,的模式。平面系数类似SACMODEL_PLANE。
    * SACMODEL_PARALLEL_LINES - 尚未实现
    * SACMODEL_NORMAL_PLANE - 一个使用一个额外的约束来确定平面:在每个内点的表面法线在指定的最大角偏差,表面正常的输出平面平行。平面系数类似SACMODEL_PLANE。
    * SACMODEL_PARALLEL_PLANE - 一个maximim指定的角偏差,到用户指定的轴范围内确定一个平面平行的典范。 SACMODEL_PLANE。
    * SACMODEL_NORMAL_PARALLEL_PLANE 使用额外的一般平面约束来分割3D平面。平面必须平行与用户指定的轴。SACMODEL_NORMAL_PARALLEL_PLANE因此是equivallent SACMODEL_NORMAL_PLANE + SACMODEL_PARALLEL_PLANE。平面系数类似SACMODEL_PLANE。



2、柱体分割Cylinder Segmentation

cpp:
#include <vtkAutoInit.h>         
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/passthrough.h>
#include <pcl/features/normal_3d.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/search/kdtree.h>  
#include <pcl/visualization/pcl_visualizer.h> typedef pcl::PointXYZ PointT;int
main (int argc, char** argv)
{// All the objects neededpcl::PCDReader reader;pcl::PassThrough<PointT> pass;pcl::NormalEstimation<PointT, pcl::Normal> ne;pcl::SACSegmentationFromNormals<PointT, pcl::Normal> seg; pcl::PCDWriter writer;pcl::ExtractIndices<PointT> extract;pcl::ExtractIndices<pcl::Normal> extract_normals;pcl::search::KdTree<PointT>::Ptr tree (new pcl::search::KdTree<PointT> ());// Datasetspcl::PointCloud<PointT>::Ptr cloud (new pcl::PointCloud<PointT>);pcl::PointCloud<PointT>::Ptr cloud_filtered (new pcl::PointCloud<PointT>);pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);pcl::PointCloud<PointT>::Ptr cloud_filtered2 (new pcl::PointCloud<PointT>);pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2 (new pcl::PointCloud<pcl::Normal>);pcl::ModelCoefficients::Ptr coefficients_plane (new pcl::ModelCoefficients), coefficients_cylinder (new pcl::ModelCoefficients);pcl::PointIndices::Ptr inliers_plane (new pcl::PointIndices), inliers_cylinder (new pcl::PointIndices);// Read in the cloud datareader.read ("table_scene_mug_stereo_textured.pcd", *cloud);std::cerr << "PointCloud has: " << cloud->points.size () << " data points." << std::endl;// Build a passthrough filter to remove spurious NaNspass.setInputCloud (cloud);pass.setFilterFieldName ("z");pass.setFilterLimits (0, 1.5);pass.filter (*cloud_filtered);std::cerr << "PointCloud after filtering has: " << cloud_filtered->points.size () << " data points." << std::endl;// Estimate point normalsne.setSearchMethod (tree);ne.setInputCloud (cloud_filtered);ne.setKSearch (50);ne.compute (*cloud_normals);// Create the segmentation object for the planar model and set all the parametersseg.setOptimizeCoefficients (true);seg.setModelType (pcl::SACMODEL_NORMAL_PLANE);seg.setNormalDistanceWeight (0.1);seg.setMethodType (pcl::SAC_RANSAC);seg.setMaxIterations (100);seg.setDistanceThreshold (0.03);seg.setInputCloud (cloud_filtered);seg.setInputNormals (cloud_normals);// Obtain the plane inliers and coefficientsseg.segment (*inliers_plane, *coefficients_plane);std::cerr << "Plane coefficients: " << *coefficients_plane << std::endl;// Extract the planar inliers from the input cloudextract.setInputCloud (cloud_filtered);extract.setIndices (inliers_plane);extract.setNegative (false);// Write the planar inliers to diskpcl::PointCloud<PointT>::Ptr cloud_plane (new pcl::PointCloud<PointT> ());extract.filter (*cloud_plane);std::cerr << "PointCloud representing the planar component: " << cloud_plane->points.size () << " data points." << std::endl;writer.write ("table_scene_mug_stereo_textured_plane.pcd", *cloud_plane, false);// Remove the planar inliers, extract the restextract.setNegative (true);extract.filter (*cloud_filtered2);extract_normals.setNegative (true);extract_normals.setInputCloud (cloud_normals);extract_normals.setIndices (inliers_plane);extract_normals.filter (*cloud_normals2);// Create the segmentation object for cylinder segmentation and set all the parametersseg.setOptimizeCoefficients (true);seg.setModelType (pcl::SACMODEL_CYLINDER);seg.setMethodType (pcl::SAC_RANSAC);seg.setNormalDistanceWeight (0.1);seg.setMaxIterations (10000);seg.setDistanceThreshold (0.05);seg.setRadiusLimits (0, 0.1);seg.setInputCloud (cloud_filtered2);seg.setInputNormals (cloud_normals2);// Obtain the cylinder inliers and coefficientsseg.segment (*inliers_cylinder, *coefficients_cylinder);std::cerr << "Cylinder coefficients: " << *coefficients_cylinder << std::endl;// Write the cylinder inliers to diskextract.setInputCloud (cloud_filtered2);extract.setIndices (inliers_cylinder);extract.setNegative (false);pcl::PointCloud<PointT>::Ptr cloud_cylinder (new pcl::PointCloud<PointT> ());extract.filter (*cloud_cylinder);if (cloud_cylinder->points.empty ()) std::cerr << "Can't find the cylindrical component." << std::endl;else{std::cerr << "PointCloud representing the cylindrical component: " << cloud_cylinder->points.size () << " data points." << std::endl;writer.write ("table_scene_mug_stereo_textured_cylinder.pcd", *cloud_cylinder, false);}std::cerr << "Start display……" << std::endl;// display  pcl::visualization::PCLVisualizer p;pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> source(cloud, 255, 0, 0);p.setWindowName("源数据");p.addPointCloud(cloud, source, "source");p.spinOnce();pcl::visualization::PCLVisualizer p2;pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> ps_filtered(cloud_filtered, 0, 255, 0);p2.setWindowName("直通滤波后的数据");p2.addPointCloud(cloud_filtered, ps_filtered, "ps_filtered");p2.spinOnce();//no spin()  //pcl::visualization::PCLVisualizer p3;//pcl::visualization::PointCloudColorHandlerCustom<pcl::Normal> normals(cloud_normals, 0, 0, 255);//p3.setWindowName("法线数据");//p3.addPointCloud(cloud_normals, normals, "normals");//p3.spinOnce();pcl::visualization::PCLVisualizer p4;pcl::visualization::PointCloudColorHandlerCustom<PointT> extra_outlier(cloud_filtered2, 0, 0, 255);p4.setWindowName("提取外点数据");p4.addPointCloud(cloud_filtered2, extra_outlier, "extra_outlier");p4.spinOnce();pcl::visualization::PCLVisualizer p5;//pcl::visualization::PointCloudColorHandlerCustom<pcl::Normal> normals2(cloud_normals2, 0, 0, 255);p5.setWindowName("提取外点法线数据");p5.addPointCloudNormals<PointT, pcl::Normal>(cloud_filtered2, cloud_normals2, 10, 0.05, "normals2");//normals corresponded with origin datap5.spinOnce();pcl::visualization::PCLVisualizer p6;pcl::visualization::PointCloudColorHandlerCustom<PointT>  plane(cloud_plane, 0, 0, 255);p6.setWindowName("内点平面");p6.addPointCloud(cloud_plane, plane, "plane");p6.addCylinder(*coefficients_plane, "coefficients_plane");p6.spinOnce();pcl::visualization::PCLVisualizer p7;pcl::visualization::PointCloudColorHandlerCustom<PointT>  cylinder(cloud_cylinder, 0, 0, 255);p7.setWindowName("内点柱面");p7.addPointCloud(cloud_cylinder, cylinder, "cylinder");p7.addCylinder(*coefficients_cylinder, "coefficients_cylinder");p7.spin();std::cerr << "The end……" << std::endl;return (0);
}

运行:


3、cluster extraction——欧式聚类提取(分割)

cpp:
#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>#include <pcl/visualization/pcl_visualizer.h>     
#include <pcl/common/time.h> 
#include <time.h>int 
main (int argc, char** argv)
{clock_t start, end;// Read in the cloud data读数据pcl::PCDReader reader;pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>), cloud_f (new pcl::PointCloud<pcl::PointXYZ>);reader.read ("table_scene_lms400.pcd", *cloud);std::cout << "PointCloud before filtering has: " << cloud->points.size () << " data points." << std::endl; //*// Create the filtering object: downsample the dataset using a leaf size of 1cm体素栅格滤波pcl::VoxelGrid<pcl::PointXYZ> vg;pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);vg.setInputCloud (cloud);vg.setLeafSize (0.01f, 0.01f, 0.01f);vg.filter (*cloud_filtered);std::cout << "PointCloud after filtering has: " << cloud_filtered->points.size ()  << " data points." << std::endl; //*// Create the segmentation object for the planar model and set all the parameters随机采样一致性分割pcl::SACSegmentation<pcl::PointXYZ> seg;pcl::PointIndices::Ptr inliers (new pcl::PointIndices);pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane (new pcl::PointCloud<pcl::PointXYZ> ());pcl::PCDWriter writer;seg.setOptimizeCoefficients (true);seg.setModelType (pcl::SACMODEL_PLANE);seg.setMethodType (pcl::SAC_RANSAC);seg.setMaxIterations (100);seg.setDistanceThreshold (0.02);int i=0, nr_points = (int) cloud_filtered->points.size ();while (cloud_filtered->points.size () > 0.3 * nr_points){// Segment the largest planar component from the remaining cloud从剩余点云中分割出最大平面seg.setInputCloud (cloud_filtered);seg.segment (*inliers, *coefficients);if (inliers->indices.size () == 0){std::cout << "Could not estimate a planar model for the given dataset." << std::endl;break;}// Extract the planar inliers from the input cloud从输入点云(滤波后的点云)中提取平面内点pcl::ExtractIndices<pcl::PointXYZ> extract;extract.setInputCloud (cloud_filtered);extract.setIndices (inliers);extract.setNegative (false);// Write the planar inliers to disk存储平面点云extract.filter (*cloud_plane);std::cout << "PointCloud representing the planar component: " << cloud_plane->points.size () << " data points." << std::endl;// Remove the planar inliers, extract the rest移除内点,提取剩下的点云extract.setNegative (true);extract.filter (*cloud_f);cloud_filtered = cloud_f;}// // Creating the KdTree object for the search method of the extraction为提取算法创建KdTreepcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);tree->setInputCloud (cloud_filtered);// std::vector<pcl::PointIndices> cluster_indices;pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;//欧式聚类ec.setClusterTolerance (0.02); // 2cmec.setMinClusterSize (100);ec.setMaxClusterSize (25000);ec.setSearchMethod (tree);ec.setInputCloud (cloud_filtered);start = clock();ec.extract (cluster_indices);end = clock();// int j = 0;for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it){pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>);for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); pit++)cloud_cluster->points.push_back (cloud_filtered->points[*pit]); //*cloud_cluster->width = cloud_cluster->points.size ();cloud_cluster->height = 1;cloud_cluster->is_dense = true;std::cout << "PointCloud representing the Cluster: " << cloud_cluster->points.size () << " data points." << std::endl;std::stringstream ss;ss << "cloud_cluster_" << j << ".pcd";writer.write<pcl::PointXYZ> (ss.str (), *cloud_cluster, false); //*j++;}//  //得到欧式聚类时间  std::cout << "欧式聚类运行时间" << std::endl;std::cout << "运行时间:" << (double)(end-start)/*/CLOCKS_PER_SEC*/ << "毫妙" << std::endl;//  pcl::visualization::PCLVisualizer viewer;int v1(0);viewer.createViewPort(0.0, 0.0, 0.25, 1.0, v1);viewer.setBackgroundColor(1.0, 0.5, 1.0, v1);viewer.addText("Remove the planar inliers, extract the rest ", 10, 10, "cloud_f", v1);viewer.addPointCloud(cloud_f, "cloud_f", v1);int v2(0);viewer.createViewPort(0.25, 0.0, 0.5, 1.0, v2);viewer.setBackgroundColor(1.0, 0.5, 1.0, v2);viewer.addText("cloud_plane", 10, 10, "cloud_plane", v2);viewer.addPointCloud(cloud_plane, "cloud_plane", v2);int v3(0);viewer.createViewPort(0.5, 0.0, 0.75, 1.0, v3);viewer.setBackgroundColor(1.0, 0.5, 1.0, v3);viewer.addText("cloud", 10, 10, "cloud", v3);viewer.addPointCloud(cloud, "cloud", v3);int v4(0);viewer.createViewPort(0.75, 0.0, 1.0, 1.0, v4);viewer.setBackgroundColor(1.0, 0.5, 1.0, v4);viewer.addText("cloud_filtered", 10, 10, "cloud_filtered", v4);viewer.addPointCloud(cloud_filtered, "cloud_filtered", v4);//viewer.spin();//  return (0);
}

运行:




4、区域生长分割:

代码:

#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/search/kdtree.h>
#include <pcl/features/normal_3d.h>
#include <pcl/segmentation/region_growing.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <iostream>
using namespace std;int
main(int argc, char** argv)
{	string filename("region_growing_tutorial.pcd");// Object for storing the point cloud.pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);// Object for storing the normals.pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);// Read a PCD file from disk.if (pcl::io::loadPCDFile<pcl::PointXYZ>(filename, *cloud) != 0)//argv[1]{return -1;}// kd-tree object for searches.pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);kdtree->setInputCloud(cloud);// Estimate the normals.pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> normalEstimation;normalEstimation.setInputCloud(cloud);normalEstimation.setRadiusSearch(0.03);normalEstimation.setSearchMethod(kdtree);normalEstimation.compute(*normals);// Region growing clustering object.pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> clustering;clustering.setMinClusterSize(100);clustering.setMaxClusterSize(10000);clustering.setSearchMethod(kdtree);clustering.setNumberOfNeighbours(30);clustering.setInputCloud(cloud);clustering.setInputNormals(normals);// Set the angle in radians that will be the smoothness threshold// (the maximum allowable deviation of the normals).clustering.setSmoothnessThreshold(7.0 / 180.0 * M_PI); // 7 degrees.// Set the curvature threshold. The disparity between curvatures will be// tested after the normal deviation check has passed.clustering.setCurvatureThreshold(1.0);std::vector <pcl::PointIndices> clusters;clustering.extract(clusters);// For every cluster...int currentClusterNum = 1;for (std::vector<pcl::PointIndices>::const_iterator i = clusters.begin(); i != clusters.end(); ++i){// ...add all its points to a new cloud...pcl::PointCloud<pcl::PointXYZ>::Ptr cluster(new pcl::PointCloud<pcl::PointXYZ>);for (std::vector<int>::const_iterator point = i->indices.begin(); point != i->indices.end(); point++)cluster->points.push_back(cloud->points[*point]);cluster->width = cluster->points.size();cluster->height = 1;cluster->is_dense = true;// ...and save it to disk.if (cluster->points.size() <= 0)break;std::cout << "Cluster " << currentClusterNum << " has " << cluster->points.size() << " points." << std::endl;std::string fileName = "cluster" + boost::to_string(currentClusterNum) + ".pcd";pcl::io::savePCDFileASCII(fileName, *cluster);currentClusterNum++;}//Read cluster cloud points saved above from filepcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster1(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster2(new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster3(new pcl::PointCloud<pcl::PointXYZ>);pcl::io::loadPCDFile("cluster1.pcd",*cloud_cluster1);pcl::io::loadPCDFile("cluster2.pcd", *cloud_cluster2);pcl::io::loadPCDFile("cluster3.pcd",*cloud_cluster3);//Visualizationpcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D viewer"));//create viewport #1int v1(0);viewer->createViewPort(0.0, 0.5, 0.5, 1.0, v1);viewer->setBackgroundColor(0.5, 0.5, 0.5);pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_handle1(cloud_cluster1, 250, 0, 0);viewer->addPointCloud(cloud_cluster1,cloud_handle1,"cluster1",v1);viewer->spinOnce();//create viewport #2int v2(0);viewer->createViewPort(0.5, 0.5, 1.0, 1.0, v2);viewer->setBackgroundColor(0.5, 0.5, 0.5);pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_handle2(cloud_cluster2, 0, 250, 0);viewer->addPointCloud(cloud_cluster2, cloud_handle2, "cluster2", v2);viewer->spinOnce();//create viewport #3int v3(0);viewer->createViewPort(0.0, 0.0, 0.5, 0.5, v3);viewer->setBackgroundColor(0.5, 0.5, 0.5);pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_handle3(cloud_cluster3, 0, 0, 250);viewer->addPointCloud(cloud_cluster3, cloud_handle3, "cluster3", v3);viewer->spinOnce();//create viewport #4int v4(0);viewer->createViewPort(0.5, 0.0, 1.0, 0.5, v4);viewer->setBackgroundColor(0.5, 0.5, 0.5);pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_handle(cloud, 220, 220, 20);viewer->addPointCloud(cloud, cloud_handle, "cloud", v4);viewer->spin();}

运行结果:





5、RANSAC模型分割,基本的代码

 //创建一个模型参数对象,用于记录结果pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);//inliers表示误差能容忍的点 记录的是点云的序号pcl::PointIndices::Ptr inliers (new pcl::PointIndices);// 创建一个分割器pcl::SACSegmentation<pcl::PointXYZ> seg;// Optionalseg.setOptimizeCoefficients (true);// Mandatory-设置目标几何形状seg.setModelType (pcl::SACMODEL_PLANE);//分割方法:随机采样法seg.setMethodType (pcl::SAC_RANSAC);//设置误差容忍范围seg.setDistanceThreshold (0.01);//输入点云seg.setInputCloud (cloud);//分割点云seg.segment (*inliers, *coefficients);


上面的模型系数计算出来后可以直接输出。在有的函数中会用到模型参数进行集合建模,如直线和平面等。


这篇关于《PCL点云库学习VS2010(X64)》Part 14 PCL1.72(VTK6.2.0)点云分割(Point Cloud Segmentation)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/515341

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

2、PF-Net点云补全

2、PF-Net 点云补全 PF-Net论文链接:PF-Net PF-Net (Point Fractal Network for 3D Point Cloud Completion)是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像