【三维点云系列】PCL点云库之数据文件与IO操作
由于项目涉及点云目标识别和定位等相关内容,因此开始接触基于PCL的三维点云处理。对于PCL,官方解释是:PCL(Point Cloud Library,点云库)是吸收了前人点云相关研究的基础上建立起来的大型跨平台开源C++编程库,它实现了大量点云相关的通用算法和高效数据结构,涉及点云获取、滤波、分割、配准、检索、特征提取、识别、追踪、曲面重建、可视化等。本系列文章主要记录关于PCL点云库的学习过程。
本小节主要是关于点云文件格式与IO操作的相关内容。PCL中的IO库提供了点云文件输入输出相关的操作类,IO模块利用50多个类与30多个函数来实现点云的获取、读入、存储等。
一 点云文件格式
3D点云数据的文件格式包括多种,包括pcd、ply、txt等。本节主要基于PCL的内部文件格式——PCD,针对其文件格式以及它在点云库PCL中应用的方法。
1.1 文件头格式
每一个PCD文件都包含一个文件头来确定和声明文件中存储的点云数据的某种特性。PCL正式发布的PCD文件格式是0.7版本,以一个实际的PCD文件举例,说明0.7版本之后,PCD文件头包含的这些字段。
VERSION 0.7 //指定PCD文件版本
FIELDS x y z //指定一个点的维度和字段的名字,此处表示点云维度是XYZ
SIZE 4 4 4 //用字节数指定每一个维度的大小
TYPE F F F //用一个字符指定每一个维度的类型,此处F表示浮点类型(另外还有I表示有符号类型,U表示无符号类型)
COUNT 1 1 1 //每一个维度包含的元素数目,默认情况下为1
WIDTH 6411 //用点的数量表示点云数据集的宽度
HEIGHT 1 //用点的数量表示点云数据集的高度
VIEWPOINT 0 0 0 1 0 0 0 //指定数据集中点云的获取视点,在不同坐标系之间转换会用到,或者在辅助获取其他特征,比如获取曲面法线,判断方向一致性时会用到视点。
POINTS 6411 //点云中点的总数
DATA ascii //指定存储点云的数据类型
补充说明,若在文件头中,有如下字段说明:
WIDTH 640 //每行有640个点
HEIGHT 480 //640行*480列=307200个点
则表示有序点云,也就是类似于图像或者说矩阵的结构,分为行和列。
WIDTH 307200
HEIGHT 1
表示为无序点云,它有307200个点。因此,可以通过检查HEIGHT的值来判断点云属于哪种类型。
相比于无序点云,有序点云的优势在于,可以更高效地处理目标点与邻域之间的关系,可以实现加速计算并降低PCL中某些算法的成本。
1.2 数据存储类型
以上PCD文件中,在DATA行(包含)之前的所有行均为文件头,且必须按照固定顺序进行指定,不同指定之间用换行隔开。在文件头中DATA的下一行开始,就是点云的数据部分了,在0.7版本中,PCD文件用ASCII和二进制两种模式存储数据。若以ASCII形式,每一个点占据一个新行。从PCL1.0.1开始,用”nan”表示NaN无效点,即该点的值不存在或者非法。
二、PCD文件IO操作
由于pcd点云数据格式有它独特的优势,因此本项目基于此继续研究。首先是对点云数据的IO处理,包括从PCD文件读取点云数据和写入点云数据。
依赖头文件如下:
#include <iostream>
#include <pcl/io/pcd_io.h> //PCD读写类相关的头文件
#include <pcl/point_types.h> //PCL中支持的点类型头文件
2.1 PCD文件的读取操作
法一:使用loadPCDFile
读取milk.pcd文件,若文件不存在,返回错误。此处读取数据采用的是相对路径。
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("milk.pcd", *cloud) == -1)
{
std::cout << "Cloud reading failed." << std::endl;
return (-1);
}
法二:使用reader
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDReader reader;
reader.read("E://box1.pcd", *cloud);
2.2 PCD文件的写入操作
法一:使用writer
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PCDWriter writer;
writer.write<pcl::PointXYZ>("test_pcd.pcd", *cloud, false);
法二:使用savePCDFileASCII
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::io::savePCDFileASCII("test_pcd.pcd",cloud);
下面截图了目标物的三维点云数据的可视化结果,包括PointXYZ和PointXYZI两种数据格式。
原始图像:
目标物的PointXYZ数据类型的点云:
目标物的PointXYZI数据类型的点云:
总结:本小节简单地介绍了点云文件格式和IO操作,为之后点云数据的进一步处理垫定基础。才疏学浅,如有不妥之处,望指正。
- SSDB安装配置记录
- Python标准库笔记(3) — datetime模块
- Django 1.10中文文档-第一个应用Part4-表单和通用视图
- Python标准库笔记(2) — re模块
- Python爬虫—破解JS加密的Cookie
- Go语言中json转成map结构
- rpc-dubbo简单入门
- Django 1.10中文文档-第一个应用Part3-视图和模板
- Go语言对JSON进行编码和解码
- [Go 语言社区]服务器自测JS 工程
- Django 1.10中文文档-第一个应用Part2-模型和管理站点
- 亿以内所有素数(Go语言版)
- Django 1.10中文文档-第一个应用Part1-请求与响应
- 三步学会用spring开发OSGI——(第二步:工程篇)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 微商城订单模块重构实践
- 有赞移动应用如何给页面安上“任意门”
- 无用的设计模式-上篇
- JavaScript简介及JavaScript中的关键保留字、变量和数据类型
- 有赞iOS精准测试实践
- 聊聊java中的哪些Map:(一)HashMap(1.8)源码分析
- spring redis 模糊查找key
- EXTJS防止表单中回车触发提交
- 中间件的解析漏洞详解及演示
- 任意文件包含漏洞原理解析及演示
- 【每日一题】39. Combination Sum
- 有赞灰度发布与蓝绿发布实践
- 有赞 Android 编译进阶之路 —— 增量编译提效方案Savitar
- react+electron使应用窗口相互独立
- Presto 在有赞的实践之路