目录
PCL直通滤波使用和点云打印
除了对PCL直通滤波的常用基本功能实现,具体看注释。
说明了多维度直通滤波的用法,即卡多个阈值得到点云结果,例如PointXYZ,对“x” “y” 三个值都需要卡阈值时的使用方法;
/*20201022 by 手口一斤*/
#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int
testfilters_passthrough(int argc, char** argv)
{
srand(time(0));
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_xz(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_xyz(new pcl::PointCloud<pcl::PointXYZ>);
//填入点云数据
cloud->width = 10;
cloud->height = 1;
cloud->points.resize(cloud->width * cloud->height);
for (size_t i = 0; i < cloud->points.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;
}
std::cerr << "Cloud before filtering: " << std::endl;
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;
// 创建滤波器对象,第一次对Z卡阈值
pcl::PassThrough<pcl::PointXYZ> pass(true);
pass.setInputCloud(cloud);
pass.setFilterFieldName("z"); //通过z滤波
pass.setFilterLimits(0.0, 1.0);
pass.setNegative (true);//设置为true,则输出范围外的点
pass.filter(*cloud_filtered);
// 第二次对X卡阈值滤波
pcl::IndicesConstPtr cloud_filtered_other = pass.getRemovedIndices();//获取上一步剩下的点,即cloud_filtered以外的点
pass.setIndices(cloud_filtered_other); //对cloud_filtered_other中的点进行滤波处理
pass.setFilterFieldName("x");
pass.setFilterLimits(0.0, 1.0);
pass.setNegative(false);
pass.filter(*cloud_filtered_xz);
//这样滤波也能成功,但是结果不对,所以想多次滤波还是按照上面的方式
//pass.setInputCloud(cloud_filtered_xz);
//pass.setFilterFieldName("y");
//pass.setFilterLimits(-1.0,0.0);
//pass.filter(*cloud_filtered_xyz);
std::cerr << "Cloud after filtering: " << std::endl;
for (size_t i = 0; i < cloud_filtered->points.size(); ++i)
std::cerr << " " << cloud_filtered->points[i].x << " "
<< cloud_filtered->points[i].y << " "
<< cloud_filtered->points[i].z << std::endl;
std::cerr << "Cloud after filtering2: " << std::endl;
for (size_t i = 0; i < cloud_filtered_xz->points.size(); ++i)
std::cerr << " " << cloud_filtered_xz->points[i].x << " "
<< cloud_filtered_xz->points[i].y << " "
<< cloud_filtered_xz->points[i].z << std::endl;
//std::cerr << "Cloud after filtering3: " << std::endl;
//for (size_t i = 0; i < cloud_filtered_xyz->points.size(); ++i)
// std::cerr << " " << cloud_filtered_xyz->points[i].x << " "
// << cloud_filtered_xyz->points[i].y << " "
// << cloud_filtered_xyz->points[i].z << std::endl;
//return (0);
}
运行结果
点的数值不一样,因为可能是随机生成的
直通滤波的原理
先规定要卡值的对象,例如X,Y,Z,I,R,G,B等,取得或者去掉某一个值范围外的点集;
直通滤波的使用场景和使用体验
卡出或者卡掉某一个维度取值在一定范围内的点,适合点云初步卡ROI区域;
适合点云分布较分散的情况,根据某一些值可得到目标点云;
适合简单卡掉或者卡出异常值;
运算速度比较快,适合大点云小点云卡范围;
不适合卡出非常复杂的范围的情况,不好验证;
参考:https://pcl.readthedocs.io/projects/tutorials/en/latest/passthrough.html#passthrough