官方代码解析
首先解析一波官方代码:
pcl::PCDReaderreader;//定义读取对象
reader.read<pcl::PointXYZ>("table_scene_lms400.pcd",*cloud);//读取点云文件
然后,创建了一个pcl::StatisticalOutlierRemoval滤波器,将对每个点分析的临近点个数设为50,并将标准差倍数设为1,这意味着如果一个点的距离超出平均距离一个标准差以上,则该点被标记为离群点,并将被移除。计算后的输出结果储存在cloud_filtered中。
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;// 创建滤波器对象
sor.setInputCloud(cloud); //设置呆滤波的点云
sor.setMeanK(50); //设置在进行统计时考虑查询点邻近点数
sor.setStddevMulThresh(1.0); //设置判断是否为离群点的阈值
sor.filter(*cloud_filtered); //执行滤波处理保存内点到cloud_filtered
剩下的数据(内部点)将被存入磁盘,以供其他使用,例如可视化等。
pcl::PCDWriterwriter;
writer.write<pcl::PointXYZ>("table_scene_lms400_inliers.pcd",*cloud_filtered,false);
然后,使用同样的参数再次调用该滤波器,但是利用函数setNegative设置使输出取外点,以获取离群点数据(也就是原本滤除掉的点)。
sor.setNegative(true);
sor.filter(*cloud_filtered);
并将数据写回到磁盘。
writer.write<pcl::PointXYZ>("table_scene_lms400_outliers.pcd",*cloud_filtered,false);
实战数据:
#include <iostream>
#include <vector>
#include <ctime>
//---------------------------------------------
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/vtk_lib_io.h> //obj读取头文件
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
//-法向显示错误:no override found for vtkActor--
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
//outlier
#include <pcl/filters/statistical_outlier_removal.h>
using namespace std;
int main() {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr bottom(new pcl::PointCloud<pcl::PointXYZ>);
//-------------------------------读取点云文件---------------------------------------------------
pcl::PolygonMesh mesh;
if (pcl::io::loadPolygonFile("D:/pcd/shoeData/0422/0423-1.obj", mesh) == -1)
{
cout << "COULD NOT READ FILE mid.pcl \n";
system("pause");
return (-1);
}
pcl::fromPCLPointCloud2(mesh.cloud, *cloud);
cout << "points sieze is:" << cloud->size() << endl;
//outlier
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud(cloud);
sor.setMeanK(200); //设置在进行统计时考虑查询点邻近点数
sor.setStddevMulThresh(1.0); //设置判断是否为离群点的阈值,如果一个点的距离超出平均距离一个标准差以上,则该点被标记为离群点,并将被移除。
sor.filter(*cloud_filtered);
//---------------------------------显示---------------------------------------------------------------------
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D viewer"));
int v1(0);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);//xmin, ymin, xmax, ymax,取值范围0-1
viewer->setBackgroundColor(0, 0, 0, v1);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green0(cloud, 0, 225, 0);
viewer->addPointCloud(cloud, green0, "cloud", v1);
int v2(0);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->setBackgroundColor(0.3, 0.3, 0.3, v2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green1(cloud_filtered, 0, 225, 0);
viewer->addPointCloud(cloud_filtered, green1, "cloud_filtered", v2);
while (!viewer->wasStopped()) {
viewer->spinOnce(100);
}
system("pause");
return 0;
}