云点数据读写

一、常见点云数据格式

  1. LAS/LAZ格式

    • LAS是点云数据的行业标准格式

    • LAZ是LAS的压缩版本

    • 支持地理参考信息、颜色、强度等属性

  2. PCD格式(Point Cloud Data)

    • PCL(Point Cloud Library)开发的格式

    • 支持ASCII和二进制存储

    • 包含头部信息和数据部分

  3. PLY格式(Polygon File Format)

    • 最初为存储3D扫描仪数据设计

    • 支持点云和网格数据

    • 可包含颜色、法线等属性

  4. OBJ格式

    • 简单文本格式

    • 主要用于3D模型但也可存储点云

二、读写工具和库

  1. PDAL(Point Data Abstraction Library)

    • 开源点云数据处理库

    • 支持多种格式转换和处理

  2. PCL(Point Cloud Library)

    • 强大的点云处理库

    • 提供多种点云格式的读写接口

  3. LASlib/LASzip

    • 专门用于LAS/LAZ格式的读写
  4. CloudCompare

    • 开源点云处理软件

    • 支持多种格式的导入导出

三、PCL读写点云数据

PCL(Point Cloud Library)是处理点云数据的强大开源库,提供了多种点云数据格式的读写功能。以下是使用PCL进行点云数据读写的主要方法。

1. 基本点云数据结构

pcl::PointCloud 类

主要属性

  • width - 点云的宽度(对于无组织点云表示点数,对于有组织点云表示每行点数)

  • height - 点云的高度(对于无组织点云通常为1,对于有组织点云表示行数)

  • points - 存储所有点的向量

  • is_dense - 布尔值,表示点云是否包含无限/NaN值

  • sensor_origin_ - 传感器原点坐标(Eigen::Vector4f)

  • sensor_orientation_ - 传感器方向(Eigen::Quaternionf)

2. 常用点类型

点类型 描述 包含数据
pcl::PointXYZ 基本XYZ点 float x, y, z
pcl::PointXYZI 带强度的XYZ点 float x, y, z, intensity
pcl::PointXYZRGB 带RGB颜色的XYZ点 float x, y, z; uint32_t rgb
pcl::PointXYZRGBA 带RGBA颜色的XYZ点 float x, y, z; uint32_t rgba
pcl::PointNormal 带法线的XYZ点 float x, y, z, normal_x, normal_y, normal_z, curvature

3. 读写点云数据方法

读取点云文件

cpp

复制代码
#include <pcl/io/pcd_io.h>

// 读取PCD文件
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("input.pcd", *cloud) == -1) {
    PCL_ERROR("Couldn't read file input.pcd\n");
    return -1;
}

// 读取PLY文件
#include <pcl/io/ply_io.h>
pcl::PLYReader reader;
reader.read("input.ply", *cloud);

写入点云文件

cpp

复制代码
// 写入PCD文件(二进制格式)
pcl::io::savePCDFileBinary("output.pcd", *cloud);

// 写入PCD文件(ASCII格式)
pcl::io::savePCDFileASCII("output_ascii.pcd", *cloud);

// 写入PLY文件
pcl::PLYWriter writer;
writer.write("output.ply", *cloud, false); // false表示不保存二进制格式

4. 常用方法参数表

方法 参数 返回值 描述
loadPCDFile (const std::string &file_name, PointCloud &cloud) int 加载PCD文件
savePCDFile (const std::string &file_name, const PointCloud &cloud, bool binary_mode=false) int 保存PCD文件
loadPLYFile (const std::string &file_name, PointCloud &cloud) int 加载PLY文件
savePLYFile (const std::string &file_name, const PointCloud &cloud, bool binary_mode=false) int 保存PLY文件
fromROSMsg (const sensor_msgs::PointCloud2 &msg, PointCloud &cloud) void 从ROS消息转换
toROSMsg (const PointCloud &cloud, sensor_msgs::PointCloud2 &msg) void 转换为ROS消息

其他格式支持

1. PLY格式读写

cpp

复制代码
#include <pcl/io/ply_io.h>

// 读取PLY文件
pcl::PLYReader reader;
reader.read("input.ply", *cloud);

// 写入PLY文件
pcl::PLYWriter writer;
writer.write("output.ply", *cloud);
2. OBJ格式读写

cpp

复制代码
#include <pcl/io/obj_io.h>

// 读取OBJ文件
pcl::OBJReader reader;
reader.read("input.obj", *cloud);

// 写入OBJ文件
pcl::OBJWriter writer;
writer.write("output.obj", *cloud);
二进制与ASCII格式

PCD文件可以保存为二进制或ASCII格式:

cpp

复制代码
// 保存为二进制格式(更小更快)
pcl::io::savePCDFileBinary("output_binary.pcd", *cloud);

// 保存为压缩二进制格式(更小)
pcl::io::savePCDFileBinaryCompressed("output_compressed.pcd", *cloud);

// 保存为ASCII格式(可读)
pcl::io::savePCDFileASCII("output_ascii.pcd", *cloud);

5. 点云基本操作

添加点

cpp

复制代码
pcl::PointXYZ point;
point.x = 1.0; point.y = 2.0; point.z = 3.0;
cloud->points.push_back(point);

访问点

cpp

复制代码
// 随机访问
float x = cloud->points[10].x;

// 遍历所有点
for (const auto& point : *cloud) {
    std::cout << "x: " << point.x 
              << " y: " << point.y 
              << " z: " << point.z << std::endl;
}

点云属性

cpp

复制代码
std::cout << "点云大小: " << cloud->size() << std::endl;
std::cout << "宽度: " << cloud->width << std::endl;
std::cout << "高度: " << cloud->height << std::endl;
std::cout << "是否为有组织点云: " << cloud->isOrganized() << std::endl;

6. 常用信号(ROS相关)

在PCL与ROS结合使用时,常用的信号包括:

信号 参数 描述
pcl::visualization::PointPickingEvent const pcl::visualization::PointPickingEvent &event 当用户选择点时触发
pcl::visualization::KeyboardEvent const pcl::visualization::KeyboardEvent &event 键盘事件
pcl::visualization::MouseEvent const pcl::visualization::MouseEvent &event 鼠标事件

7. 示例代码:完整读写流程

cpp

复制代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>

int main() {
    // 创建一个点云对象
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    
    // 填充点云数据
    cloud->width = 5;
    cloud->height = 1;
    cloud->is_dense = false;
    cloud->points.resize(cloud->width * cloud->height);
    
    for (auto& point : *cloud) {
        point.x = 1024 * rand() / (RAND_MAX + 1.0f);
        point.y = 1024 * rand() / (RAND_MAX + 1.0f);
        point.z = 1024 * rand() / (RAND_MAX + 1.0f);
    }
    
    // 保存到文件
    pcl::io::savePCDFileASCII("test_pcd.pcd", *cloud);
    std::cout << "保存了 " << cloud->size() << " 个点到 test_pcd.pcd" << std::endl;
    
    // 从文件读取
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_from_file(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::io::loadPCDFile<pcl::PointXYZ>("test_pcd.pcd", *cloud_from_file);
    
    // 显示读取的点云
    for (const auto& point : *cloud_from_file)
        std::cout << "    " << point.x << " " << point.y << " " << point.z << std::endl;
    
    return 0;
}

8. 注意事项

  1. 内存管理 :使用智能指针(如boost::shared_ptrpcl::PointCloud::Ptr)管理点云对象

  2. 文件格式:PCD文件有ASCII和二进制格式,二进制格式更节省空间

  3. 点云类型:读写时要确保点云类型匹配

  4. ROS集成 :PCL与ROS紧密集成,可以方便地与sensor_msgs::PointCloud2相互转换

相关推荐
byxdaz3 天前
使用 PCL 和 Qt 实现点云可视化与交互
qt·pcl
sanzk14 天前
ubuntu20.04.6LTS 安装PCL 1.9.1
pcl
点云SLAM1 个月前
PCL 1.12.0 释放std::free(ptr)问题解决
pcl·pcl报错·pcl智能指针释放
石悼花4 个月前
Visual Studio 2022+CMake配置PCL1.14.1
c++·cmake·visual studio·pcl·openni2
knighthood20016 个月前
Ubuntu如何显示pcl版本
pcl
boss-dog7 个月前
订阅ROS2中相机的相关话题并保存RGB、深度和点云图
pcl·ros2
黄晓魚9 个月前
MechMind结构光相机 采图SDK python调用
开发语言·图像处理·python·计算机视觉·pcl·点云处理
stay hungry foolish9 个月前
PCL + Qt + Ribbon 风格(窗口自由组合) demo展示
c++·后端·spring cloud·ribbon·vtk·pcl
coco_1998_210 个月前
Ubuntu22.04 搭建 PCL 环境(VTK源码安装),PCL测试代码
linux·vtk·点云·pcl