PCL 点云压缩(由八叉树实现)(Common_Compression)

注意:点云压缩时,若点云精度(分辨率)设置错误,将有一定的精度损失。因此注意点云分辨率的正确设置。

可压缩无序点云和有序点云。

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.结果展示

压缩信息打印结果:

压缩和解压缩结果(左为压缩前,右为压缩后再解压缩):

  • 23
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值