点云滤波
滤波
在获取点云数据时,由于设备精度、操作者经验、环境因素等带来的影响,点云数据中不可避免的出现了一些噪声点(就是自己用不到的点),我们在处理数据时,需要把这些点去除掉,这个过程叫滤波。
一、pcl中的点云滤波方案
(1)点云数据密度不规则需要平滑
(2)因为遮挡等问题造成离群点需要去除
(3)大量数据需要进行下采样(Downsample)。
(4)噪声数据需要去除。
对应方法如下:
(1)按具体给定的规则限制过滤去除点。
(2)通过常用滤波算法修改点的部分属性。
(3)对数据进行下采样。
直通滤波器
直通滤波器:对于在空间分布有一定空间特征的点云数据,比如使用线结构光扫描的方式采集点云,沿z向分布较广,但x,y向的分布处于有限范围内。此时可使用直通滤波器,确定点云在x或y方向上的范围,可较快剪除离群点,达到第一步粗处理的目的。
#include<iostream>
#include<pcl/point_types.h>
#include<pcl/filters/passthrough.h> //直通滤波器头文件
using namespace std;
int main()
{
///****************************************************
/*创建点云数据集。*/
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
cloud->width = 500;
cloud->height = 1;
cloud->points.resize(cloud->width*cloud->height);
std::cout << "创建原始点云数据" << std::endl;
for (size_t i = 0; i < cloud->points.size(); ++i)
{
cloud->points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud->points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud->points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
for (size_t i = 0; i < cloud->points.size(); i++)
{
std::cerr << " " << cloud->points[i].x << " "
<< cloud->points[i].y << " "
<< cloud->points[i].z << std::endl;
}
std::cout << "原始点云数据点数:" << cloud->points.size()<< std::endl << std::endl;
///****************************************************
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_after_PassThrough(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PassThrough<pcl::PointXYZ> passthrough;
passthrough.setInputCloud(cloud);//输入点云
passthrough.setFilterFieldName("z");//对z轴进行操作
passthrough.setFilterLimits(0.0, 400.0);//设置直通滤波器操作范围
//passthrough.setFilterLimitsNegative(true);//true表示保留范围内,false表示保留范围外
passthrough.filter(*cloud_after_PassThrough);//执行滤波,过滤结果保存在 cloud_after_PassThrough
std::cout << "直通滤波后点云数据点数:" << cloud_after_PassThrough->points.size() << std::endl;
std::cerr<<"cloud afer filtering:"<<std::endl;
for(size_i=0;i<cloud_after_PassThrough->points.size();++i)
{
std::cerr<<""<<cloud_after_PassThrough->points[i]