1. 连接两个点云
#include <iostream> //输入输出流
#include <pcl/io/pcd_io.h> //PCL的PCD格式文件的输入输出头文件
#include <pcl/point_types.h> //PCL对各种格式的点的支持头文件
using namespace std;
using namespace pcl;
//拼接A和B到C
/************************************
int main(int argc,char**argv)
参数1: argc 命令行输入的个数(以空白符为分隔)
参数2: argv 存储了所有命令行参数,以Null结束
*************************************/
int main(int argc,char**argv)
{
//不管怎样argv[0]都是工程exe的路径
if (argc != 3) //提示如果执行可执行文件输入两个参数-f或者-p
{
cout << "please specify command line arg'-f' or '-p'" << endl;
system("pause");
exit(0);
}
/*******************************************************************
定义了连接点云会用到的5个点云对象:3个输入(cloud_a cloud_b 和n_cloud_b)
两个输出(cloud_c n_cloud_c)然后就是为两个输入点云cloud_a和 cloud_b或者cloud_a 和n_cloud_b填充数据
********************************************************************/
//申明三个PointXYZ点云数据类型,分别为cloud_a,cloud_b,cloud_c
PointCloud<PointXYZ> cloud_a, cloud_b, cloud_c;
//存储进行连接的时候需要的Normal点云, Normal(float n_x,float n_y,float n_z)
PointCloud<Normal> n_cloud_b;
//存储连接XYZ与normal后的点云。
PointCloud<PointNormal> p_n_cloud_c;
//创建点云数据
//设置cloud_a的个数是5;
cloud_a.width = 5;
cloud_a.height= cloud_b.height= cloud_c.height = 1; //设置点云为无序点云。
cloud_a.points.resize(cloud_a.width*cloud_a.height); //总的点数
// strcmp(s1,s2)用来比较两个字符串,若s1,s2字符串相等,则返回0。若s1大于s2,返回大于零的数;否则返回小于零的数。
if (strcmp(argv[1], "-p") == 0) //判断是否为连接(a+b=c),点云连接。
{
cloud_b.width =3;
cloud_b.height = 1; //设置点云为无序点云。
cloud_b.points.resize(cloud_b.width*cloud_b.height); //总的点数
}
else //连接XYZ与normal
{
n_cloud_b.width = 5; //如果是连接XYZ与normal则生成5个法线
n_cloud_b.height = 1;
n_cloud_b.points.resize(n_cloud_b.width*n_cloud_b.height);
}
//循环生成无序点云填充上面定义的两种类型的点云数据
for (size_t i = 0; i < cloud_a.points.size(); i++)
{
cloud_a.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_a.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_a.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
if (strcmp(argv[1], "-p") == 0)
{
//连接a+b=c,则cloud_b用三个点作为xyz的数据。
for (size_t i = 0; i < cloud_b.points.size(); i++)
{
cloud_b.points[i].x = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_b.points[i].y = 1024 * rand() / (RAND_MAX + 1.0f);
cloud_b.points[i].z = 1024 * rand() / (RAND_MAX + 1.0f);
}
}
else
{
//连接xyz+normal=xyznormal,则n_cloud_b用5个点作为normal数据。
for (size_t i = 0; i < n_cloud_b.points.size(); i++)
{
n_cloud_b.points[i].normal[0] = 1024 * rand() / (RAND_MAX + 1.0f);
n_cloud_b.points[i].normal[1] = 1024 * rand() / (RAND_MAX + 1.0f);
n_cloud_b.points[i].normal[2] = 1024 * rand() / (RAND_MAX + 1.0f);
}
}
//输出点云Cloud_A;
cout << "cloud A:" << endl;
for (size_t i = 0; i < cloud_a.points.size(); ++i)
{
cout << " " << cloud_a.points[i].x << " " << cloud_a.points[i].y << " " << cloud_a.points[i].z << endl;
}
//输出点云Cloud_B;
if (strcmp(argv[1], "-p") == 0) //输出cloud_b
{
cout << "cloud B:" << endl;
for (size_t i = 0; i < cloud_b.points.size(); ++i)
{
cout << " " << cloud_b.points[i].x << " " << cloud_b.points[i].y << " " << cloud_b.points[i].z << endl;
}
}
else //输出n_cloud_b
{
cout << "cloud N_B:" << endl;
for (size_t i = 0; i < n_cloud_b.points.size(); i++)
{
cout << " " << n_cloud_b.points[i].normal[0] << " " << n_cloud_b.points[i].normal[1] << " " << n_cloud_b.points[i].normal[2] << endl;
}
}
//复制点云中的点
if (strcmp(argv[1], "-p") == 0)
{
cloud_c = cloud_a;
cloud_c += cloud_b; //将cloud_a和cloud_b点云数据连接一起创建cloud_c。
//输出连接结果
cout << "cloud C:" << endl;
for (size_t i = 0; i < cloud_c.points.size(); i++)
{
cout << " " << cloud_c.points[i].x << " " << cloud_c.points[i].y << " " << cloud_c.points[i].z << endl;
}
}
else //连接cloud_a和n_cloud_b获得p_n_cloud_c
{
cout << "p_n_cloud C:" << endl;
concatenateFields(cloud_a, n_cloud_b,p_n_cloud_c);
for (size_t i = 0; i < p_n_cloud_c.points.size(); i++)
{
cout << " " << p_n_cloud_c.points[i].x
<< " " << p_n_cloud_c.points[i].y
<< " " << p_n_cloud_c.points[i].z<<endl;
}
}
system("pause");
return 0;
}
2.PCL中的OpenNI点云获取框架
PCL提供一个通用采集接口, 这样可以方便的连接到不同的设备以及驱动、文件格式以及其他数据源。PCL集成的第一个数据获取驱动是新的OpenNI Grabber,他使得从OpenNI兼容的设备请求数据流变得十分简单。