1.pcd介绍
(1)PCD文件头格式:所有的pcd文件前十行必须是以上的格式,并且不能改变顺序。
下图为pcd格式:
- VERSION 0.7:指定pcd文件的版本(0.6及0.7两种,详细区别见pcl/io/pcd_io.h第62行)。
- FIELDS:指定每个点可以具有的维度,以及每个维度所代表的含义。例如:FIELDS x y z r g b表示该点的位置信息(x,y,z),颜色信息(r,g,b)。
- SIZE:以字节为单位指定每个数据所占用的内存。
- TYPE:指定每个数据的数据类型。其中无效的点的通常存储为NAN类型。 I:可表示int8,int16,int32;U:可表示uint8,unit16,uint32;F:表示float(上图所用的为浮点类型)。
- COUNT:指定每个维度有多少元素。例如xyz数据通常只有一个元素。
- WIDTH:指定数据点的宽度,它包含两个含义:1.可指定点云总个数(与POINTS相同),用于无组织的数据;2.可指定有组织点云数据的宽度(连续点的总数)。
- HEIGTH:指定数据点的高度,它包含两个含义:1.可指定有组织的点云数据的高度(总行数)。2.对未组织的数据,它被设置为1。
- POINTS:指定点云总个数。
- VIEWPOINT:采集数据时的视点(由平移tx,ty,tz和四元数qw,qx,qy,qz组成)。
- DATA: 点云数据存储的数据类型(支持ascii和binary)。如果以ASCII形式,每一点占据一个新行。
2.读取
(1)方式一(一般使用该方式)
/****************方式一********************/
pcl::io::loadPCDFile("D:/code/csdn/data/bunny.pcd", *cloud_pcd);
(2)方式二
/****************方式二********************/
// 读取文件头
pcl::PCLPointCloud2 cloud2_pcd_header; // 结果点云数据头信息
Eigen::Vector4f origin_header; // 传感器采集原点(仅适用于>FILE_V7,如果不存在则为空)
Eigen::Quaternionf orientation_header; // 传感器采集方向(仅适用于>FILE-V7)
int file_version_header; // 文件的file版本(file_V6或file_V7)
int data_type_header; // 数据类型(二进制数据=1,pcd=0等)
unsigned int data_idx_header; // 文件中点云数据的偏移量
pcdReader->readHeader("D:/code/csdn/data/bunny.pcd", cloud2_pcd_header, origin_header, orientation_header, file_version_header, data_type_header, data_idx_header);
// 读取文件
pcl::PCLPointCloud2 cloud2_pcd; // 结果点云数据
Eigen::Vector4f origin; // 传感器采集原点(仅适用于>FILE_V7,如果不存在则为空)
Eigen::Quaternionf orientation; // 传感器采集方向(仅适用于>FILE-V7)
int file_version; // 文件的file版本(file_V6或file_V7)
pcdReader->read("D:/code/csdn/data/bunny.pcd", cloud2_pcd, origin, orientation, file_version);
pcl::fromPCLPointCloud2<pcl::PointXYZ>(cloud2_pcd, *cloud_pcd); // 转换为pcl::point<pointT>形式
3.保存
(1)写入pcd文件,默认为ASCII格式(可以直接用文本打开,但是文件较大)
pcl::io::savePCDFile("D:/code/csdn/data/bunny_ascii.pcd", *cloud_pcd);
(2)写入pcd文件,bin的二进制格式(使用二进制编码,文件较小)
pcl::io::savePCDFileBinary("D:/code/csdn/data/bunny_bin.pcd", *cloud_pcd);
(3)写入pcd文件,经过压缩的bin的二进制格式
pcl::io::savePCDFileBinaryCompressed("D:/code/csdn/data/bunny_bincompress.pcd", *cloud_pcd);
4.完整代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#define PCD_LOAD_FUNC
int main()
{
/****************读取PCD文件********************/
pcl::PCDReader* pcdReader = new pcl::PCDReader(); // pcd对象
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_pcd(new pcl::PointCloud<pcl::PointXYZ>);
#ifdef PCD_LOAD_FUNC
/****************方式一********************/
pcl::io::loadPCDFile("D:/code/csdn/data/bunny.pcd", *cloud_pcd);
#else
/****************方式二********************/
// 读取文件头
pcl::PCLPointCloud2 cloud2_pcd_header; // 结果点云数据头信息
Eigen::Vector4f origin_header; // 传感器采集原点(仅适用于>FILE_V7,如果不存在则为空)
Eigen::Quaternionf orientation_header; // 传感器采集方向(仅适用于>FILE-V7)
int file_version_header; // 文件的file版本(file_V6或file_V7)
int data_type_header; // 数据类型(二进制数据=1,pcd=0等)
unsigned int data_idx_header; // 文件中点云数据的偏移量
pcdReader->readHeader("D:/code/csdn/data/bunny.pcd", cloud2_pcd_header, origin_header, orientation_header, file_version_header, data_type_header, data_idx_header);
// 读取文件
pcl::PCLPointCloud2 cloud2_pcd; // 结果点云数据
Eigen::Vector4f origin; // 传感器采集原点(仅适用于>FILE_V7,如果不存在则为空)
Eigen::Quaternionf orientation; // 传感器采集方向(仅适用于>FILE-V7)
int file_version; // 文件的file版本(file_V6或file_V7)
pcdReader->read("D:/code/csdn/data/bunny.pcd", cloud2_pcd, origin, orientation, file_version);
pcl::fromPCLPointCloud2<pcl::PointXYZ>(cloud2_pcd, *cloud_pcd); // 转换为pcl::point<pointT>形式
#endif // PCD_LOAD_FUNC
/****************写入PCD文件********************/
pcl::io::savePCDFile("D:/code/csdn/data/bunny_ascii.pcd", *cloud_pcd); // 写入pcd文件,默认为ASCII格式
pcl::io::savePCDFileBinary("D:/code/csdn/data/bunny_bin.pcd", *cloud_pcd); // 写入pcd文件,bin的二进制格式
pcl::io::savePCDFileBinaryCompressed("D:/code/csdn/data/bunny_bincompress.pcd", *cloud_pcd); // 写入pcd文件,经过压缩的bin的二进制格式
// 展示
boost::shared_ptr<pcl::visualization::PCLVisualizer> view_raw(new pcl::visualization::PCLVisualizer("raw"));
view_raw->addPointCloud(cloud_pcd, "raw cloud");
view_raw->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "raw cloud");
while (!view_raw->wasStopped())
{
view_raw->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
5.结果展示
(1)读取结果:
(2)写入文件大小对比