点云库PCL学习——几种滤波方式

一、下采样

一般下采样是通过构造一个三维体素栅格,然后在每个体素内用体素内的所有点的重心近似显示体素中的其他点,这样体素内所有点就用一个重心点来表示,进行下采样的来达到滤波的效果,这样就大大的减少了数据量,特别是在配准,曲面重建等工作之前作为预处理,可以很好的提高程序的运行速度。

#pragma warning(disable:4996)
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <pcl/io/pcd_io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>

int
main()
{
	// 创建点云对象
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);

	// 读取PCD文件
	if (pcl::io::loadPCDFile<pcl::PointXYZ>("F:\\C++project\\pig.pcd", *cloud) != 0)
	{
		return -1;
	}
	//typedef pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZI> ColorHandlerT3;
	// 创建滤波对象
	pcl::VoxelGrid<pcl::PointXYZ> filter;
	filter.setInputCloud(cloud);
	// 设置体素栅格的大小为 2x2x2cm
	filter.setLeafSize(0.02f, 0.02f, 0.02f);
	filter.filter(*filteredCloud);
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->initCameraParameters();
	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
	int v2(0);
	viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
	viewer->setBackgroundColor(255, 255, 255,v1);
	viewer->setBackgroundColor(255, 255, 255,v2);
	viewer->addPointCloud(filteredCloud,  "filtered_points",v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "filtered_points");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "filtered_points");
	viewer->addPointCloud(cloud, "input_cloud",v2);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "input_cloud");
	viewer->spin();

}

复制代码

二、均匀采样

均匀采样:这个类基本上是相同的,但它输出的点云索引是选择的关键点在计算描述子的常见方式。

	pcl::UniformSampling<pcl::PointXYZ> filter;
	filter.setInputCloud(cloud);
	filter.setRadiusSearch(0.02f);
	filter.filter(*filteredCloud);

有的版本用法如下:

    pcl::UniformSampling<pcl::PointXYZ> filter;
    filter.setInputCloud(cloud);
    filter.setRadiusSearch(0.01f);
    pcl::PointCloud<int> keypointIndices;
    filter.compute(keypointIndices);
    pcl::copyPointCloud(*cloud, keypointIndices.points, *filteredCloud);

我的版本为1.8,已经没有compute这个函数了。

三、增采样

增采样是一种表面重建方法,当你有比你想象的要少的点云数据时,增采样可以帮你恢复原有的表面(S),通过内插你目前拥有的点云数据,这是一个复杂的猜想假设的过程。所以构建的结果不会百分之一百准确,但有时它是一种可选择的方案。所以,在你的点云云进行下采样时,一定要保存一份原始数据!

利用第一个下采样后的点云图,来进行增采样操作:

#pragma warning(disable:4996)
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <pcl/io/pcd_io.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
#include<pcl/keypoints/uniform_sampling.h>
#include<pcl/surface/mls.h>


int
main()
{
	// 创建点云对象
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr filteredCloud2(new pcl::PointCloud<pcl::PointXYZ>);

	// 读取PCD文件
	if (pcl::io::loadPCDFile<pcl::PointXYZ>("F:\\C++project\\pig.pcd", *cloud) != 0)
	{
		return -1;
	}
	// 创建滤波对象
	pcl::VoxelGrid<pcl::PointXYZ> filter;
	filter.setInputCloud(cloud);
	// 设置体素栅格的大小为 2x2x2cm
	filter.setLeafSize(0.02f, 0.02f, 0.02f);
	filter.filter(*filteredCloud);	

	pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ> filter2;
	filter2.setInputCloud(filteredCloud);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree;
	filter2.setSearchMethod(kdtree);
	filter2.setSearchRadius(0.03);
	filter2.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ>::SAMPLE_LOCAL_PLANE);
	// 采样的半径是
	filter2.setUpsamplingRadius(0.03);
	// 采样步数的大小
	filter2.setUpsamplingStepSize(0.02);
	filter2.process(*filteredCloud2);



	/*pcl::UniformSampling<pcl::PointXYZ> filter;
	filter.setInputCloud(cloud);
	filter.setRadiusSearch(0.02f);
	filter.filter(*filteredCloud);*/
 	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->initCameraParameters();
	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.33, 1.0, v1);
	int v2(0);
	viewer->createViewPort(0.33, 0.0, 0.66, 1.0, v2);
	int v3(0);
	viewer->createViewPort(0.66, 0.0, 1.0, 1.0, v3);

	viewer->setBackgroundColor(255, 255, 255,v1);
	viewer->setBackgroundColor(255, 255, 255,v2);
	viewer->setBackgroundColor(255, 255, 255,v3);
	viewer->addPointCloud(filteredCloud,  "filtered_points",v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "filtered_points");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "filtered_points");
	viewer->addPointCloud(cloud, "input_cloud",v2);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "input_cloud");
	viewer->addPointCloud(filteredCloud2, "filtered2_points", v3);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "filtered2_points");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 0, 0, "filtered2_points");
	viewer->spin();
}

1.下采样之后 2.原始 3.增采样后

猜你喜欢

转载自blog.csdn.net/zzh_AI/article/details/93042852
今日推荐