PCD文件介绍

PCL以PCD文件形式保存点云。 (主要是为了保存n维点类型)

其文件格式如下:

每一个PCD文件都包含一个文件头,它确定和声明文件中存储的点云数据的某种特性。

PCD文件头必须使用ASCII码来编码。PCD文件中指定的每一个文件头字段以及ASCII点数据都用一个新行(\n)分开了。

从0.7版本开始,PCD文件头包含下面的这些字段

  • VERSIO:指定PCD文件版本
  • FEIELDS:指定一个点可以有的每一个维度和字段的名字。例如
FEIELDS x y z     # XYZ data
FEIELDS x y zrgb  # XYZ+colors
  • SIZE: 用字节数指定每一个维度的大小
unsigned char/char/  1个字节
unsigned short/short 2个字节
unsigned int/int/float 4个字节
double  8个字节
  • TYPE:用要给字符指定每一个维度的类型。可以使用的类型有:
I 表示有符号类型 int8(char)、int16(short)、int32(int)
U 表示无符号类型 uint8(unsigned char)、uint16(unsigned short)、uint32(unsigned int)
F 表示 浮点型
  • COUNT:指定每一个维度包含的元素数目。x这元素就是1.默认没有COUNT ,所有维度数目设置为1
  • WIDTH:用点的数量表示点云数据集的宽度。根据是有序点云还是无序点云。有序就是一行的宽度,无序就是点云总个数
  • HEIGHT: 用点的数量表示点云数据集的高度。被用于检查有序还是无序。无序为1 ,有序为高度
//有序点云
WIDTH 640  #像图像一样的有序结构 640*480
HEIGHT 480

//无序点云
WIDTH 307200
HEIGHT 1        #  无序点 共 307200个
  • VIEWPOINT:指定数据集中点云的获取视点。在不同坐标系转换的时候用到。 平移+四元数 默认为 VIEWPOINT 0 0 0 1 0 0 0
  • DATA :指定存储点云数据的数据类型。

从PCD文件中读点云数据

在这里插入图片描述
需要包含的头文件

在这里插入图片描述
创建一个点云变量 的共享指针 并实例化

在这里插入图片描述
从 pcd文件 读取 点云
如果没有读到 报错相关信息 结束进程

这里要重点说明下 loadPCDFile 这个函数了 。 这个就是 pcl 里面 从PCD文件读取点云的核心函数

结合上面的例子 用法就是:
pcl::io::loadPCDFile< 点云类型 >(PCD文件路径,读取后存入的 地址指向)

在这里插入图片描述
计算点云数量 打印相关信息

在这里插入图片描述

Code

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

int main(int argc,char** argv)
{
    /*创建一个点云变量 的共享指针  并实例化*/
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

      /*从 pcd文件  读取 点云*/
    if(pcl::io::loadPCDFile<pcl::PointXYZ>("../test_pcd.pcd",*cloud)==-1)
    {    
        //  返回值是 -1  代表 没有读到
        PCL_ERROR("Couldn't read file test_pcd.pcd \n");
        return  (-1);
    }

      //计算点云数量   打印相关信息
    std::cout<<"Loaded "<<cloud->width*cloud->height<<" data points from test_pcd.pcd with the following fields: "<<std::endl;

    /*遍历输出 各点云的内容*/
    for(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);
}

Result

原pcd
在这里插入图片描述
读取终端 显示 内容
在这里插入图片描述

从PCD读取自定义的点云类型

上面的例子是 读取 pcl原定义好的点云类型

如果像之前我们 定义了 新的点云类型,此时 如何读取?

此时需要在 main函数前 加上 自己的点云定义

struct MyPointType    //定义点类型结构
{
    PCL_ADD_POINT4D;  //该点类型有4个元素      

    /*尝试新增一个自定义*/  
    float JoneAdd;    //定义自己新增的类型名称
     //测试了添加这么多个也没问题
    float JoneAdd1;
    float JoneAdd2;
    float JoneAdd3;
    float JoneAdd4;
    float JoneAdd5;
    float JoneAdd6;
    float JoneAdd7;
    float JoneAdd8;
    float JoneAdd9;

    EIGEN_MAKE_ALIGNED_OPERATOR_NEW   //确保new操作符对齐操作 

}EIGEN_ALIGN16;   //强制SSE 对齐

POINT_CLOUD_REGISTER_POINT_STRUCT(MyPointType,    //注册点类型宏
    (float ,x,x)
    (float ,y,y)
    (float ,z,z)
    (float ,JoneAdd,JoneAdd)
    (float ,JoneAdd,JoneAdd1)
    (float ,JoneAdd,JoneAdd2)
    (float ,JoneAdd,JoneAdd3)
    (float ,JoneAdd,JoneAdd4)
    (float ,JoneAdd,JoneAdd5)
    (float ,JoneAdd,JoneAdd6)
    (float ,JoneAdd,JoneAdd7)
    (float ,JoneAdd,JoneAdd8)
    (float ,JoneAdd,JoneAdd9)
    )

或者 定义在 一个.hpp文件里面 。 引用这个文件

然后 函数里面的 内容 改成 如下 形式

在这里插入图片描述
那么如果 加载的pcd 文件不是 我们 定义 的点云类型 会怎么办 ?
出现下面的结果
在这里插入图片描述
设置 打印 信息 如下
在这里插入图片描述

原PCD文件
在这里插入图片描述

终端打印读取信息
在这里插入图片描述