pcl 点云压缩与解压缩

简介: pcl 点云压缩与解压缩

为什么要进行点云压缩

点云带有大量的数据,不仅包括三维信息,还有额外的距离,颜色,法向量等等。此外,点云可以快速生成,这会占有大量的内存资源。一旦点云必须被存储或者用于通信传输,对于点云的压缩技术就显得十分重要了。PCL提供了点云压缩功能,它支持对各种类型点云的压缩,其中包括无序点云,此外,在八叉树结构下的数据支持高效地合并多个来自不同数据源的点云。

压缩pcl::PointXYZ类型数据

Code

最基本的操作 : 将读取点云,然后压缩成字节流,再将字节流解压。

    //先读取点云 
    /*创建一个点云变量 的共享指针  并实例化*/
    pcl::PointCloud<pcl::PointXYZ> cloud;
          /*从 pcd文件  读取 点云*/
    if(pcl::io::loadPCDFile<pcl::PointXYZ>("../test_pcd.pcd",cloud)==-1)
    {    
        //  返回值是 -1  代表 没有读到
        PCL_ERROR("Couldn't read file test_pcd.pcd \n");
        return  (-1);
    }

先读取点云 从 pcd文件 读取 点云

     //打印压缩前从文件中读取的点云
    std::cout<<"before"<<std::endl;
    for(size_t i;i<cloud.points.size();++i)
    { 
        std::cout<<"x="<<cloud.points[i].x<<"\t"<<"y="<<cloud.points[i].y<<"\t"<<"z="<<cloud.points[i].z<<std::endl;
    }

打印压缩前从文件中读取的点云

压缩部分

       /* 设置压缩 和解压 时 的结果信息是否打印显示出来  */
    bool showStatistics = true ;
    //bool showStatistics = false;

设置压缩 和解压 时 的结果信息是否打印显示出来
在这里插入图片描述
打印的 信息 就是 上面 这种

      /* 压缩选项  可以参考 usr/include/pcl/compression/compression_profiles.h   */    
    pcl::io::compression_Profiles_e compressionProfile = pcl::io::MANUAL_CONFIGURATION;//设定为允许为高级参数化进行手工配置 

这个部分要详细说明下
pcl::io::MANUAL_CONFIGURATION 这个是压缩类型的一种 , 用来配置 八叉树的压缩参数。如果选择进行手工设置,则需要在后面进行相关的参数设置。共6个参数。

可以参考 usr/include/pcl/compression/compression_profiles.h
在这里插入图片描述
这个是文件里的 可选的压缩类型

在这里插入图片描述
下面分别对应着 不同类型对应的参数
一共有6个参数

  1. pointResolution 点的分辨率该变量决定了点的坐标在编码时可以精确的程度,但是该变量只在进行细节编码(detail coding)时才会生效
  2. octreeResolution 划分八叉树时最小块
  3. doVoxelGridDownDownSampling 是否对点云文件进行下采样。为true时,对点云文件进行下采样,以体素的中心点的坐标来代替整个体素内的点的坐标,而颜色则以体素内所有点的颜色的均值为代表,此时pointResolution不会生效。为false时,则进行细节编码,即编码一个体素内的具体坐标与颜色,实现方式是计算体素内每个点到体素左下角的偏移量,并通过整除pointResolution来得到整数坐标,而颜色则需编码体素内每个点的颜色相对于平均值的残差
  4. iFrameRate 用来决定进行I帧编码的频率,如果此数值为30,则每隔30帧进行一次I帧编码,中间的帧则进行P帧编码
  5. colorBitResolution 表示颜色的RGB的保留的有效位数
  6. doColorEncoding 决定是否进行颜色编码。

下面列举下不同 编码类型的对应的含义

LOW_RES_ONLINE_COMPRESSION_WITHOUT_COLOR 分辨率1cm3,无颜色,快速在线编码
LOW_RES_ONLINE_COMPRESSION_WITH_COLOR 分辨率1cm3,有颜色,快速在线编码
MED_RES_ONLINE_COMPRESSION_WITHOUT_COLOR 分辨率5mm3,无颜色,快速在线编码
MED_RES_ONLINE_COMPRESSION_WITH_COLOR 分辨率5mm3,有颜色,快速在线编码
HIGH_RES_ONLINE_COMPRESSION_WITHOUT_COLOR 分辨率1mm3,无颜色,快速在线编码
HIGH_RES_ONLINE_COMPRESSION_WITH_COLOR 分辨率1mm3,有颜色,快速在线编码
LOW_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR 分辨率1cm3,无颜色,高效离线编码
LOW_RES_OFFLINE_COMPRESSION_WITH_COLOR 分辨率1cm3,有颜色,高效离线编码
MED_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR 分辨率5mm3,无颜色,高效离线编码
MED_RES_OFFLINE_COMPRESSION_WITH_COLOR 分辨率5mm3,有颜色,高效离线编码
HIGH_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR 分辨率5mm3,无颜色,高效离线编码
HIGH_RES_OFFLINE_COMPRESSION_WITH_COLOR 分辨率5mm3,有颜色,高效离线编码
MANUAL_CONFIGURATION 允许为高级参数化进行手工配置

如果选择 MANUAL_CONFIGURATION 则需要后面设置参数 。 例如下面的

      /*声明八叉树的压缩 变量  指针*/
    pcl::io::OctreePointCloudCompression<pcl::PointXYZ> * PointCloudEncoder;
        /*  进行 八叉树 的 压缩 配置  */
    PointCloudEncoder = new pcl::io::OctreePointCloudCompression<pcl::PointXYZ>(compressionProfile,showStatistics,0.001,0.01,true,100,true,8);//输入参数

进行 八叉树 的 压缩 配置
注意初始化的 参数 后面 加了六个,对应上面写的六个参数

        //压缩的字节流
    std::stringstream compressedData;

        /* 实现压缩 的  函数   第一个参数要求时只能指针,  .makeShared()即将cloud转成了 ptr */
    PointCloudEncoder->encodePointCloud(cloud.makeShared(),compressedData);

调用实现压缩的函数 。第一个参数是 要压缩的点云 第二个参数是 压缩的字节流

       //声明 解压 缩 后的 点云 指针
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudOut(new pcl::PointCloud<pcl::PointXYZ>());
    /* 实现 解压缩 的 地方 第一个参数字节流 第二个参数 点云指针*/
    PointCloudEncoder->decodePointCloud(compressedData,cloudOut);

解压缩点云 的部分


    //打印解压缩后的点云坐标
    std::cout<<"after"<<std::endl;
    for(size_t i;i<cloudOut->points.size();++i)
    { 
        
        std::cout<<"x="<<cloudOut->points[i].x<<"\t"<<"y="<<cloudOut->points[i].y<<"\t"<<"z="<<cloudOut->points[i].z<<std::endl;
    }

打印解压后的点云数据

Result

在这里插入图片描述
可以看到 前后 的 点云 的顺序变了

压缩 pcl::PointXYZRGB 类型数据

之前压缩的是 XYZ类型的数据 。 XYZI类型的数据 会报 encodePointCloud 函数调用错误。
可以 压缩 XYZRGB 的数据

生成XYZRGB的数据

这次构建多个点云数据,通过 代码 生成

    pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>());;

     uint8_t r(255), g(15), b(15);
  for (float z(-1.0); z <= 1.0; z += 0.1)
  {
    for (float angle(0.0); angle <= 360.0; angle += 60.0)
    {
      pcl::PointXYZ basic_point;
      basic_point.x = 0.5 * cosf (float(angle/180*M_PI));
      basic_point.y = sinf (float(angle/180*M_PI));
      basic_point.z = z;

      pcl::PointXYZRGB point;
      point.x = basic_point.x;
      point.y = basic_point.y;
      point.z = basic_point.z;
      uint32_t rgb = (static_cast<uint32_t>(r) << 16 |
              static_cast<uint32_t>(g) << 8 | static_cast<uint32_t>(b));
      point.rgb = *reinterpret_cast<float*>(&rgb);
      point_cloud_ptr->points.push_back (point);
    }
    if (z < 0.0)
    {
      r -= 12;
      g += 12;
    }
    else
    {
      g -= 12;
      b += 12;
    }
  }
  point_cloud_ptr->width = (int) point_cloud_ptr->points.size ();
  point_cloud_ptr->height = 1;   
   
   pcl::io::savePCDFile("creat_xyzrgb.pcd",*point_cloud_ptr);

自动生成点云。 保存成pcd文件。 点云类型为 pcl::PointXYZRGB

生成pcd文件后可以在终端 通过 pcl_viewer 功能 查看点云

在这里插入图片描述
可以看到 6个竖线 ,z逐渐升高。 主要就是上面 for 条件的代码。

压缩和解压

这部分和上一节基本一致 。注意 点云类型一致就可以了

      /* 设置压缩 和解压 时 的结果信息是否打印显示出来  */
    bool showStatistics = true ;
    //bool showStatistics = false;

      /* 压缩选项  可以参考 usr/include/pcl/compression/compression_profiles.h   */    
    pcl::io::compression_Profiles_e compressionProfile = pcl::io::MANUAL_CONFIGURATION;//设定为允许为高级参数化进行手工配置 


      /*声明八叉树的压缩 变量  指针*/
    pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB> * PointCloudEncoder;
        /*  进行 八叉树 的 压缩 配置  */
    PointCloudEncoder = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB>(compressionProfile,showStatistics,0.001,0.01,true,100,true,8);//输入参数

        //压缩的字节流
    std::stringstream compressedData;

        /* 实现压缩 的  函数   第一个参数要求时只能指针,  .makeShared()即将cloud转成了 ptr */
    PointCloudEncoder->encodePointCloud(cloud.makeShared(),compressedData);
  
       //声明 解压 缩 后的 点云 指针
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudOut(new pcl::PointCloud<pcl::PointXYZRGB>());

    /* 实现 解压缩 的 地方 第一个参数字节流 第二个参数 点云指针*/
    PointCloudEncoder->decodePointCloud(compressedData,cloudOut);

Result

通过

viewer.showCloud(cloudOut);

查看解压后的点云
在这里插入图片描述
和压缩前是一致的。

相关文章
|
编解码 算法 数据处理
基于八叉树的空间划分及搜索操作
基于八叉树的空间划分及搜索操作
基于八叉树的空间划分及搜索操作
|
算法 数据处理
点云地面点滤波(Progressive Morphological Filter)算法介绍(PCL库)
点云地面点滤波(Progressive Morphological Filter)算法介绍(PCL库)
1733 0
点云地面点滤波(Progressive Morphological Filter)算法介绍(PCL库)
|
存储 传感器 自动驾驶
几种常见的点云格式数据解析与在线预览
3D模型在线转换网站支持pcd、pts、xyz、las、laz、asc、ply等点云格式文件在线预览,同时支持将点云格式在线转换为ply、xyz等模型格式。
5819 1
|
机器学习/深度学习 存储 编解码
Open3d系列 | 3. Open3d实现点云上采样、点云聚类、点云分割以及点云重建
Open3d系列 | 3. Open3d实现点云上采样、点云聚类、点云分割以及点云重建
13660 1
Open3d系列 | 3. Open3d实现点云上采样、点云聚类、点云分割以及点云重建
|
3月前
|
人工智能 搜索推荐 API
AI-Compass DeepSearch深度搜索生态:集成阿里ZeroSearch、字节DeerFlow、MindSearch等前沿平台,实现超越传统关键词匹配的智能信息检索革命
AI-Compass DeepSearch深度搜索生态:集成阿里ZeroSearch、字节DeerFlow、MindSearch等前沿平台,实现超越传统关键词匹配的智能信息检索革命
AI-Compass DeepSearch深度搜索生态:集成阿里ZeroSearch、字节DeerFlow、MindSearch等前沿平台,实现超越传统关键词匹配的智能信息检索革命
|
2月前
|
机器学习/深度学习 存储 人工智能
深度解析大模型压缩技术:搞懂深度学习中的减枝、量化、知识蒸馏
本文系统解析深度学习模型压缩三大核心技术:剪枝、量化与知识蒸馏,详解如何实现模型缩小16倍、推理加速4倍。涵盖技术原理、工程实践与组合策略,助力AI模型高效部署至边缘设备。
441 0
|
存储 算法 索引
Draco使用笔记(1)——图形解压缩
Draco使用笔记(1)——图形解压缩
283 0
|
移动开发 Java API
大疆无人机对接
本文介绍了大疆无人机对接第三方云平台的方案,包括设备对接和CloudAPI对接两种方式,重点讨论了CloudAPI对接。CloudAPI对接方案通过DJI Pilot 2或大疆机场将无人机与第三方云平台连接,实现低门槛接入,无需重复开发APP。方案优势在于让开发者更专注于业务开发,而非无人机功能适配。文章详细阐述了对接流程,包括环境准备、申请APPKey、对接流程、直播功能及获取无人机实时数据等内容,并提供了丰富的接口说明和技术支持资源。
6538 4
大疆无人机对接
|
8月前
|
存储 网络协议 Linux
【Linux】进程IO|系统调用|open|write|文件描述符fd|封装|理解一切皆文件
本文详细介绍了Linux中的进程IO与系统调用,包括 `open`、`write`、`read`和 `close`函数及其用法,解释了文件描述符(fd)的概念,并深入探讨了Linux中的“一切皆文件”思想。这种设计极大地简化了系统编程,使得处理不同类型的IO设备变得更加一致和简单。通过本文的学习,您应该能够更好地理解和应用Linux中的进程IO操作,提高系统编程的效率和能力。
315 34