点云输入/输出(I/O)

数据文件格式

一个典型的PCD文件内容如下:

# .PCD v.5 - Point Cloud Data file format
VERSION .5
FIELDS x y z
SIZE 4 4 4
TYPE F F F
COUNT 1 1 1
WIDTH 397
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 397
DATA ascii
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
  1. VERSION .5 指定PCS文件版本

  2. 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

  3. SIZE 4 4 4 指定每一个维度的字节数大小

  4. TYPE F F F 指定每一个维度的类型,I表示int,U表示uint,F表示浮点

  5. COUNT 1 1 1 指定每一个维度包含的元素数,如果没有COUNT,默认都为1

  6. WIDTH 397 点云数据集的宽度

  7. HEIGHT 1 点云数据集的高度

  8. VIEWPOINT 0 0 0 1 0 0 0 指定点云获取的视点和角度,在不同坐标系之间转换时使用(由3个平移+4个四元数构成)

  9. POINTS 397 总共的点数(显得多余)

  10. DATA ascii 存储点云数据的数据类型,ASCII和binary

 其他格式

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

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

        以上所有格式都有其优缺点,因为他们是在不同时期为了满足不同的需求所创建的,那时很多当今流行的传感器和算法都还没有发明。

反序列化 

        我们可以对一个点云进行反序列化操作,将其保存到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>("G:/vsdata/PCLlearn/PCDdata/bun0.pcd", *cloud) == -1) //* 加载文件
    {
        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);
}

序列化

        以下代码,随机生成了50个点,并将之以ASCII形式保存(序列化):

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

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

    // 构造点云数据
    cloud.width = 50;
    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;

    // 随机生成50个点
    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);
     有时为了节省空间,提高读写效率,还会以binary的格式进行序列化,即将save操作改为:
    //pcl::io::savePCDFileBinary("test_pcd_binary.pcd", cloud);
     或
    //pcl::io::savePCDFile("test_pcd_binary.pcd", cloud, true);
    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);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小镇种田家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值