PCL点云库(2) — IO模块

news2024/9/9 4:39:49

目录

2.1 IO模块接口

2.2 PCD数据读写

(1) PCD数据解析

(2)PCD文件读写示例

2.3 PLY数据读写

(1)PLY数据解析

(2)PLY文件读写示例

2.4 OBJ数据读写

(1)OBJ数据解析

(2)OBJ文件读写示例

2.5 VTK数据读写

(1)VTK数据解析

(2)VTK文件读写示例

2.6 保存为PNG


2.1 IO模块接口

参考文章:PCL函数库摘要——IO模块_pcl/io_悠缘之空的博客-CSDN博客

(1)Class pcl::FileReader

类FileReader定义了PCD文件的读取接口,主要用做其他读取类的父类。

(2)Class pcl::FileWriter

类FileWriter 与 FileReader对应,是写人PCD文件的类接口定义,可以作为其它写入类的父类。

(3)Class pcl::Grabber

类Grabber为PCL1.X对应的设备驱动接口的基类定义。

(4)Class openni_wrapper::OpenNIDevice

类OpenNIDevice定义OpenNI设备的基类,继承该基类可以实现不同的OpenNI设备子类,用于获取包括红外数据、RGB数据、深度图像数据等。

(5)Class openni_wrapper::DeviceKinect

(6)Class openni_wrapper::DevicePrimesense

(7)Class openni_wrapper::DeviceXtionPro

以上3个类分别封装了Kinect,Primesense,XtionPro相关设备操作和数据获取操作实现,其详细接口参考其父类OpenNIDevice的关键函数说明。

(8)Class openni_wrapper::DeviceONI

封装了利用ONI文件回放虚拟类kinect设备的操作和数据获取操作实现,其详细接口参考其父类OpenNIDevice的关键函数说明。

(9)Class openni_wrapper::OpenNIDriver

类OpenNIDriver采用单例模式实现对底层驱动的封装,里面包含一xn::Context对象,提供给所有设备使用。该类提供了枚举和访问所有设备的方法实现。

(10)Class openni_wrapper::OpenNIException

类OpenNIException封装一般的异常处理实现。

(11)Class openni_wrapper::Image

类Image是简单的图像数据封装基类。

(12)Class openni_wrapper::ImageBayerGRBG

(13)Class openni_wrapper::ImageRGB24

(14)Class openni_wrapper::ImageYUV422 Class Reference

以上3个类分别实现了对原始数据 BayerGRBG ,RGB24、YUV422到图像转化接口,详细参考其父类关键函数说明。

(15)Class pcl::OpenNIGrabber

类OpenNIGrabber 实现对OpenNI设备(例如Primesense PSDK,MicrosoftKinect,Asus XTion Pro/Live)数据的采集接口,详细参考其父类Grabber 关键函数说明。

(16)Class pcl::PCDReader

(17)Class pcl::PLYReader

以上两个类分别是PCD、PLY文件格式读入接口的实现,详细参考其父类pcl: :FileReader。

(18)Class pcl::PLYWriter

(19)Class pcl::PCDWriter

以上两个类分别是PCD、PLY文件格式写出接口的实现,详细参考其父类pcl: :FileWriter。

(20)Class pcl::io::IOException

类pcl::io::IOException 是I/O相关的异常处理接口实现,详细参考其父类PCLEx-ception。

(21)I/O模块其他关键成员

2.2 PCD数据读写

(1) PCD数据解析

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z _
SIZE 4 4 4 1
TYPE F F F U
COUNT 1 1 1 4
WIDTH 112099
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 112099
DATA binary
  • VERSION 0.7:指定pcd文件的版本。
  • FIELDS:指定每个点可以具有的维度,以及每个维度所代表的含义。例如:FIELDS x y z r g b表示该点的位置信息(x,y,z),颜色信息(r,g,b)。
  • SIZE:以字节为单位指定每个数据所占用的内存。
  • TYPE:指定每个数据的数据类型。其中无效的点的通常存储为NAN类型。

            I:可表示int8,int16,int32。
            U:可表示uint8,unit16,uint32。
            F:表示float(上图所用的为浮点类型)。

  • COUNT:指定每个维度有多少元素。例如xyz数据通常只有一个元素。
  • WIDTH:指定数据点的宽度,它包含两个含义:(1)可指定点云总个数(与POINTS相同),用于无组织的数据。(2)可指定有组织点云数据的宽度(连续点的总数)。
  • HEIGTH: 指定数据点的高度,它包含两个含义:(1)可指定有组织的点云数据的高度(总行数)。(2)对未组织的数据,它被设置为1。
  • POINTS:指定点云总个数。
  • VIEWPOINT:采集数据时的视点(由平移tx,ty,tz和四元数qw,qx,qy,qz组成)。
  • DATA:点云数据存储的数据类型(支持ascii和binary)。如果以ASCII形式,每一点占据一个新行。

(2)PCD文件读写示例

cmake_minimum_required(VERSION 2.6)
project(pcd)
 
find_package(PCL 1.10 REQUIRED)
 
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
 
add_executable(pcd pcd.cpp)
 
target_link_libraries (pcd ${PCL_LIBRARIES})
 
install(TARGETS pcd RUNTIME DESTINATION bin)
#include <iostream>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;

int main()
{
    pcl::PCDReader reader;
    pcl::PCLPointCloud2 org;
    pcl::io::loadPCDFile("../pcdfile.pcd",org);

    for(auto &f : org.fields)
    cout << f.name;

    pcl::PointCloud<pcl::PointXYZ> cloud;
    pcl::fromPCLPointCloud2<pcl::PointXYZ>(org,cloud);

    pcl::PCDWriter writer;
    pcl::io::savePCDFileBinaryCompressed("../savepcdfile.pcd",cloud);
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer);
    viewer->setWindowName("PCDFile");
    viewer->addPointCloud(cloud.makeShared());
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
    }
    return 0;
}

2.3 PLY数据读写

(1)PLY数据解析

典型的PLY文件结构:

  • 头部
  • 顶点列表
  • 面片列表
  • 其他元素列表
ply
format ascii 1.0
element vertex 14806
property float x
property float y
property float z
property float nx
property float ny
property float nz
element face 0
property list uchar int vertex_indices
end_header
0.91441 -0.536438 0.822624 -0.0442205 -0.930906 0.362575
0.933494 -0.545228 0.820276 0.073409 -0.981856 0.174844
...

(2)PLY文件读写示例

cmake_minimum_required(VERSION 2.6)
project(ply)
 
find_package(PCL 1.10 REQUIRED)
 
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
 
add_executable(ply ply.cpp)
 
target_link_libraries (ply ${PCL_LIBRARIES})
 
install(TARGETS ply RUNTIME DESTINATION bin)
#include <iostream>
#include <pcl/point_cloud.h>
#include <pcl/io/ply_io.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;

int main()
{
    pcl::PCLPointCloud2 cloud;
    pcl::io::loadPLYFile("../ply.ply",cloud);

    pcl::PLYReader reader;
    pcl::PLYWriter writer;

    pcl::PointCloud<pcl::PointXYZ> cloud1;
    pcl::fromPCLPointCloud2<pcl::PointXYZ>(cloud,cloud1);

    pcl::io::savePLYFile("saveply.ply",cloud,Eigen::Vector4f::Zero (),
                         Eigen::Quaternionf::Identity (),
                         true);

    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer);
    viewer->setWindowName("PLYFile");
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> color(cloud1.makeShared(), "y");
    viewer->addPointCloud(cloud1.makeShared(),color);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,2);

    while(!viewer->wasStopped())
        viewer->spinOnce(100);

    return 0;
}

2.4 OBJ数据读写

(1)OBJ数据解析

mtllib cube.mtl
g default
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
vt 0.001992 0.001992
vt 0.998008 0.001992
vt 0.001992 0.998008
vt 0.998008 0.998008
...

mtllib:代表材质库,通常指向到某个mtl文件

  • v(vertices):几何形状的顶点,因为物体是由面构成的,而面是由线构成的,线由点构成的,所以无论是何形状,都必须要有几何顶点;一些应用支持顶点颜色,通过在x y z后面跟上red, green, blue值来表示。颜色值的范围为0到1.0。
  • vt(vertex texture):顶点纹理,代表当前顶点对应纹理图的哪个像素,通常是0-1,如果大于1,就相当于将纹理重新扩充然后取值,比如镜像填充、翻转填充之类的,然后根据纹理图的宽高去计算具体像素位置
  • vn(vertex normal):顶点法线,物理里面有说过眼睛看到物体是因为光线经过物体表面反射到眼睛,所以这个法线就是通过入射光线计算反射光线使用的法线。
  • f(face):大部分几何体都包括面,除非是像头发丝那一类模型只包含一根根头发的顶点,而且大部分模型的头发也用的面片的方法渲染的。

        其他参考:obj格式解析_obj格式详解_风翼冰舟的博客-CSDN博客

(2)OBJ文件读写示例

cmake_minimum_required(VERSION 2.6)
project(obj)
 
find_package(PCL 1.10 REQUIRED)
 
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
 
add_executable(obj obj.cpp)
 
target_link_libraries (obj ${PCL_LIBRARIES})
 
install(TARGETS obj RUNTIME DESTINATION bin)
#include <iostream>

#include <pcl/point_cloud.h>
#include <pcl/io/obj_io.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;

int main()
{
    pcl::PolygonMesh mesh;
    pcl::PCLPointCloud2 cloud;
    pcl::TextureMesh tmesh;

#if 0
    pcl::io::loadOBJFile("../obj.obj",cloud);
    pcl::io::loadOBJFile("../obj.obj",mesh);
    pcl::io::loadOBJFile("../obj.obj",tmesh);
#else
    pcl::OBJReader objreader;
    objreader.read("../obj.obj",cloud);
    objreader.read("../obj.obj",mesh);
    objreader.read("../obj.obj",tmesh);
#endif

    pcl::io::saveOBJFile("../saveobj.obj",mesh);

    pcl::PointCloud<pcl::PointXYZ> cloudxyz;
    pcl::fromPCLPointCloud2<pcl::PointXYZ>(cloud,cloudxyz);

    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer);
    viewer->setWindowName("OBJFile");

    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> color(cloudxyz.makeShared(), "z");
    viewer->addPointCloud(cloudxyz.makeShared(),color);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,2);
    viewer->addPolygonMesh(mesh);

    while(!viewer->wasStopped())
        viewer->spinOnce(100);

    return 0;
}

2.5 VTK数据读写

(1)VTK数据解析

# vtk DataFile Version 2.0
vtk output
ASCII
DATASET POLYDATA
POINTS 2312 float
0.263107 0 0.425176 0.33131 0 0.374478 0.389942 0 0.312962 
0.43731 0 0.242405 0.472045 0 0.164845 0.493143 0 0.0825238 
  • 第一行是说明vtk文件的version(这是legacy 版本,此外还有较新的xml版本)
  • 第二行是文件描述,随便写什么
  • 第三行是ASCII或者BINARY
  • 第四行是说明数据类型,有STRUCTURED_POINTS,STRUCTURED_GRID,RECTILINEAR_GRID,POLYDATA
  • 后面为数据,它分为三个部分:POINTS 点数据,CELSS 网格数据,CELL_TYPES网格类型
     

(2)VTK文件读写示例

cmake_minimum_required(VERSION 2.6)
project(vtkfile)
 
find_package(PCL 1.10 REQUIRED)
find_package(VTK REQUIRED)

include(${VTK_USE_FILE})
link_directories(${VTK_LIBRARY_DIRS})
 
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable(vtkfile vtkfile.cpp)
 
target_link_libraries (vtkfile ${PCL_LIBRARIES} ${VTK_LIBRARIES})
target_link_libraries (vtkfile ${VTK_LIBRARIES})
 
install(TARGETS vtkfile RUNTIME DESTINATION bin)
#include <iostream>
#include <pcl/point_cloud.h>
#include <pcl/io/vtk_io.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/io/obj_io.h>

using namespace std;

int main()
{
    pcl::PCLPointCloud2 cloud;
    pcl::PolygonMesh mesh,mesh1,mesh2;

#if 0
    pcl::io::loadPolygonFile("../vtk.vt",mesh);
#else
    pcl::io::loadPolygonFileVTK("../vtk.vtk",mesh);
    pcl::io::loadPolygonFileVTK("../vtk.vtk",mesh2);
#endif
    
    pcl::PointCloud<pcl::PointXYZ> cloudxyz;
    pcl::fromPCLPointCloud2<pcl::PointXYZ>(mesh.cloud,cloudxyz);

    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer);
    viewer->setWindowName("VTKFile");

    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> color(cloudxyz.makeShared(),"y");
    viewer->addPointCloud(cloudxyz.makeShared(),color);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,3);
    viewer->addPolygonMesh(mesh);

    while(!viewer->wasStopped())
        viewer->spinOnce(100);

    return 0;
}

2.6 保存为PNG

#include <iostream>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/png_io.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace std;

int main()
{

    pcl::PCDReader reader;
    pcl::PCLPointCloud2 org;

    pcl::io::loadPCDFile("../cow.pcd",org);

    for(auto &f : org.fields)
        cout << f.name << endl;

    pcl::PointCloud<pcl::PointXYZ> cloud;
    pcl::fromPCLPointCloud2<pcl::PointXYZ>(org,cloud);

    pcl::io::savePNGFile("../savepng.png",cloud,"rgb");
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> color(cloud.makeShared(), "z");
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer);
    viewer->setWindowName("savePNG");
    viewer->addPointCloud(cloud.makeShared(),color);
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,2);
    
    while(!viewer->wasStopped())
        viewer->spinOnce(100);

    return 0;
}}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/458920.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QMS-云质说质量 - 10 我和我的客户投诉(2) - 客户逐利 驱除良币

云质QMS原创 转载请注明来源 作者&#xff1a;王洪石 上策伐谋 中策伐交 前面发过一篇关于客户投诉的文章“逢年过节要祈祷”&#xff0c;引起了很多质量人的共鸣&#xff0c;特别是汽车零部件行业曾经和正在负责客诉的质量同行们。 真实的产品质量问题&#xff0c;是否发生只…

Linux-初学者系列2——用户组管理和权限管理

用户组管理和权限管理 Linux-初学者系列2_用户组管理和权限管理一、所有者1、查看文件的所有者指令 2、修改文件所有者指令实操 二、组创建语法指令&#xff1a;实操&#xff1a; 三、所在组1、查看文件/目录所在组基本指令&#xff1a;实操&#xff1a; 2、修改文件所在组基本…

【读书笔记】高效能人士的7个习惯

高效能人士的7个习惯-史蒂芬柯维 个人成功1. 积极主动&#xff08;BE PROACTIVE&#xff09;2. 以终为始&#xff08;BEGIN WITH THE END IN MIND&#xff09;3. 要事第一&#xff08;PUT FIRST THINGS FIRST&#xff09;个人成功总结 集体成功4. 双赢思维&#xff08;THINK WI…

flex布局属性详解

Flex布局 flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content其他orderflexalign-self 含义:Flex是Flexible Box的缩写&#xff0c;意为”弹性布局”&#xff0c;用来为盒状模型提供最大的灵活性。 flex-direction flex-direction属性决定主轴的方向&…

服务(第十二篇)LVS-DR模式

数据包流向分析&#xff1a; &#xff08;1&#xff09;客户端发送请求到 Director Server&#xff08;负载均衡器&#xff09;&#xff0c;请求的数据报文&#xff08;源 IP 是 CIP,目标 IP 是 VIP&#xff09;到达内核空间。 &#xff08;2&#xff09;Director Server 和 Re…

022 - C++ 析构函数

上期我们讨论了构造函数。认识了它是什么以及如何使用它。如果你没有看上一期&#xff0c;那么你一定要回去看一下。 今天我们要讨论一下它的“孪生兄弟”&#xff0c;析构函数&#xff0c;它们在某些方面非常相似。 构造函数是你创建一个新的实例对象时运行&#xff0c;而析…

无线测温系统在煤矿高压电气设备上的应用

摘要&#xff1a;随着社会经济的不断发展&#xff0c;电力系统向着高电压、高容量的方向前进着&#xff0c;电力系统全新的技术与设备层出不穷&#xff0c;电力的输送能力不断提升。然而&#xff0c;高压电气设备承载的高压电力负荷也让其自身的温升问题成为了威胁电网稳定的元…

张驰咨询:企业如何在不确定的环境中逆势增长?

企业不确定环境主要包括以下几个方面&#xff1a; 1、宏观经济环境的不确定性 包括国内外经济形势、政策调整、外汇汇率等因素的变化&#xff0c;会对企业的发展带来不确定性。 2、市场需求的不确定性 市场需求的变化&#xff0c;包括消费者需求、市场规模、市场结构等方面…

【自制键盘01】CH9329代码两则,让任何单片机都能做键盘

简介 CH9329是一款由WCH&#xff08;Nanjing QinHeng Electronics Co. Ltd.&#xff09;生产的USB转串口芯片&#xff0c;可以方便地将USB接口转换为串口接口&#xff0c;它在键盘设计这块可以实现作为MCU和电脑设备的“中间人”&#xff0c;把串口信号转换为按键。 引脚定义 …

如何实现电脑通过手机上网?1分钟搞定!

案例&#xff1a;电脑没网时&#xff0c;如何通过手机上网&#xff1f; 【想用电脑看电影&#xff0c;但是附近没有Wi-Fi。朋友说可以说电脑可以通过手机上网&#xff0c;但我们都不知道具体如何操作&#xff0c;有没有小伙伴可以教教我们。】 在没有Wi-Fi或有线网络接入时&a…

《Left ventricular hypertrophy detection using electrocardiographic signal》阅读笔记

论文的摘要 Left ventricular hypertrophy (LVH) indicates subclinical organ damage, associating with the incidence of cardiovascular diseases. From the medical perspective, electrocardiogram (ECG) is a low-cost, non-invasive, and easily reproducible tool th…

低代码平台-宜搭的核心概念

宜搭的核心概念 文章目录 全局变量基本的变量使用查看输出内容以及调试方式事件绑定页面生命周期条件渲染循环渲染自定义样式表单校验 全局变量 在左侧数据源中添加变量&#xff0c;添加变量的写法和js的写法一致。 基本的变量使用 给文本绑定数据源&#xff0c;点击左侧刚才定…

蒸发器前氟离子超标的解决方法

深度除氟工艺 1、活性氧化铝&#xff1a;需PH调整至酸性 2、碳基/羟基磷灰石&#xff1a;再生次数有限制 3、反渗透膜&#xff1a;造价成本高 4、特种除氟树脂&#xff1a;预处理需做好 氟化物选择吸附树脂 Tulsimer CH-87 是一款去除水溶液中氟离子的专用的凝胶型选择性…

LVS负载均衡之DR模式

DR调度服务器 192.168.255.128 Nginx节点服务器1 192.168.255.130 Nginx节点服务器2 192.168.255.131 统一虚拟ip&#xff08;vip&#xff09; 192.168.255.188 访问客户端 192.168.255.134 第一步首先关掉所有虚拟机的防火墙 systemctl stop firewalld.service setenfor…

Maya - 后缀为xgen文件导出到虚幻引擎

Xgen是集成在Maya中的工具&#xff0c;可以在指定模型表面生成和控制大量物体的集成和离散&#xff1b;经常用于复杂的毛发制作&#xff0c;可以方便的用笔刷等控制曲线&#xff08;curves&#xff09;和导引线&#xff08;guides&#xff09;等线条来控制毛发的走向&#xff1…

【MySQL】插入文件路径,反斜杠消失

系列文章 C#底层库–MySQL脚本自动构建类&#xff08;insert、update语句生成&#xff09; 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/129179216 C#底层库–MySQL数据库访问操作辅助类&#xff08;推荐阅读&#xff09; 本文链接&#xff1a;h…

克隆Linux系统(centos)

克隆前得保证你有一台Linux系统的虚拟机了。 如果没有&#xff0c;可以参考这篇文章&#xff1a; 安装VMware虚拟机、Linux系统&#xff08;CentOS7&#xff09;_何苏三月的博客-CSDN博客 按照示意图一步一步执行即可。 克隆前先关闭运行的虚拟机系统。 然后右键已安装的虚拟…

看完就懂的vue2与vue3响应式的区别

一、前言 数据响应式 所谓数据响应式就是建立响应式数据与依赖&#xff08;调用了响应式数据的操作&#xff09;之间的关系&#xff0c;当响应式数据发生变化时&#xff0c;可以通知那些使用了这些响应式数据的依赖操作进行相关更新操作&#xff0c;可以是DOM更新&#xff0c;也…

视频音频提取器推荐:快速提取视频中的音频!

视频中的音频可以用于很多用途&#xff0c;比如制作配乐、音频剪辑等。但是&#xff0c;许多人并不知道如何将视频中的音频提取出来。如果您也是这样的情况&#xff0c;那么本文为您介绍一个简单易用的视频音频提取器&#xff1a;。 它是一个免费的在线工具&#xff0c;可以帮…

【Android FrameWork(一)】- 启动程序 init

文章目录 背景源码分析&#xff08;第一个启动程序 init&#xff09;1.main.cpp2.init.cpp3.property_service.cpp4,LoadBootScripts 拓展知识Android的架构图I/O多路复用 总结 离职找工作间隙&#xff0c;停下脚步整理下自己的知识体系&#xff0c;把之前忙于开发未曾整理的知…