• 在PCL中如何实现点云压缩(1)


    点云由庞大的数据集组成,这些数据集通过距离、颜色、法线等附加信息来描述空间三维点。此外,点云能以非常高的速率被创建出来,因此需要占用相当大的存储资源,一旦点云需要存储或者通过速率受限制的通信信道进行传输,提供针对这种数据的压缩方法就变得十分有用。PCL库提供了点云压缩功能,它允许编码压缩所有类型的点云,包括“无序”点云,它具有无参考点和变化的点尺寸、分辨率、分布密度和点顺序等结构特征。而且,底层的octree数据结构允许从几个输入源高效地合并点云数据。

    1 点云压缩示意图

    下面,我们解释单个点云和点云数据流是如何高效压缩的,在给出的例子中,我们用PCL点云压缩技术来压缩用OpenNIGrabber抓取到的点云。

     

    代码:

     

    首先,在PCL(Point Cloud Learning)中国协助发行的书提供光盘的第6章例1文件夹中,打开名为point_cloud_compression.cpp的代码文件。

     

    解释说明

     

    下面详细解析打开的源代码。从主函数开始,首先创建一个新的SimpleOpenNIViewer实例并调用它的run()方法。

    int
    main(int argc,char **argv)
    {
    SimpleOpenNIViewer v;
    v.run();
    return(0);
    }

    run()函数中,创建PointCloudCompression类的对象来编码和解码,这些对象把压缩配置文件作为配置压缩算法的参数,所提供的压缩配置文件为OpenNI兼容设备采集到的点云预先确定的通用参数集。本例中,使用MED_RES_ONLINE_COMPRESSION_WITH_COLOR配置参数集,它应用5立方毫米的编码精度并且允许彩色纹理成分编码,并进一步优化,用于快速在线压缩。压缩配置文件的完整列表及其配制方法可以在文件“/io/include/pcl/compression/compression_profiles.h”中找到。在PointCloudCompression构造函数中使用MANUAL_CONFIGURATION属性就可以手动设置压缩算法全部参数。

    bool showStatistics=true;                       //设置在标准设备上输出打印出压缩结果信息
    // 压缩选项详见 /io/include/pcl/compression/compression_profiles.h
    pcl::octree::compression_Profiles_e compressionProfile=pcl::octree::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;
    // 初始化压缩与解压缩对象,其中压缩对象需要设定压缩参数选项,解压缩按照数据源自行判断
    PointCloudEncoder=new pcl::octree::PointCloudCompression<pcl::PointXYZRGBA> (compressionProfile, showStatistics);
    PointCloudDecoder=new pcl::octree::PointCloudCompression<pcl::PointXYZRGBA> ();
    

    下面的代码为OpenNI兼容设备实例化一个新的采集器,并且启动循环回调接口,每从设备获取一帧数据,就调用回调函数一次,这里的回调函数实现数据压缩和可视化解压缩结果。

    //创建从 OpenNI获取点云的抓取对象
    pcl::Grabber* interface =new pcl::OpenNIGrabber ();
    boost::function<void(constpcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f = boost::bind (&SimpleOpenNIViewer::cloud_cb_, this, _1);//建立回调函数
    // 建立回调函数与回调信号之间绑定
    boost::signals2::connection c = interface->registerCallback (f);
    // 开始接收点云数据流
    interface->start ();
    while (!viewer.wasStopped ())
        {
    sleep (1);
        }
    interface->stop ();
    

    OpenNIGrabber采集循环执行的回调函数cloud_cb_中,我们首先把获取到的点云压缩到stringstream缓冲区,下一步是解压缩,它对压缩了的二进制数据进行解码,存储在新的点云对象中,解码了的点云被发送到点云可视化对象中进行实时可视化。

    void
    cloud_cb_ (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr &cloud)
      {
    if (!viewer.wasStopped ())
        {
    std::stringstream compressedData;// 存储压缩点云的字节流对象
    pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloudOut // 存储输出点云
    (new pcl::PointCloud<pcl::PointXYZRGBA> ());
    PointCloudEncoder->encodePointCloud (cloud, compressedData);// 压缩点云
    PointCloudDecoder->decodePointCloud (compressedData, cloudOut);// 解压缩点云
    viewer.showCloud (cloudOut);//可视化解压缩点云
        }
      }
    //在压缩与解压缩过程中,因为设置compressedData为true所以在标准输出上打印出压缩率帧数等信息

    编译并运行该程序

    利用光盘提供的CMakeLists.txt文件,在cmake中建立工程文件,并生成相应的可执行文件,生成执行文件后,就可以运行了,在cmd中键入命令:

    ...>point_cloud_compression.exe

    可以看到如图2所示结果,左边为实时可视化带RGB纹理信息的点云结果,用户缩放可视化结果可以看到经过压缩后点云进行了重采样,纹理信息有所丢失,但数据量有所减小,在实际应用当中需折中取舍。右边则为实时压缩信息输出,可以看出压缩的帧数、点数、压缩率等信息。

    2 点云压缩运行结果

     

     

  • 相关阅读:
    POJ 1016 不断压缩字符串判断三种结果
    递归的运行机制简单理解
    模拟链表
    输入两个字符串,不用系统提供的函数strcat,自定义函数将两个字符串连接起来。
    信号量多线程同步
    windows 多线程同步技术
    qsort和sort的区别(转)
    大数阶乘位数
    字符串数组qsort排序
    Safecracker
  • 原文地址:https://www.cnblogs.com/flyinggod/p/8598500.html
Copyright © 2020-2023  润新知