注意:点云压缩时,若点云精度(分辨率)设置错误,将有一定的精度损失。因此注意点云分辨率的正确设置。
可压缩无序点云和有序点云。
1.原理
点云带有大量的数据,不仅包括三维信息,还有额外的距离,颜色,法向量等等。此外,点云可以快速生成,这会占有大量的内存资源。一旦点云必须被存储或者用于通信传输,对于点云的压缩技术就显得十分重要了。PCL提供了点云压缩功能,它支持对各种类型点云的压缩,其中包括无序点云,此外,在八叉树结构下的数据支持高效地合并多个来自不同数据源的点云。
2.使用场景
对点云数据进行压缩,减少空间消耗。
3.注意事项
正确设置合适分辨率,防止精度丢失。
有序点云及无序点云均可用。
4.关键函数
(1)默认参数压缩对象
// 默认参数压缩对象
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB>* compression = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB>
(pcl::io::LOW_RES_ONLINE_COMPRESSION_WITH_COLOR);
1)参数:定义压缩配置文件
- LOW_RES_ONLINE_COMPRESSION_WITHOUT_COLOR:分辨率1立方厘米,压缩完之后无颜色,快速在线编码
- LOW_RES_ONLINE_COMPRESSION_WITH_COLOR:分辨率1立方厘米,压缩完之后有颜色,快速在线编码
- MED_RES_ONLINE_COMPRESSION_WITHOUT_COLOR:分辨率5立方毫米,压缩完之后无颜色,快速在线编码
- MED_RES_ONLINE_COMPRESSION_WITH_COLOR:分辨率5立方毫米,压缩完之后有颜色,快速在线编码
- HIGH_RES_ONLINE_COMPRESSION_WITHOUT_COLOR:分辨率1立方毫米,压缩完之后无颜色,快速在线编码
- HIGH_RES_ONLINE_COMPRESSION_WITH_COLOR:分辨率1立方毫米,压缩完之后有颜色,快速在线编
- LOW_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR:分辨率1立方厘米,压缩完之后无颜色,高效离线编码
- LOW_RES_OFFLINE_COMPRESSION_WITH_COLOR:分辨率1立方厘米,压缩完之后有颜色,高效离线编码
- MED_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR:分辨率5立方毫米,压缩完之后无颜色,高效离线编码
- MED_RES_OFFLINE_COMPRESSION_WITH_COLOR:分辨率5立方毫米,压缩完之后有颜色,高效离线编码
- HIGH_RES_OFFLINE_COMPRESSION_WITHOUT_COLOR:分辨率1立方毫米,压缩完之后无颜色,高效离线编码
- HIGH_RES_OFFLINE_COMPRESSION_WITH_COLOR:分辨率1立方毫米,压缩完之后有颜色,高效离线编码
(2)自定义参数压缩对象
// 自定义参数压缩对象
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB>* compression = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB> // 定义点云压缩对象
(
pcl::io::MANUAL_CONFIGURATION, // 定义自定义参数型压缩配置文件
true, // 是否打印压缩统计信息
0.001, // 点坐标的精度
0.01, // 最低八叉树级别的八叉树分辨率,即八叉树最低层级的体素块的边长
false, // 点云压缩前,是否进行体素网格过滤
100, // 点云压缩模式对点云进行差分编码压缩,用这种方法对新引入的点云和之前编码的点云之间的差分进行编码,以便获得最大压缩性能,iFrameRate_arg指定了一个速率,如果数据流中的帧速率低于这个速率则不进行差分编码压缩
true, // 是否对颜色编码进行压缩
8 // 每一个颜色编码所占的位数
);
1)源码中函数原型为:
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) :
- compressionProfile_arg:定义压缩配置文件
- showStatistics_arg:是否打印压缩统计信息
- pointResolution_arg:点的分辨率。即点的坐标可精确到的程度(精确到小数点后几位)【开启细节编码时生效】。该值设置不对,将造成精度丢失。
- octreeResolution_arg:八叉树最小体素块的边长。
- doVoxelGridDownDownSampling_arg:在压缩前,是否进行体素抽稀。
- iFrameRate_arg:是用来决定进行l帧编码的频率,如果此数值为30,则每隔30帧进行一次!帧编码,中间的帧则进行P帧编码。
- doColorEncoding_arg:是否进行颜色编码。
- colorBitResolution_arg:颜色的字节数。
5.代码
#include <iostream>
#include <pcl/point_cloud.h>
#include <pcl/io/pcd_io.h>
#include <pcl/compression/octree_pointcloud_compression.h> //点云压缩
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
int main()
{
/****************基于八叉树的点云压缩********************/
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>());
pcl::io::loadPCDFile("D:/code/csdn/data/bunny.pcd", *cloud); // 加载原始点云数据
std::stringstream compressedData; // 压缩之后的点云数据(字节流)
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloudOut(new pcl::PointCloud<pcl::PointXYZRGB>()); // 解压缩之后点云
// 基于八叉树的点云压缩
默认参数压缩对象
//pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB>* compression = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB> // 定义点云压缩对象
// (pcl::io::LOW_RES_ONLINE_COMPRESSION_WITH_COLOR);
// 自定义参数压缩对象
pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB>* compression = new pcl::io::OctreePointCloudCompression<pcl::PointXYZRGB> // 定义点云压缩对象
(
pcl::io::MANUAL_CONFIGURATION, // 定义压缩配置文件
true, // 是否打印压缩统计信息
0.0001, // 点坐标的精度
0.001, // 最低八叉树级别的八叉树分辨率,即八叉树最低层级的体素块的边长
false, // 点云压缩前,是否进行体素网格过滤
100, // 点云压缩模式对点云进行差分编码压缩,用这种方法对新引入的点云和之前编码的点云之间的差分进行编码,以便获得最大压缩性能,iFrameRate_arg指定了一个速率,如果数据流中的帧速率低于这个速率则不进行差分编码压缩
true, // 是否对颜色编码进行压缩
8 // 每一个颜色编码所占的位数
);
// 压缩点云
compression->encodePointCloud(cloud, compressedData); // 压缩点云
compressedData.write("D:/code/csdn/data/compressed.bin", sizeof(compressedData)); // 将压缩点云的文件结果写到bin文件中
// 解压缩点云
std::ifstream compressedBin("D:/code/csdn/data/compressed.bin", ios::binary); // 读取bin文件
compression->decodePointCloud(compressedData, cloudOut); // 解压缩点云
/****************展示********************/
// 压缩前
boost::shared_ptr<pcl::visualization::PCLVisualizer> view0(new pcl::visualization::PCLVisualizer("raw"));
view0->addPointCloud<pcl::PointXYZRGB>(cloud, "raw cloud");
view0->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "raw cloud");
// 压缩后
boost::shared_ptr<pcl::visualization::PCLVisualizer> view1(new pcl::visualization::PCLVisualizer("result"));
view1->addPointCloud<pcl::PointXYZRGB>(cloudOut, "result cloud");
view1->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "result cloud");
while (!view0->wasStopped() || !view1->wasStopped())
{
view0->spinOnce(100);
view1->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
6.结果展示
压缩信息打印结果:
压缩和解压缩结果(左为压缩前,右为压缩后再解压缩):