从PCD文件中读取与保存点云文件

2023-11-21 04:40
文章标签 读取 保存 点云 pcd

本文主要是介绍从PCD文件中读取与保存点云文件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        序列化和反序列化是将数据结构或对象转换为字节流(序列化)以及将字节流还原为数据结构或对象(反序列化)的过程。
        在计算机科学中,当我们需要将数据从内存中保存到磁盘或通过网络传输时,通常需要进行序列化操作。序列化将数据结构或对象转换为一个字节流的形式,以便能够进行持久化存储或传输。这样,在需要时就可以从字节流中还原出原始的数据结构或对象。
        反序列化则是将之前序列化过的字节流重新转换为原始的数据结构或对象,使其可以被系统再次使用。
        在点云领域中,序列化和反序列化操作允许我们将点云数据保存到文件中或通过网络传输,并在需要时重新加载点云数据。这对于点云处理、共享和传输非常有用。

        PCL(点云库)提供了一些函数来执行点云数据的序列化和反序列化操作,例如 pcl::io::savePCDFile()pcl::io::loadPCDFile()。这些函数将点云数据转换为二进制格式并保存到文件中,然后可以通过读取文件并解析字节流来还原点云数据。
        总结而言,序列化和反序列化操作是将数据结构或对象转换为字节流以及将字节流还原为原始数据结构或对象的过程,用于持久化存储、传输和再利用数据。

        字节流可以有多种不同的表现形式,其中包括二进制表示。
        二进制表示:字节流最常见的表现形式是二进制表示,即将数据转换为由 0 和 1 组成的位序列。在计算机系统中,所有的数据最终都以二进制形式存储和处理。
        文本表示:字节流也可以被解释为字符序列,具体的解释方式取决于所使用的字符编码。例如,在 ASCII 编码中,每个字节对应一个字符;而在 Unicode 编码中,每个字符可能需要多个字节进行表示。
        十六进制表示:为了方便可读性和显示,字节流经常以十六进制的形式进行表示。在十六进制表示中,每个字节用两个十六进制数字(0-9, A-F)表示。
        除了上述常见的表现形式,字节流还可以通过其他编码和压缩算法来进行表示,例如 Base64 编码、gzip 压缩等。
        在点云领域中,点云数据通常以二进制形式表示,因为它们包含大量的浮点数和坐标值,这些数据可以直接以二进制形式存储和处理。
        总结而言,字节流可以以多种不同的表现形式存在,包括二进制表示、文本表示和十六进制表示。具体的表现形式取决于数据的使用场景和编码方式。

        从文件中加载点云数据是反序列化的过程,而将点云保存到文件中是序列化的过程。具体而言:
        序列化:将数据结构或对象转换为字节流的过程。在点云库中,将点云数据转换为二进制形式,并将其写入磁盘文件,是一种序列化操作。这个过程将点云数据序列化为字节流并持久化存储到文件中。
        反序列化:将字节流还原为原始的数据结构或对象的过程。在点云库中,从磁盘文件中读取二进制数据,并将其解析为点云数据结构,是一种反序列化操作。这个过程将之前序列化的字节流反序列化为原始的点云数据。

反序列化:

#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/octants.pcd", *cloud) == -1) //* load the file{PCL_ERROR("Couldn't read file octants.pcd \n");return (-1);}std::cout << "Loaded "<< cloud->width * cloud->height<< " data points from octants.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);
}

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

#include <pcl/visualization/cloud_viewer.h>
#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 datacloud.width = 5000;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("../output_data/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;
*/pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_show(new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile("../output_data/test_pcd.pcd", *cloud_show) == -1) {PCL_ERROR("Couldn't read file  \n");return (-1);}else {pcl::visualization::CloudViewer viewer("simple cloud viewer");viewer.showCloud(cloud_show);while (!viewer.wasStopped()){// todo::}}return (0);
}

 输出的文件内容如下:

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

pcl::io::savePCDFileBinary("../output_data/test_pcd_Binary.pcd", cloud);
pcl::io::savePCDFile("../output_data/test_pcd.pcd", cloud, true);

此时输出的内容如下:

ps:11行的DATA类型为binary,最后的内容由于是以二进制形式保存,故而不可以直接看到值,需要用程序读取。

输出文件大小对比:

 


         cloud.is_dense = false;是对点云数据结构中的 is_dense 属性进行设置。这个属性用于指示点云是否密集(dense)。
        当 is_dense 被设置为 false 时,表示点云是非密集的。这意味着点云中可能存在一些缺失或无效的点,例如由于传感器噪声、遮挡或其他原因导致的点云数据不完整。在非密集的点云中,某些点的位置信息可能会丢失或不准确。
        相反,当 is_dense 被设置为 true 时,表示点云是密集的。这意味着点云中的每个点都有有效和准确的位置信息。
        通过设置 cloud.is_dense = false;,你指示该点云是非密集的,即它可能包含缺失或无效的点。


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

         这段代码使用了 C++ 的随机数生成函数 rand() 和输出流 std::cout,并进行了一些计算和打印操作。

  • std::cout << rand() << std::endl; 打印一个随机整数。rand() 函数会生成一个范围在 0 到 RAND_MAX 之间的整数,其中 RAND_MAX 是库定义的最大随机数值。该行代码将随机整数输出到标准输出流 std::cout 中,并通过 std::endl 进行换行。
  • std::cout << rand() / (RAND_MAX + 1.0f) << std::endl; 打印一个介于 0 和 1 之间的随机浮点数。这里使用 (RAND_MAX + 1.0f)RAND_MAX 转换为浮点数,然后用 rand() 除以该值来得到一个范围在 0 到 1 之间的随机浮点数。该行代码将随机浮点数输出到标准输出流中,并通过 std::endl 进行换行。

  • std::cout << 1024 * rand() / (RAND_MAX + 1.0f) << std::endl; 打印一个介于 0 和 1024 之间的随机整数。与上一行类似,这里先将 RAND_MAX 转换为浮点数,然后用 rand() 产生的随机数乘以 1024,再除以 (RAND_MAX + 1.0f) 来得到一个范围在 0 到 1024 之间的随机整数。该行代码将随机整数输出到标准输出流中,并通过 std::endl 进行换行。


#include <iostream> //标准c++库输入输出相关头文件
#include <pcl/io/pcd_io.h> // pcd读写相关头文件
#include <pcl/point_types.h> // pcl中支持的点类型头文件// 定义点云格式,具体见下章
typedef pcl::PointXYZ PointT;int main(int argc, char** argv)
{// 定义点云pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);// 读取点云,失败返回-1if (pcl::io::loadPCDFile<PointT>("../input_cloud/20230605_133316.pcd", *cloud) == -1){PCL_ERROR("couldn't read file\n");return (-1);}// 输出点云大小 cloud->width * cloud->heightstd::cout << "点云大小:" << cloud->size() << std::endl;// 保存点云文件pcl::io::savePCDFile("../output_cloud/01_saveName_2.pcd", *cloud);system("pause"); // windows命令行窗口暂停return (0);
}

参考:02-点云输入/输出(I/O)

这篇关于从PCD文件中读取与保存点云文件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/399865

相关文章

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

使用C++将处理后的信号保存为PNG和TIFF格式

《使用C++将处理后的信号保存为PNG和TIFF格式》在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示,C++提供了多种库来处理图像数据,本文将介绍如何使用stb_ima... 目录1. PNG格式保存使用stb_imagephp_write库1.1 安装和包含库1.2 代码解

vscode保存代码时自动eslint格式化图文教程

《vscode保存代码时自动eslint格式化图文教程》:本文主要介绍vscode保存代码时自动eslint格式化的相关资料,包括打开设置文件并复制特定内容,文中通过代码介绍的非常详细,需要的朋友... 目录1、点击设置2、选择远程--->点击右上角打开设置3、会弹出settings.json文件,将以下内

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl

C#读取本地网络配置信息全攻略分享

《C#读取本地网络配置信息全攻略分享》在当今数字化时代,网络已深度融入我们生活与工作的方方面面,对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键,而在C#编程的世界里,我们又该如何巧妙地读取... 目录一、引言二、C# 读取本地网络配置信息的基础准备2.1 引入关键命名空间2.2 理解核心类与方法

SpringBoot使用Apache POI库读取Excel文件的操作详解

《SpringBoot使用ApachePOI库读取Excel文件的操作详解》在日常开发中,我们经常需要处理Excel文件中的数据,无论是从数据库导入数据、处理数据报表,还是批量生成数据,都可能会遇到... 目录项目背景依赖导入读取Excel模板的实现代码实现代码解析ExcelDemoInfoDTO 数据传输

Python读取TIF文件的两种方法实现

《Python读取TIF文件的两种方法实现》本文主要介绍了Python读取TIF文件的两种方法实现,包括使用tifffile库和Pillow库逐帧读取TIFF文件,具有一定的参考价值,感兴趣的可以了解... 目录方法 1:使用 tifffile 逐帧读取安装 tifffile:逐帧读取代码:方法 2:使用

2、PF-Net点云补全

2、PF-Net 点云补全 PF-Net论文链接:PF-Net PF-Net (Point Fractal Network for 3D Point Cloud Completion)是一种专门为三维点云补全设计的深度学习模型。点云补全实际上和图片补全是一个逻辑,都是采用GAN模型的思想来进行补全,在图片补全中,将部分像素点删除并且标记,然后卷积特征提取预测、判别器判别,来训练模型,生成的像

matlab读取NC文件(含group)

matlab读取NC文件(含group): NC文件数据结构: 代码: % 打开 NetCDF 文件filename = 'your_file.nc'; % 替换为你的文件名% 使用 netcdf.open 函数打开文件ncid = netcdf.open(filename, 'NC_NOWRITE');% 查看文件中的组% 假设我们想读取名为 "group1" 的组groupName

argodb自定义函数读取hdfs文件的注意点,避免FileSystem已关闭异常

一、问题描述 一位同学反馈,他写的argo存过中调用了一个自定义函数,函数会加载hdfs上的一个文件,但有些节点会报FileSystem closed异常,同时有时任务会成功,有时会失败。 二、问题分析 argodb的计算引擎是基于spark的定制化引擎,对于自定义函数的调用跟hive on spark的是一致的。udf要通过反射生成实例,然后迭代调用evaluate。通过代码分析,udf在