PCL——基于平面模型的点云分割(地面点云分割)(Plane Model Segmentation)
程序员文章站
2024-03-25 10:41:18
...
运行环境:
VS2013,PCL1.8.0
代码参考:
http://pointclouds.org/documentation/tutorials/
最近做的项目需要对采集到的点云场景进行去除地面的操作。在参考了CSDN博主:有梦想的田园犬对于PCL官方几种例程中的点云分割方法的实验后,考虑到系统的实时性要求,选择基于平面模型的地面点云去噪方法。
1、算法细节
该方法是利用RANSAC去找到点云中的平面,简单总结RANSAC的原理:通过随机采样,只利用有效的数据实现最优的拟合效果(如有不对望指正)。具体的原理可以参考随机抽样一致算法(Random sample consensus,RANSAC)。
2、调参
这个方法需要调节的参数就只有一个,setDistanceThreshold,距离阈值(PCL中单位为m)。距离阈值越大,离平面越远的点也被算作平面的组成。
#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/filters/extract_indices.h>
void viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
viewer.setBackgroundColor(0,0,1);
}
int
main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
// 读入点云PCD文件
reader.read("3dpoints.pcd",*cloud);
std::cerr << "Point cloud data: " << cloud->points.size () << " points" << std::endl;
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
// Create the segmentation object
pcl::SACSegmentation<pcl::PointXYZ> seg;
// Optional
seg.setOptimizeCoefficients (true);
// Mandatory
seg.setModelType (pcl::SACMODEL_PLANE);
seg.setMethodType (pcl::SAC_RANSAC);
// 距离阈值 单位m
seg.setDistanceThreshold (0.15);
seg.setInputCloud (cloud);
seg.segment (*inliers, *coefficients);
if (inliers->indices.size () == 0)
{
PCL_ERROR ("Could not estimate a planar model for the given dataset.");
return (-1);
}
// 提取地面
pcl::ExtractIndices<pcl::PointXYZ> extract;
extract.setInputCloud (cloud);
extract.setIndices (inliers);
extract.filter (*cloud_filtered);
std::cerr << "Ground cloud after filtering: " << std::endl;
std::cerr << *cloud_filtered << std::endl;
pcl::PCDWriter writer;
writer.write<pcl::PointXYZ> ("3dpoints_ground.pcd", *cloud_filtered, false);
// 提取除地面外的物体
extract.setNegative (true);
extract.filter (*cloud_filtered);
std::cerr << "Object cloud after filtering: " << std::endl;
std::cerr << *cloud_filtered << std::endl;
writer.write<pcl::PointXYZ> ("3dpoints_object.pcd", *cloud_filtered, false);
// 点云可视化
pcl::visualization::CloudViewer viewer("Filtered");
viewer.showCloud(cloud_filtered);
viewer.runOnVisualizationThreadOnce(viewerOneOff);
while(!viewer.wasStopped()){
}
return (0);
}
作者:Di_Wong
来源:CSDN
原文:https://blog.csdn.net/Di_Wong/article/details/81507626
版权声明:本文为博主原创文章,转载请附上博文链接!