云点数据读写

news/2025/6/19 18:10:43

一、常见点云数据格式

  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::PointPickingEventconst pcl::visualization::PointPickingEvent &event当用户选择点时触发
pcl::visualization::KeyboardEventconst pcl::visualization::KeyboardEvent &event键盘事件
pcl::visualization::MouseEventconst 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相互转换


https://dhexx.cn/news/show-5501459.html

相关文章

B+树节点与插入操作

B树节点与插入操作 设计B树节点 在设计B树的数据结构时&#xff0c;我们首先需要定义节点的格式&#xff0c;这将帮助我们理解如何进行插入、删除以及分裂和合并操作。以下是对B树节点设计的详细说明。 节点格式概述 所有的B树节点大小相同&#xff0c;这是为了后续使用自由…

Python多任务编程:进程全面详解与实战指南

1. 进程基础概念 1.1 什么是进程&#xff1f; 进程(Process)是指正在执行的程序&#xff0c;是程序执行过程中的一次指令、数据集等的集合。简单来说&#xff0c;进程就是程序的一次执行过程&#xff0c;它是一个动态的概念。 想象你打开电脑上的音乐播放器听歌&#xff0c;…

基于尚硅谷FreeRTOS视频笔记——16—FreeRTOS的任务创建和删除

动态创建任务函数 简介 BaseType_t xTaskCreate&#xff1a;x表示定义出来的类型。Task表示在Task.c文件中。 1.TaskFunction_t pxTaskCode&#xff1a;任务的地址。 2.const char * const pcName&#xff1a;任务的别名&#xff0c;就是外号。但要注意&#xff0c;最大长度…

RV1126网络环境TFTPNFS搭建(二)

二、RV1126 开发板TFTP环境搭建 2.1、Ubuntu下安装和配置 xinetd 执行以下指令&#xff0c;安装 xinetd sudo apt-get install xinetd 执行以下指令创建一个 xinetd.conf 文件 sudo vi /etc/xinetd.conf 修改 xinetd.conf 文件内容如下&#xff1a; # Simple configurat…

C语言状态字与库函数详解:概念辨析与应用实践

C语言状态字与库函数详解&#xff1a;概念辨析与应用实践 一、状态字与库函数的核心概念区分 在C语言系统编程中&#xff0c;"状态字"和"库函数"是两个经常被混淆但本质完全不同的概念&#xff0c;理解它们的区别是掌握系统编程的基础。 1. 状态字&…

字节头条golang二面

docker和云服务的区别 首先明确Docker的核心功能是容器化&#xff0c;它通过容器技术将应用程序及其依赖项打包在一起&#xff0c;确保应用在不同环境中能够一致地运行。而云服务则是由第三方提供商通过互联网提供的计算资源&#xff0c;例如计算能力、存储、数据库等。云服务…

深入剖析 Java Web 项目序列化:方案选型与最佳实践

在 Java Web 开发中&#xff0c;“序列化”是一个你无法绕过的概念。无论是缓存数据、共享 Session&#xff0c;还是进行远程过程调用&#xff08;RPC&#xff09;或消息传递&#xff0c;序列化都扮演着底层数据搬运工的角色。它负责将内存中的 Java 对象转换成可传输或可存储的…

【数据结构入门训练DAY-18】信息学奥赛一本通T1331-后缀表达式的值

文章目录 前言一、题目二、解题思路总结 前言 本次训练内容&#xff1a; 栈的复习。栈模拟四则运算计算问题的练习。训练解题思维。 一、题目 从键盘读入一个后缀表达式&#xff08;字符串&#xff09;&#xff0c;只含有0-9组成的运算数及加&#xff08;&#xff09;、减…

Linux文件时间戳详解:Access、Modify、Change时间的区别与作用

在 Linux 系统中&#xff0c;文件的这三个时间戳&#xff08;Access、Modify、Change&#xff09;分别表示不同的文件状态变更时间&#xff0c;具体含义如下&#xff1a; 1. Access Time (Access) 含义&#xff1a;文件最后一次被访问的时间&#xff08;读取内容或执行&#xf…

Kotlin实现Android应用保活方案

Kotlin实现Android应用保活优化方案 以下的Android应用保活实现方案&#xff0c;更加符合现代Android开发规范&#xff0c;同时平衡系统限制和用户体验。 1. 前台服务方案 class OptimizedForegroundService : Service() {private val notificationId 1private val channel…