PCL教程指南-Point Cloud Compression(八叉树压缩点云数据)
- 官方原文档
- 针对点云数据量问题,应用八叉树数据结构,进行编码压缩。
- 对原文档代码进行解读,并详细介绍压缩参数和意义,及其他扩展内容
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/io/openni_grabber.h>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/compression/octree_pointcloud_compression.h>
#include <stdio.h>
#include <sstream>
#include <stdlib.h>
#ifdef WIN32
# define sleep(x) Sleep((x)*1000)
#endif
class SimpleOpenNIViewer
{
public:
//构造函数,C++独特语法糖,直接赋值到viewer
SimpleOpenNIViewer () :
viewer (" Point Cloud Compression Example")
{
}
//传入常数指针(常数指针的好处请见本博客内《C++与Java区别》)
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);
}
}
void
run ()
{
bool showStatistics = true;
// 完整配置对象在: /io/include/pcl/compression/compression_profiles.h
//枚举类型,里面包括压缩配置(分辨率,在/离线,颜色信息)
pcl::io::compression_Profiles_e compressionProfile = pcl::io::MED_RES_ONLINE_COMPRESSION_WITH_COLOR;
// 实例化编码与解码对象,并赋值配置,showStatistics为显示压缩统计信息
PointCloudEncoder = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA> (compressionProfile, showStatistics);
PointCloudDecoder = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA> ();
// OpenNi设备捕获接口
pcl::Grabber* interface = new pcl::OpenNIGrabber ();
// 定义回调函数,用于设备回调
std::function<void(const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f =
[this] (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr& cloud) { cloud_cb_ (cloud); };
//连接所需信号的回调函数。在这种情况下,它是一个带有颜色值的点云
boost::signals2::connection c = interface->registerCallback (f);
// 开始接收点云
interface->start ();
while (!viewer.wasStopped ())
{
sleep (1);
}
interface->stop ();
// 释放内存
delete (PointCloudEncoder);
delete (PointCloudDecoder);
}
//全局对象
pcl::visualization::CloudViewer viewer;
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA>* PointCloudEncoder;
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGBA>* PointCloudDecoder;
};
int
main (int argc, char **argv)
{
SimpleOpenNIViewer v;
v.run ();
return (0);
}
代码解释与扩展
1.openni
- openni是一种多媒体与平台直接的标准传输API接口,用于将硬件数据导入到计算机中。
2.压缩编码类相关解读
- pcl::io::compression_Profiles_e 是压缩配置项的一个枚举类型包括以下部分:
LOW_RES_ONLINE_COMPRESSION_WITHOUT_COLOR
LOW_RES_ONLINE_COMPRESSION_WITH_COLOR
MED_RES_ONLINE_COMPRESSION_WITHOUT_COLOR
MED_RES_ONLINE_COMPRESSION_WITH_COLOR
HIGH_RES_ONLINE_COMPRESSION_WITHOUT_COLOR
HIGH_RES_ONLINE_COMPRESSION_WITH_COLOR
LOW_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR
LOW_RES_OFFLINE_COMPRESSION_WITH_COLOR
MED_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR
MED_RES_OFFLINE_COMPRESSION_WITH_COLOR
HIGH_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR
HIGH_RES_OFFLINE_COMPRESSION_WITH_COLOR
COMPRESSION_PROFILE_COUNT
MANUAL_CONFIGURATION
此配置作用是封装了压缩编码类的所有参数,提供预置参数值,列举出其中源码部分:
// PROFILE: LOW_RES_ONLINE_COMPRESSION_WITHOUT_COLOR
0.01, /* pointResolution = */
0.01, /* octreeResolution = */
true, /* doVoxelGridDownDownSampling = */
50, /* iFrameRate = */
4, /* colorBitResolution = */
false /* doColorEncoding = */
// PROFILE: MED_RES_ONLINE_COMPRESSION_WITH_COLOR
0.005, /* pointResolution = */
0.01, /* octreeResolution = */
false, /* doVoxelGridDownDownSampling = */
40, /* iFrameRate = */
5, /* colorBitResolution = */
true /* doColorEncoding = */
- 压缩编码类
pcl::io::OctreePointCloudCompression
构造函数参数含义:
pcl::io::OctreePointCloudCompression< PointT, LeafT, BranchT, OctreeT >::OctreePointCloudCompression (
compression_Profiles_e compressionProfile_arg = MED_RES_ONLINE_COMPRESSION_WITH_COLOR,//定义压缩配置文件
bool showStatistics_arg = false,//获取压缩统计信息
const double pointResolution_arg = 0.001,//点坐标精度
const double octreeResolution_arg = 0.01,//最低八叉树级别的八叉树分辨率
bool doVoxelGridDownDownSampling_arg = false,//是否进行体素网格降采样
const unsigned int iFrameRate_arg = 30,//编码率
bool doColorEncoding_arg = true,//颜色编码
const unsigned char colorBitResolution_arg = 6 //颜色位分辨率
)
与上一节对比可以看到pcl::io::compression_Profiles_e
其实就是直接输入预置参数,而用户也可以自定义
- 编码原理
- range coder based on Dmitry Subbotin’s carry-less implementation (http://www.compression.ru/ds/)
3.回调函数问题
- 解释其中代码含义
std::function<void(const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)> f =
[this] (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr& cloud) { cloud_cb_ (cloud); };
std::function<void(const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr&)>
是函数模板用法,用于创建一个函数对象,void即返回值(此处为空),(const pcl::PointCloudpcl::PointXYZRGBA::ConstPtr&)即输入参数(此处为一个常数指针)[this] (const pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr& cloud) { cloud_cb_ (cloud); }
此处则为C++的lambda匿名函数,形式为[captures] (params) -> ret {Statments;} ,其中[this]即截取当前类中的this指针,即函数内部可以使用this中内容。此处匿名函数即调用了用户定义的压缩方法。