一、 算法原理
直通滤波器:class pcl: : PassThrough<< PointT >
对指定维度(X,Y,Z,BGR等)进行某一个范围滤波,可以删除这个范围内部点,也可以删除这个范围外部的点。
类 PassThrough 实现对用户给定点云某个字段的限定下 , 对点云进行简单的基本过滤 , 例如限制过滤掉点云中所有 X 字段不在某个范围内的点 , 该类的使用比较灵活但完全取欧于用户的限定字段和对应条件。
关键函数
关键成员函数 :
void setFilterFieldName (const std: :string &.field_name)
设置限定字段的名称字符串 field_name, 例如“z“等。
void setFilterLimits (const double &limit_min, const double & limit_max)
设置滤波限制条件 , 包括最小值 limit_min 和最大值 limit_max。该函数与 setFilterFieldName( 一起使用 , 点云中所有点的 setFilterFieldName( ) 设置的字段的值未在用户所设定区间范围外的点将被删除。参数 limit_min 为允许的区间范围的最小值 , 默认为 DBL _ MIN, limit_max 为允许的区间范围的最大值 , 默认为DB L_MAX。
void getFilterLimitsNegative (bool &limit_negative)
设置返回滤波限制条件外的点还是内部点,limit_negative默认值是false,输出点云为在设定字段的设定范围内的点,设为true则正好相反。
二、代码实例
1. 代码示例1
#include <QCoreApplication>
#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int
main ()
{ 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>);
//填入点云数据
cloud->width = 5;
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;
// 创建滤波器对象
pcl::PassThrough<pcl::PointXYZ> pass; //设置滤波器对象
pass.setInputCloud (cloud); //设置输入点云
pass.setFilterFieldName ("z"); //设置过滤时所需要的点云类型的Z字段
pass.setFilterLimits (0.0, 1.0); //设置在过滤字段上的范围
//pass.setFilterLimitsNegative (true); //设置保留范围内的还是过滤掉范围内的
pass.filter (*cloud_filtered);
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;
return (0);
}
2.代码示例2
#include <iostream>
#include <string>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
#include <pcl/common/common.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>
using namespace std;
typedef pcl::PointXYZ PointType;
int main(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
//创建存储模型系数的对象
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
pcl::PointIndices::Ptr inliers (new pcl::PointIndices); // 创建存贮内点的索引
pcl::SACSegmentation<pcl::PointXYZ> seg; //此类是利用采样一致性算法实现的分割,即创建一个分割器
seg.setOptimizeCoefficients(true); //可选。这一步主要是优化模型系数
seg.setModelType(pcl::SACMODEL_PLANE); //分割类型为平面
seg.setMethodType(pcl::SAC_RANSAC); //方法
seg.setDistanceThreshold(0.1); //设置距离阀值,可调节分割平面的点数(平面精度),需要根据实际采样点集设置
seg.setInputCloud(cloud);
seg.segment(*inliers, *coefficients); //coefficients存储平面参数,inlier为平面点索引
/*提取平面点*/
pcl::ExtractIndices<pcl::PointXYZ> extract;
extract.setInputCloud(cloud);
extract.setIndices(inliers);
extract.setNegative(false); //设置提取平面点。(若为true,则是提取的非平面点,inliers之外的点)
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_p (new pcl::PointCloud<pcl::PointXYZ>);
extract.filter(*cloud_p); //最终cloud_p为平面点云
//visualization
pcl::visualization::PCLVisualizer viewer;
pcl::visualization::PointCloudColorHandlerCustom<PointType> tc_handler(cloud_p, 0, 0, 0); //转换到原点的点云相关
viewer.addPointCloud(cloud_p, tc_handler, "transformCloud");
viewer.setBackgroundColor(1.0, 1.0, 1.0);
while (!viewer.wasStopped())
{
viewer.spinOnce(100);
}
//保存结果
pcl::io::savePCDFile("result.pcd",*cloud_p);
return 0;
}
三、结果展示
示例1结果展示
示例2结果展示