1. 背景
在大数据点云的存储中,常常要进行空间分区,一般的策略是构建四叉树或者八叉树。在构建树的过程中,一个不可避免的点就是点云的快速抽稀。
不同层级之间,下一层的数据永远比上一层的数据更加精细,即:上一层数据是从下一层通过某种抽稀算法筛选出来的。常规意义上的抽稀算法,是在内存中进行筛选,但由于大数据点云的特殊性(无法全部读进内存),这些抽稀算法均不满足要求,存在一下问题:
- 无法全部读进内存,因此抽稀之后不同分块(分块策略是前提)的效果不一;
- 抽稀效率比较低,需要预先将数据读进内存,再进行分层筛选;
某项目中,需要将*.las转换成自定义格式,其转换速率要求很高。而由于las文件在使用LASTools读写时,只能逐点读取,因此需要一种既能解决上述问题,又能保证效率的抽稀算法。
本文介绍的抽稀算法,原理上是利用伪随机数的均匀分布来实现,但同时能兼顾效率和效果。其局限性如下:
- 随机数表是存储在内存中,因此数据量过大的情况下,内存占用可能会很高;
- 抽稀效率随C++标准库的随机数生成算法影响;
- 数据量很小的时候,存在某层数据为空的可能;
2. 原理
基于以下出发点:
- 每读一个点,能立即得到该点所属层级——las的逐点读限制;
- las文件只需读一次,就能得到抽稀结果——O(n),n为点数;
- 保证抽稀结果均匀——加入随机数;
对于第一点,将las文件中的顶点数据,类比成一个存储了顶点的数组:
| v | v | v | v | v | v | v | v | v | v | v | v | v | v | v | v | … |
|---|
LASTools的读操作器每一次读取的时候,都会将游标移到下一个点。对每一个点来说,本身并没有层级信息,因此需要人为地赋予其层级。
计算层级可以类比分类游戏:一堆小球从入口进入,中间穿插阻碍棒,最终落到容器内:

而将红色小球理解为点云的顶点,将下面的容器理解为结果,则中间的蓝色小球是我们的抽稀算法。
核心原理就是,每次获取一个随机数,这个随机数的值就是当前点所在的层级。而随机数的范围,就是按照n叉树的层级点数比例,计算出来的一个值。具体实现见后文。
3. 实现
3.1 定义Utils类
class Utils
{
private:
Utils(int lvl);
~Utils();
public:
static Utils &instance();
int getLayer();
protected:
char *m_lv

文章介绍了针对大数据点云存储中的空间分区问题,提出了一种基于随机数的抽稀算法。由于点云数据量大,无法全部加载到内存,常规抽稀方法效率低。该算法利用伪随机数的均匀分布,根据LAS文件的逐点读取特性,实现了一次读取即可得到抽稀结果的高效方法。算法局限性包括内存占用和随机数生成效率的影响。
最低0.47元/天 解锁文章
775

被折叠的 条评论
为什么被折叠?



