PCL教程-点云滤波之投影滤波

原文链接:Projecting points using a parametric model

本小节将学习如何将点投影到一个参数化模型上(例如平面或球等)。参数化模型通过一组参数来设定,对于平面来说使用其等式形式ax+by+cz+d=0,在PCI中有专门存储常见模型系数的数据结构。

程序代码

#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/visualization/pcl_visualizer.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>);

	pcl::visualization::PCLVisualizer viewer("project inliers");
	int v1(1);
	int v2(2);
	viewer.createViewPort(0, 0, 0.5, 1, v1);
	viewer.createViewPort(0.5, 0, 1, 1, v2);


	// 填入点云数据
	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;
	// 平面公式:ax + by + cz + d = 0
	// 创建一个系数为X=Y=0,Z=1的平面,相当于是x-y平面
	// a = b = d = 0, c = 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;

	viewer.addPointCloud(cloud, "c1", v1);
	viewer.addPointCloud(cloud_projected, "c2", v2);
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1000, "c1", v1);
	viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1000, "c2", v2);
	viewer.addCoordinateSystem(1000, cloud_projected->points[0].x, cloud_projected->points[0].y, cloud_projected->points[0].z, v2);
	viewer.addCoordinateSystem(1000, cloud->points[0].x, cloud->points[0].y, cloud->points[0].z, v1);

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

 在本程序中使用的投影模型为平面。

平面公式:ax + by + cz + d = 0

创建一个系数为X=Y=0,Z=1的平面,相当于是x-y平面
系数设置为:a = b = d = 0, c = 1;

	// 平面公式:ax + by + cz + d = 0
	// 创建一个系数为X=Y=0,Z=1的平面,相当于是x-y平面
	// a = b = d = 0, c = 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);

 实验结果

首先随机生成五个点,如左图。

然后将所有点全部投影到X-Y平面(Z=1):如右图:

 

 

 Cloud before projection:
    1.28125 577.094 197.938
    828.125 599.031 491.375
    358.688 917.438 842.562
    764.5 178.281 879.531
    727.531 525.844 311.281
Cloud size before projection: 5
Cloud after projection:
    1.28125 577.094 0
    828.125 599.031 0
    358.688 917.438 0
    764.5 178.281 0
    727.531 525.844 0
Cloud size after projection: 5

由上述结果可知:将点云投影到一个平面,会使点云的某个坐标失去意义(坐标值相同),将三维的点云变成了二维的图像。 

 同理,对点云数据 table_scene_lms400.pcd进行投影滤波的结果如下:

 

 

 三维的点云图像已经失去了一个坐标的数据,变成了二维扁平的点云图像。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值