《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

相关文章

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Spring Cloud之注册中心Nacos的使用详解

《SpringCloud之注册中心Nacos的使用详解》本文介绍SpringCloudAlibaba中的Nacos组件,对比了Nacos与Eureka的区别,展示了如何在项目中引入SpringClo... 目录Naacos服务注册/服务发现引⼊Spring Cloud Alibaba依赖引入Naco编程s依

Spring Cloud Hystrix原理与注意事项小结

《SpringCloudHystrix原理与注意事项小结》本文介绍了Hystrix的基本概念、工作原理以及其在实际开发中的应用方式,通过对Hystrix的深入学习,开发者可以在分布式系统中实现精细... 目录一、Spring Cloud Hystrix概述和设计目标(一)Spring Cloud Hystr

Spring Boot 3 整合 Spring Cloud Gateway实践过程

《SpringBoot3整合SpringCloudGateway实践过程》本文介绍了如何使用SpringCloudAlibaba2023.0.0.0版本构建一个微服务网关,包括统一路由、限... 目录引子为什么需要微服务网关实践1.统一路由2.限流防刷3.登录鉴权小结引子当前微服务架构已成为中大型系统的标

Spring Cloud LoadBalancer 负载均衡详解

《SpringCloudLoadBalancer负载均衡详解》本文介绍了如何在SpringCloud中使用SpringCloudLoadBalancer实现客户端负载均衡,并详细讲解了轮询策略和... 目录1. 在 idea 上运行多个服务2. 问题引入3. 负载均衡4. Spring Cloud Load

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

使用Python实现批量分割PDF文件

《使用Python实现批量分割PDF文件》这篇文章主要为大家详细介绍了如何使用Python进行批量分割PDF文件功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、架构设计二、代码实现三、批量分割PDF文件四、总结本文将介绍如何使用python进js行批量分割PDF文件的方法

Sentinel 断路器在Spring Cloud使用详解

《Sentinel断路器在SpringCloud使用详解》Sentinel是阿里巴巴开源的一款微服务流量控制组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、... 目录Sentinel 介绍同类对比Hystrix:Sentinel:微服务雪崩问题问题原因问题解决方案请

使用Python将长图片分割为若干张小图片

《使用Python将长图片分割为若干张小图片》这篇文章主要为大家详细介绍了如何使用Python将长图片分割为若干张小图片,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果1. Python需求

C#中字符串分割的多种方式

《C#中字符串分割的多种方式》在C#编程语言中,字符串处理是日常开发中不可或缺的一部分,字符串分割是处理文本数据时常用的操作,它允许我们将一个长字符串分解成多个子字符串,本文给大家介绍了C#中字符串分... 目录1. 使用 string.Split2. 使用正则表达式 (Regex.Split)3. 使用