zoukankan      html  css  js  c++  java
  • 001 :PCL 的基本文件类型PCD的读入和写入操作

                pcl1.91 官方文档的位置http://docs.pointclouds.org/1.9.1/group__io.html 

       1. PCD 数据格式的了解

        为什么要使用新的文件格式?

            PCD文件格式并不意味着彻底改变,而只是为了补充现有的文件格式,该文件格式由于某种原因不支持PCL带给nD点云处理的某些扩展。

           PCD不是第一个支持3D点云数据的文件类型。特别是计算机图形学和计算几何学社区已经创建了多种格式来描述使用激光扫描仪获取的任意多边形和点云。其中一些格式包括:

    • PLY-由Turk等人在斯坦福大学开发的多边形文件格式

    • STL -3D Systems创建的立体光刻CAD软件固有的文件格式

    • OBJ -Wavefront Technologies最初开发的一种几何定义文件格式

    • X3D-用于表示3D计算机图形数据的基于ISO标准的XML文件格式

    • 还有很多其他

         上述所有文件格式都有一些缺点,这将在下一部分中进行解释-这是自然的,因为它们是在发明感应技术和算法之前为不同的目的和在不同的时间创建的。

       文件格式  

    文件格式标题

               每个PCD文件都包含一个标头,该标头标识并声明存储在文件中的点云数据的某些属性。PCD的标头必须以ASCII编码。

                    注意

                   使用新行( n)分隔PCD文件中指定的每个标头条目以及ascii点数据(见下文)。

               从0.7版本开始,PCD标头包含以下条目:

    • VERSION-指定PCD文件版本

    • FIELDS-指定点可以具有的每个维度/字段的名称例子:

      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
      FIELDS j1 j2 j3                             # moment invariants
      ...
      
    • SIZE-定每个维度的大小(以字节为单位)。例子:

      • 无符号char / char有1个字节

      • 无符号的short / short有2个字节

      • unsigned int / int / float有4个字节

      • double有8个字节

    • TYPE-将每个维度的类型指定为char。当前接受的类型是

      • I-表示带符号的类型int8(char),int16(short)和int32(int

      • U-表示无符号类型uint8(unsigned char),uint16(unsigned short),uint32(unsigned int

      • F-表示浮点类型

    • COUNT-定每个维度有多少个元素例如,x数据通常有1个元素,但是像VFH这样的特征描述符 有308个。基本上,这是在每个点引入nD直方图描述符并将它们视为单个连续内存块的方法。默认情况下,如果不存在COUNT,则所有尺寸的计数均设置为1。

    • WIDTH-以点数指定点云数据集的宽度WIDTH具有两个含义:

      • 它可以为未组织的数据集指定云中的点总数(等于POINTS,请参见下文);

      • 它可以指定组织的点云数据集的宽度(一行中的总点数)。

      另请参阅HEIGHT

      注意

      一个有组织的点云数据集是赋予点云类似于一个有组织的图像(或矩阵)状的结构,其中,数据被划分为行和列的名称。这种点云的示例包括来自立体摄像机或飞行时间摄像机的数据。有组织的数据集的优势在于,通过了解相邻点(例如,像素)之间的关系,最近邻居操作会更加高效,从而加快了计算速度并降低了PCL中某些算法的成本。

      例子:

      WIDTH 640     # there are 640 points per line
      
    • HEIGHT-以点数指定点云数据集的高度HEIGHT有两个含义:

      • 它可以指定有组织的点云数据集的高度(总行数);

      • 对于未组织的数据集,将其设置为1从而用于检查数据集是否已组织)。

      例:

      WIDTH 640       # Image-like organized structure, with 480 rows and 640 columns,
      HEIGHT 480      # thus 640*480=307200 points total in the dataset
      

      例:

      WIDTH 307200
      HEIGHT 1        # unorganized point cloud dataset with 307200 points
      
    • VIEWPOINT-为数据集中的点指定采集视点。以后可能会用它来构建不同坐标系之间的变换,或者用于辅助需要一致方向的特征(例如表面法线)。

      视点信息被指定为平移(tx ty tz)+四元数(qw qx qy qz)。默认值为:

      VIEWPOINT 0 0 0 1 0 0 0
      
    • POINTS-定云中的总点数从0.7版开始,它的用途有点多余,因此我们希望在将来的版本中将其删除。

      例:

      POINTS 307200   # the total number of points in the cloud
      
    • DATA-指定存储点云数据的数据类型。从0.7版开始,支持两种数据类型:asciibinary有关更多详细信息,请参见下一部分。

    注意

            标头最后一行(DATA之后的下一个字节被视为点云数据的一部分,因此将被解释为点云数据。

             警告

              标头条目必须按照上述顺序精确指定,即:

       VERSION
       FIELDS
       SIZE
       TYPE
       COUNT
       WIDTH
       HEIGHT
       VIEWPOINT
       POINTS
       DATA
    

        资料储存类型

          从0.7版开始,.PCD文件格式使用两种不同的模式来存储数据:

    • ASCII形式,每个点都换行:

      p_1
      p_2
      p_3
      p_4
      ...
      
      p_n
      

               注意

              从PCL版本1.0.1开始,NaN的字符串表示形式为“ nan”。

    • 二进制形式,其中数据是pcl :: PointCloud.points数组/向量的完整内存副本 在Linux系统上,我们使用mmap / munmap 操作对数据进行最快的读/写访问

           以简单的ascii格式存储点云数据,将点,行,空格或制表符上的每个点分隔开,上面没有任何其他字符,并以二进制转储格式存储,这使我们能够同时兼顾两个方面的优点:速度,取决于基础应用程序ascii格式允许用户打开         点云文件并使用gnuplot等标准软件工具对其进行绘制, 或使用sedawk等工具对其进行操作。

           2.pcd 文件的读写

            

     1 #include<iostream>
     2 #include<pcl/io/pcd_io.h>
     3 #include<pcl/point_types.h>
     4 
     5 int
     6 main(int argc, char**argv)
     7 {
     8     //声明点云对象指针(点云类型为XYZ点云结构),并初始化该对象,pointcloud是一个泛型类,所以每次使用的记得申明
     9     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    10     //
    11     int flatMeathod = 1;
    12     //方式1
    13     if (flatMeathod ==0)
    14     {    
    15         printf("采用pcl::io::loadPCDFile<pcl::PointXYZ>的方式读取 
    ");
    16 
    17         
    18         //判断文件是否存在
    19         if (pcl::io::loadPCDFile<pcl::PointXYZ>("C:/Users/Admin/Desktop/PCL/bin/2/read_pcd/Debug/test_pcd.pcd", *cloud) == -1)
    20         {
    21             PCL_ERROR("could not find test_pcd.pcd");
    22             return -1;
    23         }
    24     }
    25     //方式2
    26     else
    27     {
    28         printf("采用pcl::PCLPointCloud2 的方式读取");
    29         //整理需要先转换为PCLPointCloud2类型
    30         pcl::PCLPointCloud2 cloud2;
    31         pcl::io::loadPCDFile("C:/Users/Admin/Desktop/PCL/bin/2/read_pcd/Debug/test_pcd.pcd", cloud2);
    32         if (pcl::io::loadPCDFile("", cloud2) == -1)
    33         {
    34             return -1;
    35         }
    36         else
    37         {
    38             pcl::fromPCLPointCloud2(cloud2, *cloud);
    39         }
    40 
    41     
    42     }
    43     for (size_t i = 0; i < cloud->points.size(); i++)
    44     {
    45         std::cout << " " << cloud->points[i].x << " " << cloud->points[i].y << " " << cloud->points[i].z << std::endl;
    46     }
    47     return 0;
    48 
    49 
    50 
    51 
    52     
    53     
    54 }

    3 pcd 写入

     1 #include <iostream>
     2 #include <pcl/io/pcd_io.h>
     3 #include <pcl/point_types.h>
     4 
     5 int
     6 main(int argc,char**argv)
     7 {
     8 pcl::PointCloud<pcl::PointXYZ> cloud;
     9 // 创建点云
    10 cloud.width=5;   //点云数据的宽度
    11 cloud.height=1;    //点云数据的高度
    12 cloud.is_dense=false;//是否为密度点云
    13 cloud.points.resize(cloud.width*cloud.height);
    14 for(size_t i=0;i<cloud.points.size();++i)
    15 {
    16 cloud.points[i].x=1024*rand()/(RAND_MAX+1.0f);
    17 cloud.points[i].y=1024*rand()/(RAND_MAX+1.0f);
    18 cloud.points[i].z=1024*rand()/(RAND_MAX+1.0f);
    19 }
    20 pcl::io::savePCDFileASCII("test_pcd.pcd",cloud);
    21 std::cerr<<"Saved "<<cloud.points.size()<<" data points to test_pcd.pcd."<<std::endl;
    22 for(size_t i=0;i<cloud.points.size();++i)
    23 std::cerr<<"    "<<cloud.points[i].x<<" "<<cloud.points[i].y<<" "<<cloud.points[i].z<<std::endl;
    24 return(0);
    25 }

            

  • 相关阅读:
    共享内存基本操作
    mmap 操作
    busybox 安装问题解决
    ubuntu apt-get failed
    live555 学习资料
    循环队列实现
    socket 聊天室实现
    socket 映射服务器--(可处理多客户端连接(fork),显示退出信息)
    socket 映射服务器程序
    vector和list插入性能对比
  • 原文地址:https://www.cnblogs.com/codeAndlearn/p/11609364.html
Copyright © 2011-2022 走看看