本教程演示如何使用已知系数的几何模型,例如平面或球体,对一个点云进行滤波操作。
代码如下
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/model_outlier_removal.h>
#include <pcl/segmentation/sac_segmentation.h>
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
// 人为填充点云数据
cloud->width = 50 ;
cloud->height = 1 ;
cloud->points.resize (cloud->width * cloud->height);
for (auto & point: *cloud)
{
point.x = 1024 * rand () / (RAND_MAX + 1.0f);
point.y = 1024 * rand () / (RAND_MAX + 1.0f);
point.z = 1.0;
}
// 制造 3 个 outlier
(*cloud)[0].z = 2.0;
(*cloud)[3].z = -2.0;
(*cloud)[6].z = 4.0;
// 进行平面分割,这应该都很简单了
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
pcl::SACSegmentation<pcl::PointXYZ> seg ;
seg.setModelType(pcl::SACMODEL_PLANE) ;
seg.setMethodType(pcl::SAC_RANSAC) ;
seg.setDistanceThreshold(0.01) ;
seg.setInputCloud(cloud) ;
seg.segment(*inliers, *coefficients) ;
// 看看得到的平面的系数
std::cout << "Model coefficients: " << coefficients->values[0] << " "
<< coefficients->values[1] << " "
<< coefficients->values[2] << " "
<< coefficients->values[3] << std::endl;
// 开始对点云进行平面滤波
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane_filtered (new pcl::PointCloud<pcl::PointXYZ>) ;
pcl::ModelOutlierRemoval<pcl::PointXYZ> plane_filter;
plane_filter.setModelCoefficients (*coefficients); // 把得到的平面的系数丢进去
plane_filter.setThreshold (2); // 距离平面 2 米之内的点不被认为是 outlier 这里的阈值根据需要设置
plane_filter.setModelType (pcl::SACMODEL_PLANE); // 设置模型的类型,当然是平面模型啦
plane_filter.setInputCloud (cloud); // 把原始点云丢进去
plane_filter.setNegative(true) ; // 想得到 outlier 就设置为 true 想得到 inlier 就设置为 false
plane_filter.filter (*cloud_plane_filtered); // 这就是最终得到的滤波之后的点云啦
std::cout << "cloud_plane_filtered->points.size = " << cloud_plane_filtered->points.size() << std::endl;
// 以下仅仅只是可视化部分,帮助理解
pcl::visualization::PCLVisualizer viewer ;
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> blue (cloud_plane_filtered, 0, 255, 0);
viewer.addPointCloud(cloud_plane_filtered, blue, "cloud") ;
viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "cloud");
viewer.addCoordinateSystem (2.0);
while (!viewer.wasStopped())
{
viewer.spinOnce() ;
}
return 0;
}
咱的原始点云长这样
可以很清晰的看见有一堆点位于某个平面上,而存在 3 个 outlier
滤波之后将会得到位于平面上的那些点
评论(0)
您还未登录,请登录后发表或查看评论