经典的滤波方法有:直通滤波器,体素滤波器,统计滤波器,条件滤波,半径滤波器,双边滤波,高斯滤波
直通滤波
代码:
#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int main (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>);
//填入点云数据
cloud->width = 5;
cloud->height = 1;
//修改点云的大小
cloud->points.resize (cloud->width * cloud->height);
//建立3组随机数
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);
//滤波字段名被设置为X轴方向
pass.setFilterFieldName ("x");
//设置滤波范围
pass.setFilterLimits (0.0, 1.0);
//pass.setFilterLimitsNegative (true);
//执行滤波,保存结果到cloud_filtered
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);
}
调试数据
体素滤波器(下采样)
代码:
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/range_image_visualizer.h> //深度图可视化
#include<pcl/visualization/cloud_viewer.h>
int main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
// 填入点云数据
pcl::PCDReader reader;
// 把路径改为自己存放文件的路径
reader.read ("C:\\Users\\Empower\\Desktop\\exep\\bunny.pcd", *cloud);
std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height
<< " data points (" << pcl::getFieldsList (*cloud) << ").";
// 创建滤波器对象 体素网格下采样
pcl::VoxelGrid<pcl::PointXYZ> sor;
//设置输入的点云
sor.setInputCloud (cloud);
//点云降采样
sor.setLeafSize (0.01f, 0.01f, 0.01f);
//执行滤波,保存结果到cloud_filtered
sor.filter (*cloud_filtered);
std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
<< " data points (" << pcl::getFieldsList (*cloud_filtered) << ").";
pcl::PCDWriter writer;
cout << "sta" << endl;
//写入文件
writer.write ("2d.pcd", *cloud_filtered, false);
pcl::visualization::CloudViewer viewer1("ddd");//创建点云对象
viewer1.showCloud (cloud_filtered);//显示点云
cout << "ok" << endl;
system("pause");
return (0);
}
调试结果
统计滤波器
代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/visualization/range_image_visualizer.h> //深度图可视化
#include<pcl/visualization/cloud_viewer.h>
int
main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
// 填入点云数据
pcl::PCDReader reader;
reader.read<pcl::PointXYZ> ("C:\\Users\\Empower\\Desktop\\exep\\bunny.pcd", *cloud);
std::cerr << "Cloud before filtering: " << std::endl;
std::cerr << *cloud << std::endl;
// 创建滤波器对象 统计滤波器
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
//设置输入的点云
sor.setInputCloud (cloud);
//设置考虑查询点临近点数
sor.setMeanK (50);
//设置判断是否为离群点的阀值
sor.setStddevMulThresh (1.0);
//执行滤波,保存结果到cloud_filtered
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);
// 然后,使用同样的参数再次调用该滤波器,但是利用函数 setNegative 设置使输出取外点,以获取离群点数据 也就是原本滤除掉的点 。
sor.setNegative (true);
//执行滤波,保存结果到cloud_filtered
sor.filter (*cloud_filtered);
writer.write<pcl::PointXYZ> ("table_scene_lms400_outliers.pcd", *cloud_filtered, false);
pcl::visualization::CloudViewer viewer1("ddd");//创建点云对象
viewer1.showCloud(cloud_filtered);//显示点云
return (0);
}
调试结果
投影滤波:
代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/project_inliers.h>
int
main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected (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 = 1024 * rand () / (RAND_MAX + 1.0f);
cloud->points[i].y = 1024 * rand () / (RAND_MAX + 1.0f);
cloud->points[i].z = 1024 * rand () / (RAND_MAX + 1.0f);
}
std::cerr << "Cloud before projection: " << 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;
// 创建一个系数为X=Y=0,Z=1的平面
pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients ());
//设置四个数学模型系数
coefficients->values.resize (4);
coefficients->values[0] = coefficients->values[1] = 0;
coefficients->values[2] = 1.0;
coefficients->values[3] = 0;
// 创建滤波器对象 投影滤波
pcl::ProjectInliers<pcl::PointXYZ> proj;
//设置投影滤波模型(平面)
proj.setModelType (pcl::SACMODEL_PLANE);
//是指输入点云
proj.setInputCloud (cloud);
//设置模型对应的系数
proj.setModelCoefficients (coefficients);
//投影结果存储
proj.filter (*cloud_projected);
//输出投影结果
std::cerr << "Cloud after projection: " << std::endl;
for (size_t i = 0; i < cloud_projected->points.size (); ++i)
std::cerr << " " << cloud_projected->points[i].x << " "
<< cloud_projected->points[i].y << " "
<< cloud_projected->points[i].z << std::endl;
return (0);
}
调试结果: