小淼博客

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、标准点云数据文件格式

1. 典型PCD文件

# .PCD v.5 - Point Cloud Data file format
VERSION .5 # 指定PCS文件版本
FIELDS x y z # 指定一个点的每一个维度和字段名字,例如 FIELDS x y z # XYZ data 或 FIELDS x y z rgb # XYZ + colors 或  FIELDS x y z normal_x normal_y normal_z # XYZ + surface normals
SIZE 4 4 4 # 指定每一个维度的字节数大小
TYPE F F F # 指定每一个维度的类型,I表示int,U表示uint,F表示浮点
COUNT 1 1 1 # 指定每一个维度包含的元素数,如果没有COUNT,默认都为1
WIDTH 397 # 点云数据集的宽度
HEIGHT 1 # 点云数据集的高度
VIEWPOINT 0 0 0 1 0 0 0 # 指定点云获取的视点和角度,在不同坐标系之间转换时使用(由3个平移+4个四元数构成)
POINTS 397 # 总共的点数 = WIDTH * HEIGHT
DATA ascii # 存储点云数据的数据类型,ASCII和binary
0.0054216 0.11349 0.040749
-0.0017447 0.11425 0.041273
-0.010661 0.11338 0.040916
0.026422 0.11499 0.032623
0.024545 0.12284 0.024255
0.034137 0.11316 0.02507

2. 其他文件格式

     PCD 不是第 一个支持 3D点云数据的文件类型,尤其是计算机图形学和计算几何学领域,已经创建了很多格式来描述任意多边形和激光扫描仪获取的点云。常见的有下面几种格式:

1. PLY 是一种多边形文件格式 , 由 Stanford 大学的 Turk 等人设计开发;
2. STL 是 3D Systems 公司创建的模型文件格式,主要应用于 CAD 、 CAM领域 ;
3. OBJ 是从几何学上定义的文件格式,首先由 Wavefront Technologies 开发;
4. 其他格式

     以上所有格式都有其优缺点,因为他们是在不同时期为了满足不同的需求所创建的,那时很多当今流行的传感器和算法都还没有发明;PCL 中 PCD 文件格式的正式发布是 0.7版本,之前也有0.5,0.6版本。

二、PCD点云文件的读写

1. 反序列化

我们可以对一个点云进行反序列化操作,将之保存到PointCloud对象中:

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

int main(int argc, char **argv) {
    // 准备pcl::PointXYZ类型的点云
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    // 将pcd中的数据加载到cloud中
    if (pcl::io::loadPCDFile<pcl::PointXYZ>("./data/bunny.pcd", *cloud) == -1) //* load the file
    {
        PCL_ERROR ("Couldn't read file bunny.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);
}

2. 序列化

以下代码,随机生成了5个点,并将之以ASCII形式保存(序列化)在 test_pcd.pcd 文件中

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

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

    // Fill in the cloud data
    cloud.width = 5;
    cloud.height = 1;
    cloud.is_dense = false;
    cloud.points.resize(cloud.width * cloud.height);

    std::cout << rand() << std::endl;
    std::cout << rand() / (RAND_MAX + 1.0f) << std::endl;
    std::cout << 1024 * rand() / (RAND_MAX + 1.0f) << std::endl;

    // 随机生成5个点
    for (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);
    std::cerr << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;

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

输出的文件内容如下:

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z
SIZE 4 4 4
TYPE F F F
COUNT 1 1 1
WIDTH 5
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 5
DATA ascii
-0.3974061 -0.47310591 0.29260206
-0.73189831 0.66710472 0.44130373
-0.73476553 0.85458088 -0.036173344
-0.46070004 -0.2774682 -0.91676188
0.1837492 0.96880913 0.5120554

🌻 Tips: 有时为了节省空间,提高读写效率,还会以binary的格式进行序列化,即将save操作改为

pcl::io::savePCDFileBinary("test_pcd_binary.pcd", cloud);
// 或
pcl::io::savePCDFile("test_pcd_binary.pcd", cloud, true);
posted on 2023-09-17 00:49  小淼博客  阅读(42)  评论(0)    收藏  举报

大家转载请注明出处!谢谢! 在这里要感谢GISPALAB实验室的各位老师和学长学姐的帮助!谢谢~