OK,本篇作为PCL学习笔记,希望同道之人互相交流、讨论!有误之处希望指出,欢迎留言
PCL库中包含几个重要的模块库:FIilter(过滤器)、Features(特征)、Keypoints(关键点)、Registration(配准)、Kd-tree、Octree(八叉树)、Segementation(分割)、Sample consensus(样本一致性)、Surface(表面)、Range image(深度图)、I/O(输入输出)、Visualization(可视化)、Common(公共)、Search(搜索)
Filter模块库:去除点云中不需要的点和点云的投影。
下面用不同方法对点云进行滤波处理:
目录
- Passthrough Filter(直通滤波):
- VoxelGrid Filter(体素化网格滤波):
- StatisticalOutlierRemoval(统计学的(稀疏)离群点去除):
- Projecting points using a parameter model(投影滤波):
- Extracting indices from a PointCloud(点云索引提取点云子集):
- RadiusOutlierRemoval或ConditionalRemoval滤波器:
1.Passthrough Filter(直通滤波):限定某个字段(理解为点云的变量参数)的范围来达到去除异常点效果关键:
步骤:输入点云-创建滤波器对象-设置字段范围-保存滤波后点云
头文件:#include<pcl/filters/passthrough.h>
代码:pcl::PassThrough<pcl::PointXYZ>pass;//创建滤波器对象
pass.setInputCloud(cloud); //调用成员函数输入点云,cloud为已创建的点云对象
pass.setFilterFieldName("z"); //调用设置字符串函数,z为设定字段对应字符串
pass.setFilterLimits(0,2.0); //调用范围设置函数,z的范围在0-2
pass.filter(*cloud_filtered); //执行直通过滤,并将执行结果被保存在cloud_filtered
完整代码(直通滤波):
#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);
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 (const auto& point : *cloud)
std::cerr << " " << point.x << " "
<< point.y << " "
<< point.z << std::endl;
//直通滤波----
pcl::PassThrough<pcl::PointXYZ> pass;
pass.setInputCloud(cloud);
pass.setFilterFieldName("z");
pass.setFilterLimits(0,1.0);
pass.filter(*cloud_filtered);
//滤波结束,结果保存在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);
}
执行结果
Cloud before filtering:
-0.0164185 -0.177155 0.0244751
-0.194244 0.169983 -0.147095
0.277649 -0.317963 -0.36441
0.166901 0.220856 0.144196
-0.467896 0.15387 -0.345825
Cloud after filtering:
-0.0164185 -0.177155 0.0244751
0.166901 0.220856 0.144196
2.VoxelGrid Filter(体素化网格滤波):创建一个3D体素网格,每个体素中所有点将由质心来代替,将体素想象为立方体。
步骤:输入点云-创建滤波器对象-设置立方体大小-保存滤波后点云-可视化
头文件:#include <pcl/filters/voxel_grid.h>
代码:#include <pcl/io/pcd_io.h>
#include <pcl/io/io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/cloud_viewer.h>
#include <boost/thread/thread.hpp>
#include <pcl/point_cloud.h>
#include<iostream>
#include <pcl/features/normal_3d.h>
using namespace std;
typedef pcl::PointXYZ PointT;
int main(int argc, char** argv)
{
pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>); //待滤波点云
///读入点云数据
cout << "->正在读入点云..." << endl;
/*pcl::io::loadPCDFile("rabbit.pcd", *cloud);*/
pcl::PCDReader reader;
reader.read("E:\\PCLNotes\\practice\\rabbit.pcd", *cloud);
cout << "\t\t<读入点云信息>\n" << *cloud << endl;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>); //滤波后点云
///体素滤波器点云下采样
cout << "->正在体素下采样..." << endl;
pcl::VoxelGrid<pcl::PointXYZ> vg; //创建滤波器对象
vg.setInputCloud(cloud); //设置待滤波点云
vg.setLeafSize(1.15f, 1.15f, 1.15f); //设置体素大小
vg.filter(*cloud_filtered); //执行滤波,保存滤波结果于cloud_filtered
///保存下采样点云
cout << "->正在保存下采样点云..." << endl;
pcl::PCDWriter writer;
writer.write("sub.pcd", *cloud_filtered, true);
cout << "\t\t<保存点云信息>\n" << *cloud_filtered << endl;
/*return 0;
}*/
//================================= 滤波前后对比可视化 =================================
/*pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("滤波前后对比"));*/
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
viewer->initCameraParameters();//初始化相机参数
/*-----视口1-----*/
int v1(0);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); //设置第一个视口在X轴、Y轴的最小值、最大值,取值在0-1之间
viewer->setBackgroundColor(0, 0, 0, v1); //设置背景颜色,0-1,默认黑色(0,0,0)
viewer->addText("befor_filtered", 10, 10, "v1_text", v1);
viewer->addPointCloud<pcl::PointXYZ>(cloud, "befor_filtered_cloud", v1);
/*-----视口2-----*/
int v2(0);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);
viewer->addText("after_filtered", 10, 10, "v2_text", v2);
viewer->addPointCloud<pcl::PointXYZ>(cloud_filtered, "after_filtered_cloud", v2);
/*-----设置相关属性-----*/
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "befor_filtered_cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "befor_filtered_cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "after_filtered_cloud", v2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "after_filtered_cloud", v2);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
执行结果:
问题:
解决方法:https://blog.csdn.net/huhu7777/article/details/125358022