直通滤波:pcl::PassThrough类
过滤掉点云某个纬度下指定区域内(或者外)的点,用于消除背景等操作。
先来个自定义的点云数据滤波:
#include
#include
#include
using namespace std;
int main()
{
//定义一个点云对象和滤波后的点云对象
pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
pcl::PointCloud::Ptr cloud_filtered(new pcl::PointCloud);
//用随机数添加点云数据
srand(time(0));
//指定点云数据大小
cloud->width = 10;
cloud->height = 1;
cloud->points.resize(size_t(cloud->width) * size_t(cloud->height));
for (size_t i = 0; i < cloud->size(); i++)
{
cloud->points[i].x = rand() / (RAND_MAX + 1.0f) - 0.5;
cloud->points[i].y = rand() / (RAND_MAX + 1.0f) - 0.5;
cloud->points[i].z = rand() / (RAND_MAX + 1.0f) - 0.5;
}
//查看一下创建好的点云数据
cout << "The src cloud:" << endl;
for (size_t i = 0; i < cloud->size(); i++)
{
cout << "x: " << cloud->points[i].x << " y: " << cloud->points[i].y << " z: " << cloud->points[i].z << endl;
}
/***********************************重点来了*********************************************************/
//创建滤波器
pcl::PassThrough pass; //定义一个直通滤波类
pass.setInputCloud(cloud); //设置数据集
pass.setFilterFieldName("z"); //指定滤波纬度
pass.setFilterLimits(0.0, 0.2); //指定滤波范围
pass.setNegative(true); //true:过滤掉指定范围的点,保留范围外的点;false时相反
pass.filter(*cloud_filtered); //执行滤波,返回滤波后的数据
/***********************************重点来了*********************************************************/
//查看一下滤波后的点云数据
cout << "The filter cloud:" << endl;
for (size_t i = 0; i < cloud_filtered->size(); i++)
{
cout << "x: " << cloud_filtered->points[i].x << " y: " << cloud_filtered->points[i].y << " z: " << cloud_filtered->points[i].z << endl;
}
return 0;
}
pass.setNegative(true); 过滤掉z值为0-0.2的点
pass.setNegative(false); 过滤掉0-0.2以外的点
如何对多个纬度进行过滤?当然是先过滤一个纬度,然后将剩下的点再对另一个纬度进行过滤,这里可以通过点的索引进行处理。
#include
#include
#include
#include
#include
#include
using namespace std;
//Demo2
int main()
{
//定义对象指针
pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
pcl::PointCloud::Ptr cloud_filterd(new pcl::PointCloud);
//加载pcd文件
pcl::io::loadPCDFile("D:/bunny.pcd", *cloud);
cout << "点云个数:" << cloud->size() << "个" << endl;
//定义带参数(true)的直通滤波
pcl::PassThrough pass(true);
pass.setInputCloud(cloud);
pass.setFilterFieldName("x");
pass.setNegative(true);
pass.setFilterLimits(0.0, 0.5);
//保留下的数据索引
std::vector indices_x;
pass.filter(indices_x);
//获取过滤掉的点的索引
pcl::IndicesConstPtr indices_rem = pass.getRemovedIndices();
pcl::IndicesPtr index_ptr_x = std::make_shared>(indices_x);
//将保留下来的点的索引代替输入的数据集
pass.setIndices(index_ptr_x);
pass.setFilterFieldName("z");
pass.setFilterLimits(0.0, 0.5);
pass.setNegative(true);
std::vector indices_xz;
pass.filter(*cloud_filterd);
cout << "点云个数:" << cloud_filterd->size() << "个" << endl;
//显示对比
boost::shared_ptr viewer(new pcl::visualization::PCLVisualizer("showcloud"));
int v1(0);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer->setBackgroundColor(0, 0, 0, v1);
viewer->addText("Src data", 10, 10, "v1", v1);
int v2(0);
viewer->createViewPort(0.5, 0.0, 1, 1.0, v2);
viewer->setBackgroundColor(0.1, 0.1, 0.1, v2);
viewer->addText("filter data", 10, 10, "v2", v2);
viewer->addPointCloud(cloud, "src cloud", v1);
viewer->addPointCloud(cloud_filterd, "filterd cloud", v2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "src cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "filterd cloud", v2);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
查看结果:
参考文献:
PCL 直通滤波器_点云侠的博客-CSDN博客_直通滤波原理
PCL滤波介绍(1) - Being_young - 博客园