PCL库学习笔记(一)

PCL库学习笔记(一)

  • 一、基础内容
    • 1、数据类型
    • 2、点的类型
  • 二、点云的基本操作
    • 1、写入点云数据
    • 2、读取点云数据
    • 3、合并点云数据

一、基础内容

1、数据类型

pcl::PointCloud<pcl::PointCloud>

是一个基本的数据类型,PointCloud是C++里的一个类,包含以下函数:

pcl::PointCloud<pcl::PointCloud::width>
pcl::PointCloud<pcl::PointCloud::height>

width:在无序数据集中表示点的总数;有序数据集中表示一行中点的个数。
height:无序数据集为常量1,;有序数据集中表示总行数。

//有序点云
cloud.width = 640; // there are 640 points per line
cloud.height = 480; // thus 640*480=307200 points total in the dataset
//无序点云
cloud.width = 307200;
cloud.height = 1; // unorganized point cloud dataset with 307200 points

若需要判断点云是否有序,无需判断height=1,只需用如下函数

if (!cloud.isOrganized ())
pcl::points<pcl::PointCloud::points>

points:用于存储PointT类型的向量,例如PointXYZ类型的点

pcl::PointCloud<pcl::PointXYZ> cloud;//PointXYZ类型的点储存到点云cloud
std::vector<pcl::PointXYZ> data = cloud.points;//cloud里的数据是储存在points里面的
pcl::is_dense<pcl::PointCloud::is_dense>

bool类型,为真时表示所有点有限,为假时表示有些点可能无限或为空。

2、点的类型

PointXYZ成员变量:float x,y,z;
1.定义一个点云(指针类型)

pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);//指针类型的

2.访问点的坐标

cloud->points[i].x
pcl::PointXYZ point;//创建一个点放到点云里去
point.x = 2.0f - y;
point.y = y;
point.z = z;
cloud.points.push_back(point);

其中 points是个vector变量,points[i]是单个的点、points[i].data[0]、points[i].x用于访问点的x坐标。

二、点云的基本操作

1、写入点云数据

#include 
#include 
#include 

int main(int argc, char** argv)
{
    pcl::PointCloud<pcl::PointXYZ> cloud;

    // 写入点云数据
    cloud.width = 5;
    cloud.height = 1;
    cloud.is_dense = false;
    cloud.points.resize(cloud.width * cloud.height);

    for (std::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);
    }

    pcl::io::savePCDFileASCII("test_pcd.pcd", cloud);//储存在pcd文件中
    std::cerr << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;

    for (std::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;

    return (0);
}

2、读取点云数据

#include 
#include 
#include 

int main(int argc, char** argv)
{
    //创建一个PointCloud  Boost共享指针并对其进行初始化。
    //从堆中分配了一个PointCloud对象,把这个对象的指针赋值给了cloud
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

    if (pcl::io::loadPCDFile<pcl::PointXYZ>("test_pcd.pcd", *cloud) == -1) //* load the file
    {
        PCL_ERROR("Couldn't read file test_pcd.pcd \n");
        return (-1);
    }

    //Loaded 个数 data points from 文件 with the following fields: x y z
    std::cout << "Loaded "
        << cloud->width * cloud->height   //点的个数
        << " data points from test_pcd.pcd with the following fields: "
        << std::endl;

    for (std::size_t i = 0; i < cloud->points.size(); ++i)
        std::cout << "' " << cloud->points[i].x //点云里点的值
        << " " << cloud->points[i].y
        << " " << cloud->points[i].z << std::endl;

    return (0);
}

3、合并点云数据

#include 
#include 
#include 

int main(int argc, char** argv)
{

	pcl::PointCloud<pcl::PointXYZ> cloud_a, cloud_b, cloud_c;//三个输入点云
	pcl::PointCloud<pcl::Normal> n_cloud_b;//两个输出点云,储存法线的点云
	pcl::PointCloud<pcl::PointNormal> p_n_cloud_c;//储存xyz和法线的点云

	// 为两个点云写入数据,points cloud_a 和cloud_b,或者cloud_a 和n_cloud_b
	cloud_a.width = 5;//点个数
	cloud_a.height = cloud_b.height = n_cloud_b.height = 1;//都为无序点云
	cloud_a.points.resize(cloud_a.width * cloud_a.height);

	cloud_b.width = 3;
	cloud_b.points.resize(cloud_b.width * cloud_b.height);

	n_cloud_b.width = 5;//创建n_cloud_b
	n_cloud_b.points.resize(n_cloud_b.width * n_cloud_b.height);

	//写入cloud_a的点
	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);
	}

	//写入cloud_b的点
	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);
	}
    //写入n_cloud_b的点
	for (std::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);
	}
	
	//输出刚刚写入点云的点的数据
	std::cerr << "Cloud A: " << std::endl;
	for (size_t i = 0; i < cloud_a.points.size(); ++i)
		std::cerr << "    " << cloud_a.points[i].x << " " << cloud_a.points[i].y << " " << cloud_a.points[i].z << std::endl;

	std::cerr << "Cloud B: " << std::endl;
	for (size_t i = 0; i < cloud_b.points.size(); ++i)
		std::cerr << "    " << cloud_b.points[i].x << " " << cloud_b.points[i].y << " " << cloud_b.points[i].z << std::endl;

	std::cerr << "n_Cloud B: " << std::endl;
	for (std::size_t i = 0; i < n_cloud_b.points.size(); ++i)//输出法线点的方式不一样
		std::cerr << "    " << n_cloud_b.points[i].normal[0] << " " << n_cloud_b.points[i].normal[1] << " " << n_cloud_b.points[i].normal[2] << std::endl;
	

	//连接点云到c
	cloud_c = cloud_a;
	cloud_c += cloud_b;
	std::cerr << "Cloud C: " << std::endl;
	for (size_t i = 0; i < cloud_c.points.size(); ++i)
		std::cerr << "    " << cloud_c.points[i].x << " " << cloud_c.points[i].y << " " << cloud_c.points[i].z << " " << std::endl;

	//连接字段到p_n_cloud_c
	pcl::concatenateFields(cloud_a, n_cloud_b, p_n_cloud_c);//连接字段到p_n_cloud_c
	std::cerr << "Cloud D: " << std::endl;
	for (size_t i = 0; i < p_n_cloud_c.points.size(); ++i)
		std::cerr << "    " <<
		p_n_cloud_c.points[i].x << " " << p_n_cloud_c.points[i].y << " " << p_n_cloud_c.points[i].z << " " <<
		p_n_cloud_c.points[i].normal[0] << " " << p_n_cloud_c.points[i].normal[1] << " " << p_n_cloud_c.points[i].normal[2] << std::endl;

	return (0);
}

以上介绍了两种不同的连接方式,每一种都有自己的约束条件,代码的输出结果为

Cloud A:
    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 B:
    15.3438 93.5938 373.188
    150.844 169.875 1012.22
    456.375 121.938 4.78125
n_Cloud B:
    9.125 386.938 544.406
    584.875 616.188 621.719
    170.219 678.938 461.594
    360.562 58.4062 622.25
    802.094 821.844 532.344
Cloud C:
    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
    15.3438 93.5938 373.188
    150.844 169.875 1012.22
    456.375 121.938 4.78125
Cloud D:
    1.28125 577.094 197.938 9.125 386.938 544.406
    828.125 599.031 491.375 584.875 616.188 621.719
    358.688 917.438 842.562 170.219 678.938 461.594
    764.5 178.281 879.531 360.562 58.4062 622.25
    727.531 525.844 311.281 802.094 821.844 532.344

你可能感兴趣的:(PCL,点云,c++)