点云分割--RANSAC平面分割

1.版本要求

版本: >PCL1.3

2.简介

平面分割可用于地面检测,ransac是一种非常有效的平面分割方法,根据设定的平面模型不断迭代找出属于平面的点。同时通过设定模型距离阈值(setDistanceThreshold)可以检测不同起伏程度的地面。

3.数据

本例中使用的点云数据(test.pcd)请见百度网盘分享。
链接:https://pan.baidu.com/s/1CN3sb1lRylfvT67PnRdKiw
提取码:kz7q

4.代码

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/cloud_viewer.h>

int main(int argc, char** argv)
{
     
	pcl::PCDReader reader;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane(new pcl::PointCloud<pcl::PointXYZ>);
	reader.read("test.pcd", *cloud);  //读取点云
	
	pcl::PointIndices::Ptr inliers(new pcl::PointIndices);  //创建平面分割后存储平面点云的索引

	pcl::SACSegmentation<pcl::PointXYZ> seg;  //创建sac分割对象
	pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
	seg.setOptimizeCoefficients(true);
	seg.setModelType(pcl::SACMODEL_PLANE);  //设置模型为平面
	seg.setMethodType(pcl::SAC_RANSAC);  //设置分割方法为ransac
	seg.setMaxIterations(100);  //设置最大迭代次数
	seg.setDistanceThreshold(0.15);  //设置偏离模型距离阈值
	seg.setInputCloud(cloud);
	seg.segment(*inliers, *coefficients);  

	if (inliers->indices.size() == 0)  //检查一下是否有平面分割出来
	{
     
		std::cout << "Could not estimate a planar model for the given dataset." << std::endl;
	}

	pcl::ExtractIndices<pcl::PointXYZ> extract;  //抽取分割得到的平面点云
	extract.setInputCloud(cloud);
	extract.setIndices(inliers);
	extract.setNegative(false);
	extract.filter(*cloud_plane);
	std::cout << "PointCloud representing the planar component: " << cloud_plane->size() << " data points." << std::endl;


	pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
	int v1(0);  //创建左窗口显示原始点云
	viewer.createViewPort(0, 0, 0.5, 1.0, v1);  //左右窗口大小划分,1:1
	viewer.setBackgroundColor(0, 0, 0, v1);
	viewer.addText("Cloud Original", 2, 2, "Cloud Original", v1);  //窗口下的标题
	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> rgb1(cloud, "z");
	viewer.addPointCloud<pcl::PointXYZ>(cloud, rgb1, "original cloud", v1);
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "original cloud", v1);
	viewer.addCoordinateSystem(1.0, "original cloud", v1);
	int v2(1);  //创建右窗口显示分割后的平面
	viewer.createViewPort(0.5, 0, 1.0, 1.0, v2);  //左右窗口大小划分,1:1
	viewer.setBackgroundColor(0, 0, 0, v2);
	viewer.addText("Cloud Segmentation", 2, 2, "Cloud Segmentation", v2);  //窗口下的标题
	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> rgb2(cloud_plane, "z");
	viewer.addPointCloud<pcl::PointXYZ>(cloud_plane, rgb2, "plane cloud", v2);
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "plane cloud", v2);
	viewer.addCoordinateSystem(1.0, "plane cloud", v2);

	viewer.spin();

	return (0);
}

5.效果

点云分割--RANSAC平面分割_第1张图片

你可能感兴趣的:(PCL-点云处理,自动驾驶,算法)