PCL专栏目录及须知-CSDN博客
1.原理
可选取pcd点云中可获取的某个字段(如pcl::PointXYZRGB中的x、y、z等字段),进行and或or的条件判断,以达到过滤某个范围内的值的结果。
条件滤波器有两个子类,其中pcl::ConditionAnd<pcl::PointXYZRGB>意味着“且”,pcl::ConditionOr<pcl::PointXYZRGB>意味着“或”。
2.使用场景
多用于删除/过滤某个字段下某个范围的值,例如车道点云中通过z值条件过滤,删除地面以上的树木、建筑物等,只留下道路,以实现道路点云的初步过滤。
如下图
3.关键函数
(1)
1)条件A 且 条件B,使用该条件函数类。
pcl::ConditionAnd<pcl::PointXYZRGB>
2)条件A 或 条件B,使用该条件函数类。
pcl::ConditionOr<pcl::PointXYZRGB>
(2)
1)本函数设置true则保持原始点云的结构,点的数目没有减少,滤波掉的点采用nan代替。设置为false则不保存原始点云结构,滤波掉的点删除。
setKeepOrganized()
2)删除NAN点,与setKeepOrganized()方法联动使用
std::vector<int> mapping;
pcl::removeNaNFromPointCloud(*cloud_filtered, *cloud_filtered, mapping); // 去除nan点
4.代码
#include <iostream>
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/conditional_removal.h> //条件滤波
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
int main()
{
/****************条件滤波********************/
// 原始点云
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>());
pcl::io::loadPCDFile("D:/code/csdn/data/two_tree.pcd", *cloud); // 加载原始点云数据
// 结果点云
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZRGB>);
// 字段
pcl::ConditionAnd<pcl::PointXYZRGB>::Ptr field(new pcl::ConditionAnd<pcl::PointXYZRGB>); // 字段
/*
pcl::ComparisonOps::GT // 大于
pcl::ComparisonOps::GE // 大于等于
pcl::ComparisonOps::LT // 小于
pcl::ComparisonOps::LE // 小于等于
pcl::ComparisonOps::EQ // 等于
*/
field->addComparison(pcl::FieldComparison<pcl::PointXYZRGB>::ConstPtr(new pcl::FieldComparison<pcl::PointXYZRGB>("z", pcl::ComparisonOps::GT, -27.0))); // z值大于-27.0
field->addComparison(pcl::FieldComparison<pcl::PointXYZRGB>::ConstPtr(new pcl::FieldComparison<pcl::PointXYZRGB>("z", pcl::ComparisonOps::LT, -24.5))); // “且”z值小于-27.0,若使用ConditionOr,则是“或”z值小于15
pcl::ConditionalRemoval<pcl::PointXYZRGB> filtered; // 条件滤波器
filtered.setCondition(field); // 字段条件
filtered.setInputCloud(cloud); // 输入点云
filtered.setKeepOrganized(false); // 设置true则保持原始点云的结构,点的数目没有减少,滤波掉的点采用nan代替。设置为false则不保存原始点云结构。
filtered.filter(*cloud_filtered); // 滤波
std::vector<int> mapping;
pcl::removeNaNFromPointCloud(*cloud_filtered, *cloud_filtered, mapping); // 去除nan点
/****************展示********************/
boost::shared_ptr<pcl::visualization::PCLVisualizer> view_raw(new pcl::visualization::PCLVisualizer("raw"));
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> raw_rgb(cloud);
view_raw->addPointCloud<pcl::PointXYZRGB>(cloud, raw_rgb, "raw cloud");
view_raw->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "raw cloud");
boost::shared_ptr<pcl::visualization::PCLVisualizer> view_filtered(new pcl::visualization::PCLVisualizer("filter"));
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> filtered_rgb(cloud);
view_filtered->addPointCloud<pcl::PointXYZRGB>(cloud_filtered, filtered_rgb, "filtered cloud");
view_filtered->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "filtered cloud");
while (!view_raw->wasStopped())
{
view_raw->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
while (!view_filtered->wasStopped())
{
view_filtered->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}