本文主要是介绍《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;
}
运行:
注意点:
- inline void setModelType (int model) 所提取目标模型的属性(平面、球、圆柱等等),这个示例中主要是提取平面。
- inline voidsetMethodType (int method)采样方法(RANSAC、LMedS)等,具体的方式可以参考教程,此处选随机一致性采样。
- 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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!