《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程

《PCL点云库学习&VS2010(X64)》Part 9 PCL1.72(VTK6.2.0)滤波例程

Part 9 PCL1.72(VTK6.2.0)滤波例程

一、直通滤波

1、新建空的控制台程序:passthrough,属性列表中加入.props属性配置文件。

2、代码passthrough.cpp

#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 (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);
	pass.setFilterFieldName("z");
	pass.setFilterLimits(0.0, 1.0);
	//pass.setFilterLimitsNegative (true);
	pass.filter(*cloud_filtered);//滤波后的数据存储在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);
}

3、运行结果:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程


如果将注释掉的pass.setFilterLimitsNegative (true)加上,则保留了滤波设定范围以外的点,而设定范围以内的点则被过滤掉了:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程


二、voxel_grid滤波

程序1:

单窗口  空的  控制台程序:voxel_grid.cpp

注意:

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

这个程序是不带强度信息的,滤波后也是单色的点,同时把球体注释掉了

cpp:

#include <vtkAutoInit.h>         
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);

#include <iostream>  
#include <pcl/io/pcd_io.h>  
#include <pcl/point_types.h>  
#include <pcl/filters/voxel_grid.h>  
#include <pcl/io/io.h>  
#include <pcl/visualization/cloud_viewer.h>  


int user_data;
void
viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
	viewer.setBackgroundColor(1.0, 0.5, 1.0);
	pcl::PointXYZ o;
	o.x = 1.0;
	o.y = 0;
	o.z = 0;
	//viewer.addSphere(o, 0.25, "sphere", 0);
	std::cout << "i only run once" << std::endl;

}

void
viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{
	static unsigned count = 0;
	std::stringstream ss;
	ss << "Once per viewer loop: " << count++;
	viewer.removeShape("text", 0);
	viewer.addText(ss.str(), 200, 300, "text", 0);
	//FIXME: possible race condition here:  
	user_data++;
}
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::io::loadPCDFile("rabbit.pcd", *cloud);

	// 创建滤波器对象  
	pcl::VoxelGrid<pcl::PointXYZ> 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) << ").";


	pcl::visualization::CloudViewer viewer("Cloud Viewer");
	//showCloud函数是同步的,在此处等待直到渲染显示为止  
	viewer.showCloud(cloud_filtered);
	//该注册函数在可视化时只调用一次  
	viewer.runOnVisualizationThreadOnce(viewerOneOff);
	//该注册函数在渲染输出时每次都调用  
	viewer.runOnVisualizationThread(viewerPsycho);
	while (!viewer.wasStopped())
	{
		//在此处可以添加其他处理  
		user_data++;
	}



	return (0);
}

运行结果:程序运行最好在控制台里运行

1)cd /d D:\PCLWorkspace\8\voxel_grid\Debug

2)voxel_grid.exe

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程

不带强度的滤波后的桌面,滤波后剩余41049个点,不带强度信息,但是可以很好观察整个物体:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程


程序2 :

多窗口程序,空的  控制台程序voxel_grid.cpp

注:该程序带强度信息

cpp:

#include <vtkAutoInit.h>         
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);

#include <iostream>  
#include <pcl/io/pcd_io.h>  
#include <pcl/point_types.h>  
#include <pcl/filters/voxel_grid.h>  
#include <pcl/io/io.h>  
#include <pcl/visualization/cloud_viewer.h>  
#include <boost/thread/thread.hpp>  

int user_data;
void
viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
	viewer.setBackgroundColor(1.0, 0.5, 1.0);
	pcl::PointXYZ o;
	o.x = 1.0;
	o.y = 0;
	o.z = 0;
	viewer.addSphere(o, 0.25, "sphere", 0);
	std::cout << "i only run once" << std::endl;

}

void
viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{
	static unsigned count = 0;
	std::stringstream ss;
	ss << "Once per viewer loop: " << count++;
	viewer.removeShape("text", 0);
	viewer.addText(ss.str(), 200, 300, "text", 0);
	//FIXME: possible race condition here:  
	user_data++;
}
int
main(int argc, char** argv)
{

	pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
	pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>);
	// 填入点云数据  
	pcl::io::loadPCDFile("rabbit.pcd", *cloud);

	// 创建滤波器对象  
	pcl::VoxelGrid<pcl::PointXYZI> 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) << ").";


	pcl::visualization::PCLVisualizer viewer("PCLVisualizer");
	viewer.initCameraParameters();

	int v1(0);
	viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);
	viewer.setBackgroundColor(1.0, 0.5, 1.0, v1);
	viewer.addText("Cloud before voxelgrid filtering", 10, 10, "v1 test", v1);
	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> cloud_color(cloud, "intensity");
	viewer.addPointCloud<pcl::PointXYZI>(cloud, cloud_color, "cloud", v1);

	int v2(0);
	viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);
	viewer.setBackgroundColor(1.0, 0.5, 1.0, v2);
	viewer.addText("Cloud after voxelgrid filtering", 10, 10, "v2 test", v2);
	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> cloud_afterfilter_color(cloud_filtered, "intensity");
	viewer.addPointCloud<pcl::PointXYZI>(cloud_filtered, cloud_afterfilter_color, "cloud_filtered", v2);

	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_filtered");


	while (!viewer.wasStopped())
	{
		//在此处可以添加其他处理  
		user_data++;
		viewer.spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}



	return (0);
}

运行结果:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程


换成table数据后,运行

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程


三、statistical_removal滤波

程序1:

单窗口程序,空的控制台程序

注:编译不通过记得在属性——c/c++——预处理器——预处理器定义中,添加_CRT_SECURE_NO_WARNINGS命令,重新编译即可通过。

cpp:

#include <vtkAutoInit.h>         
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>

#include <pcl/io/io.h>  
#include <pcl/visualization/cloud_viewer.h>  

int user_data;
void
viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
	viewer.setBackgroundColor(1.0, 0.5, 1.0);
	pcl::PointXYZ o;
	o.x = 1.0;
	o.y = 0;
	o.z = 0;
	//viewer.addSphere(o, 0.25, "sphere", 0);
	std::cout << "i only run once" << std::endl;

}

void
viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{
	static unsigned count = 0;
	std::stringstream ss;
	ss << "Once per viewer loop: " << count++;
	viewer.removeShape("text", 0);
	viewer.addText(ss.str(), 200, 300, "text", 0);
	//FIXME: possible race condition here:  
	user_data++;
}

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> ("table_scene_lms400.pcd", *cloud);
  //read data
  pcl::io::loadPCDFile("table_scene_lms400.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);
  sor.filter (*cloud_filtered);

  std::cerr << std::endl << "Cloud after filtering: " << std::endl;
  std::cerr << *cloud_filtered << std::endl;

  pcl::visualization::CloudViewer viewer("Cloud Viewer");
  //showCloud函数是同步的,在此处等待直到渲染显示为止  
  viewer.showCloud(cloud_filtered);
  //该注册函数在可视化时只调用一次  
  viewer.runOnVisualizationThreadOnce(viewerOneOff);
  //该注册函数在渲染输出时每次都调用  
  viewer.runOnVisualizationThread(viewerPsycho);
  while (!viewer.wasStopped())
  {
	  //在此处可以添加其他处理  
	  user_data++;
  }

  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);
}
运行:

table:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程

rabbit:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程

程序2:

多窗口程序,空的  控制台程序statistical_removal.cpp

1)、开头加上四句,否则编译可能不通过

2)、编译不通过记得在属性——c/c++——预编译文件——预处理器定义中,添加_CRT_SECURE_NO_WARNINGS命令,重新编译即可通过。

cpp:

#include <vtkAutoInit.h>           
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>


#include <pcl/io/io.h>  
#include <pcl/visualization/cloud_viewer.h>  
#include <boost/thread/thread.hpp> 

#include <pcl/filters/statistical_outlier_removal.h>

int user_data;
void
viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
	viewer.setBackgroundColor(1.0, 0.5, 1.0);
	pcl::PointXYZI o;
	o.x = 1.0;
	o.y = 0;
	o.z = 0;
	viewer.addSphere(o, 0.25, "sphere", 0);
	std::cout << "i only run once" << std::endl;

}

void
viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{
	static unsigned count = 0;
	std::stringstream ss;
	ss << "Once per viewer loop: " << count++;
	viewer.removeShape("text", 0);
	viewer.addText(ss.str(), 200, 300, "text", 0);
	//FIXME: possible race condition here:  
	user_data++;
}

int
main(int argc, char** argv)
{
	//pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
	//pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>);
	pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
	pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>);
	// 填入点云数据  
	pcl::io::loadPCDFile("table_scene_lms400.pcd", *cloud);

	// 填入点云数据
	//pcl::PCDReader reader;
	// 把路径改为自己存放文件的路径
	//reader.read<pcl::PointXYZI>("table_scene_lms400.pcd", *cloud);
	pcl::io::loadPCDFile("rabbit.pcd", *cloud);

	//std::cerr << "Cloud before filtering: " << std::endl;
	//std::cerr << *cloud << std::endl;
	std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height
		<< " data points (" << pcl::getFieldsList(*cloud) << ").";

	// 创建滤波器对象
	pcl::StatisticalOutlierRemoval<pcl::PointXYZI> sor;//pcl::PointXYZ改为pcl::PointXYZII
	sor.setInputCloud(cloud);
	sor.setMeanK(50);
	sor.setStddevMulThresh(1.0);
	sor.filter(*cloud_filtered);

	//std::cerr << "Cloud after filtering: " << std::endl;
	//std::cerr << *cloud_filtered << std::endl;
	std::cerr << std::endl<<"PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height
		<< " data points (" << pcl::getFieldsList(*cloud_filtered) << ").";

	pcl::visualization::PCLVisualizer viewer("PCLVisualizer");
	viewer.initCameraParameters();

	int v1(0);
	viewer.createViewPort(0.0, 0.0, 0.5,1.0, v1);
	viewer.setBackgroundColor(1.0f, 0.5f, 1.0f, v1);
	viewer.addText("Cloud before statistical_removal filtering", 10, 10, "v1 test", v1);
	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> cloud_color(cloud,"intensity");
	viewer.addPointCloud<pcl::PointXYZI>(cloud, cloud_color, "cloud", v1);

	int v2(0);
	viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);
	viewer.setBackgroundColor(1.0, 0.5, 1.0, v2);
	viewer.addText("Cloud after statistical_removal filtering", 10, 10, "v2 test", v2);
	pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> cloud_afterfilter_color(cloud_filtered, "intensity");
	viewer.addPointCloud<pcl::PointXYZI>(cloud_filtered, cloud_afterfilter_color, "cloud_filtered", v2);

	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud");
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_filtered");

	pcl::PCDWriter writer;
	writer.write<pcl::PointXYZI>("table_scene_lms400_inliers.pcd", *cloud_filtered, false);
	sor.setNegative(true);
	sor.filter(*cloud_filtered);
	writer.write<pcl::PointXYZI>("table_scene_lms400_outliers.pcd", *cloud_filtered, false);

	while (!viewer.wasStopped())
	{
		//在此处可以添加其他处理  
		user_data++;
		viewer.spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return (0);
}

运行:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程


修改元数据为table后的运行结果:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程


三、project_inliers滤波

多窗口 空的 控制台程序:project_inliers.cpp

cpp

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/project_inliers.h>

#include <pcl/io/io.h>  
#include <pcl/visualization/cloud_viewer.h>  
#include <boost/thread/thread.hpp>  

int user_data;
void
viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
	viewer.setBackgroundColor(1.0, 0.5, 1.0);
	pcl::PointXYZ o;
	o.x = 1.0;
	o.y = 0;
	o.z = 0;
	viewer.addSphere(o, 0.25, "sphere", 0);
	std::cout << "i only run once" << std::endl;

}

void
viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{
	static unsigned count = 0;
	std::stringstream ss;
	ss << "Once per viewer loop: " << count++;
	viewer.removeShape("text", 0);
	viewer.addText(ss.str(), 200, 300, "text", 0);
	//FIXME: possible race condition here:  
	user_data++;
}

int
 main (int argc, char** argv)
{
	 pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
	 pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_projected(new pcl::PointCloud<pcl::PointXYZI>);

	 // 填入点云数据  
	 pcl::io::loadPCDFile("table_scene_lms400.pcd", *cloud);

	 std::cerr << "PointCloud before projection: " << cloud->width * cloud->height
		 << " data points (" << pcl::getFieldsList(*cloud_projected) << ").";

  // 创建一个系数为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::PointXYZI> proj;
  proj.setModelType (pcl::SACMODEL_PLANE);
  proj.setInputCloud (cloud);
  proj.setModelCoefficients (coefficients);
  proj.filter (*cloud_projected);

  std::cerr <<std::endl<< "PointCloud after projection: " << cloud_projected->width * cloud_projected->height
	  << " data points (" << pcl::getFieldsList(*cloud_projected) << ").";

  pcl::visualization::PCLVisualizer viewer("PCLVisualizer");
  viewer.initCameraParameters();

  int v1(0);
  viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);
  viewer.setBackgroundColor(1.0, 0.5, 1.0, v1);
  viewer.addText("Cloud before projection", 10, 10, "v1 test", v1);
  pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> cloud_color(cloud, "intensity");
  viewer.addPointCloud<pcl::PointXYZI>(cloud, cloud_color, "cloud", v1);

  int v2(0);
  viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);
  viewer.setBackgroundColor(1.0, 0.5, 1.0, v2);
  viewer.addText("Cloud after projection", 10, 10, "v2 test", v2);
  pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> cloud_afterfilter_color(cloud_projected, "intensity");
  viewer.addPointCloud<pcl::PointXYZI>(cloud_projected, cloud_afterfilter_color, "cloud_projected", v2);

  viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud");
  viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud_projected");


  while (!viewer.wasStopped())
  {
	  //在此处可以添加其他处理  
	  user_data++;
	  viewer.spinOnce(100);
	  boost::this_thread::sleep(boost::posix_time::microseconds(100000));
  }

  return (0);
}

运行,右边投影后是一个平面:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程


四、extract_indices滤波

单窗口 空的 控制台程序:extract_indices.cpp

注:

1)、开头加上四句,否则编译可能不通过;

2)、编译不通过记得在属性——c/c++——预编译文件——预处理器定义中,添加_CRT_SECURE_NO_WARNINGS命令,重新编译即可通过;

3)编译不通过记得在属性——c/c++——语言——openMP支持——是在环境变量中增加“OMP_NUM_THREADS”变量,数值自己根据自己的CPU的性能来设置,一般2、4、8等。

cpp:

//#include <vtkAutoInit.h>           
//VTK_MODULE_INIT(vtkRenderingOpenGL);
//VTK_MODULE_INIT(vtkInteractionStyle);
//VTK_MODULE_INIT(vtkRenderingFreeType);

#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>

#include <pcl/io/io.h>    
#include <pcl/visualization/cloud_viewer.h>    
#include <boost/thread/thread.hpp>   

#include <omp.h>

int
main (int argc, char** argv)
{
	omp_set_num_threads(4);

	// Read in the cloud data
	pcl::PCDReader reader;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>), cloud_f(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);

	reader.read("table_scene_lms400.pcd", *cloud);
	std::cout << "PointCloud before filtering has: " << cloud->points.size() << " data points." << std::endl; //*

	// Create the filtering object: downsample the dataset using a leaf size of 1cm
	pcl::VoxelGrid<pcl::PointXYZ> vg;
	vg.setInputCloud(cloud);
	vg.setLeafSize(0.01f, 0.01f, 0.01f);
	vg.filter(*cloud_filtered);
	std::cout << "PointCloud after filtering has: " << cloud_filtered->points.size() << " data points." << std::endl; //*

	// Create the segmentation object for the planar model and set all the parameters
	pcl::SACSegmentation<pcl::PointXYZ> seg;
	pcl::PointIndices::Ptr inliers(new pcl::PointIndices);
	pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_plane(new pcl::PointCloud<pcl::PointXYZ>());
	pcl::PCDWriter writer;
	seg.setOptimizeCoefficients(true);
	seg.setModelType(pcl::SACMODEL_PLANE);
	seg.setMethodType(pcl::SAC_RANSAC);
	seg.setMaxIterations(1000);
	seg.setDistanceThreshold(0.002);

	int i = 0, nr_points = (int)cloud_filtered->points.size();
	// 当还有30%原始点云数据时
	while (cloud_filtered->points.size() > 0.3 * nr_points)     
	{
		// Segment the largest planar component from the remaining cloud
		seg.setInputCloud(cloud_filtered);
		seg.segment(*inliers, *coefficients);
		if (inliers->indices.size() == 0)
		{
			std::cout << "Could not estimate a planar model for the given dataset." << std::endl;
			break;
		}

		// 创建滤波器对象
		// Extract the planar inliers from the input cloud
		pcl::ExtractIndices<pcl::PointXYZ> extract;
		extract.setInputCloud(cloud_filtered);
		extract.setIndices(inliers);
		extract.setNegative(false);

		// Write the planar inliers to disk
		extract.filter(*cloud_plane);
		std::cout << "PointCloud representing the planar component: " << cloud_plane->points.size() << " data points." << std::endl;

		// Remove the planar inliers, extract the rest
		extract.setNegative(true);
		extract.filter(*cloud_f);
		*cloud_filtered = *cloud_f;

		i++;
	}

	pcl::visualization::PCLVisualizer viewer("Cloud Viewer"); 
	
	viewer.addPointCloud(cloud_filtered);
	viewer.setBackgroundColor(1, 0.5, 1);

	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}

  
  return (0);
}
运行:

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程

五、remove_outliers滤波——ConditionalRemoval和RadiusOutlierRemoval

程序1:

 空的 控制台程序,主程序由ConditionalRemoval和RadiusOutlierRemoval两个滤波器组成

注:

1)、开头加上四句,否则编译可能不通过;

2)、编译不通过记得在属性——c/c++——预编译文件——预处理器定义中,添加_CRT_SECURE_NO_WARNINGS命令,重新编译即可通过。

cpp:

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>

int
 main (int argc, char** argv)
{
  if (argc != 2)
  {
    std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
    exit(0);
  }
  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  = 10;
  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);
  }

  if (strcmp(argv[1], "-r") == 0){					//r——半径外点滤波//
    pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;	
    // build the filter 创建滤波器
    outrem.setInputCloud(cloud);
    outrem.setRadiusSearch(0.8);//设置在0.8半径的范围内找邻近点
    outrem.setMinNeighborsInRadius (2);//设置查询点的邻近点集数小于2的删除
    // apply filter    应用滤波器
    outrem.filter (*cloud_filtered);//执行条件滤波,存储结果到cloud_filtered
  }
  else if (strcmp(argv[1], "-c") == 0){					//c——条件外点滤波//
    // build the condition创建环境
    pcl::ConditionAnd<pcl::PointXYZ>::Ptr range_cond (new
      pcl::ConditionAnd<pcl::PointXYZ> ());			
	//为条件定义对象添加比较算子
    range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new
      pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::GT, 0.0)));//添加在z轴上大于0的比较算子 
    range_cond->addComparison (pcl::FieldComparison<pcl::PointXYZ>::ConstPtr (new
      pcl::FieldComparison<pcl::PointXYZ> ("z", pcl::ComparisonOps::LT, 0.8)));//添加在z轴上小于0.8的比较算子 
    // build the filter创建滤波器并用条件定义对象初始化
	//pcl::ConditionalRemoval<pcl::PointXYZ> condrem (range_cond);
	//例程中的语句会报错,重载函数调用不明确,删掉(range_cond)即可
    pcl::ConditionalRemoval<pcl::PointXYZ> condrem;
    condrem.setCondition (range_cond);
    condrem.setInputCloud (cloud);
    condrem.setKeepOrganized(true);//设置保持点云的结构
    // apply filter应用滤波器
    condrem.filter (*cloud_filtered);
  }
  else{
    std::cerr << "please specify command line arg '-r' or '-c'" << std::endl;
    exit(0);
  }
  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;
  // display pointcloud after filtering
  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);
}
运行:

1)、cd /d D:\PCLWorkspace\8\remove_outliers_single\Debug

2)、remove_outliers_single.exe -r

     remove_outliers_single.exe -c
这个例子运行后发现并没有得到想要的结果,源码详见http://pointclouds.org/documentation/tutorials/remove_outliers.php#remove-outliers

程序2:

单窗口 控制台 RadiusOutlierRemoval滤波

cpp:

//#include <vtkAutoInit.h>           
//VTK_MODULE_INIT(vtkRenderingOpenGL);
//VTK_MODULE_INIT(vtkInteractionStyle);
//VTK_MODULE_INIT(vtkRenderingFreeType);

#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/filters/extract_indices.h>

#include <pcl/io/io.h>    
#include <pcl/visualization/cloud_viewer.h>    
#include <boost/thread/thread.hpp>   

#include <pcl/filters/radius_outlier_removal.h>
#include <pcl/filters/conditional_removal.h>

#include <omp.h>

int
main(int argc, char** argv)
{
	omp_set_num_threads(4);

	// Read in the cloud data
	pcl::PCDReader reader;
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_outrem_filtered(new pcl::PointCloud<pcl::PointXYZ>);

	reader.read("table_scene_lms400.pcd", *cloud);
	std::cout << "PointCloud before filtering has: " << cloud->points.size() << " data points." << std::endl; //*

	// Create the filtering——RadiusOutlierRemoval
	pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
	// build the filter 创建滤波器
	outrem.setInputCloud(cloud);
	outrem.setRadiusSearch(0.80);//设置在0.8半径的范围内找邻近点
	outrem.setMinNeighborsInRadius(2000);//设置查询点的邻近点集数小于2000的删除
	// apply filter    应用滤波器
	outrem.filter(*cloud_outrem_filtered);//执行条件滤波,存储结果到cloud_filtered
	std::cout << "PointCloud after filtering has: " << cloud_outrem_filtered->points.size() << " data points." << std::endl; //*


	pcl::visualization::PCLVisualizer viewer("Cloud Viewer");

	viewer.addPointCloud(cloud_outrem_filtered);
	viewer.setBackgroundColor(1, 0.5, 1);

	while (!viewer.wasStopped())
	{
		viewer.spinOnce();
	}


	return (0);
}

运行:

运行时发现,聚类半径和删除临近点的数目会影响整个计算的速度,特别是一定范围内增大删除临近点的数目会使过滤掉的点数增多,剩余的点数变少,同时计算速度和可视化的速度也会提高。

《PCL点云库学习&VS2010(X64)》Part 九 PCL1.72(VTK6.2.0)滤波例程