直通滤波(PassThrough filter)
这个滤波很直接,就是按照我们的设置的要求直接进行滤波,例如我们可以通过直通滤波直接得到z分量在(0-500)的点云。
code
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
// Fill in the cloud data
cloud->width = 5;
cloud->height = 1;
cloud->points.resize(cloud->width * cloud->height);
for (auto& point : *cloud)
{
point.x = 1024 * rand() / (RAND_MAX + 1.0f);
point.y = 1024 * rand() / (RAND_MAX + 1.0f);
point.z = 1024 * rand() / (RAND_MAX + 1.0f);
}
std::cerr << "Cloud before filtering: " << std::endl;
for (const auto& point : *cloud)
std::cerr << " " << point.x << " "
<< point.y << " "
<< point.z << std::endl;
// Create the filtering object
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud(cloud);
pass.setFilterFieldName("z");
pass.setFilterLimits(0.0, 500);
//pass.setFilterLimitsNegative (true);
pass.filter(*cloud_filtered);
std::cerr << "Cloud after filtering: " << std::endl;
for (const auto& point : *cloud_filtered)
std::cerr << " " << point.x << " "
<< point.y << " "
<< point.z << std::endl;
return (0);
}
结果
体素滤波(VoxelGrid filter)
体素滤波可以用于实现降采样,可以减小点云数据规模,加快点云处理速度。体素可以看作是3D空间的像素,是空间中的一个一个均匀划分的小方块,具体可自行区查找。
code
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
int main()
{
pcl::PCLPointCloud2::Ptr cloud(new pcl::PCLPointCloud2());
pcl::PCLPointCloud2::Ptr cloud_filtered(new pcl::PCLPointCloud2());
// Fill in the cloud data
pcl::PCDReader reader;
// Replace the path below with the path where you saved your file
reader.read("table_scene_lms400.pcd", *cloud); // Remember to download the file first!
std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height
<< " data points (" << pcl::getFieldsList(*cloud) << ")." << std::endl;
// Create the filtering object
pcl::VoxelGrid<pcl::PCLPointCloud2> sor;
sor.setInputCloud(cloud);
sor.setLeafSize(0.01f, 0.01f, 0.01f);
sor.filter(*cloud_filtered);
std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
<< " data points (" << pcl::getFieldsList(*cloud_filtered) << ")." << std::endl;
pcl::PCDWriter writer;
writer.write("table_scene_lms400_downsampled.pcd", *cloud_filtered,
Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), false);
return (0);
}
结果
离群点滤波器(StatisticalOutlierRemoval filter)
可以去除离群点,其原理是计算每个点与其周围点的平均距离,该距离应该服从高斯分布,通过均值与标准差来确定野点并去除。(其实也就是去除那些看起来孤立的点,这些点一般就是野点)
code
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
// Fill in the cloud data
pcl::PCDReader reader;
// Replace the path below with the path where you saved your file
reader.read<pcl::PointXYZ>("table_scene_lms400.pcd", *cloud);
std::cerr << "Cloud before filtering: " << std::endl;
std::cerr << *cloud << std::endl;
// Create the filtering object
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud(cloud);
//选取的临近点的个数为50
sor.setMeanK(50);
//标准差的一倍作为阈值,即去除在(u-e,u+e)的点
sor.setStddevMulThresh(1.0);
sor.filter(*cloud_filtered);
std::cerr << "Cloud after filtering: " << std::endl;
std::cerr << *cloud_filtered << std::endl;
pcl::PCDWriter writer;
writer.write<pcl::PointXYZ>("table_scene_lms400_inliers.pcd", *cloud_filtered, false);
sor.setNegative(true);
sor.filter(*cloud_filtered);
writer.write<pcl::PointXYZ>("table_scene_lms400_outliers.pcd", *cloud_filtered, false);
return (0);
}
结果
去除前后的点云分别如下所示: