背景
上一篇文章《当前端遇到自动驾驶》有详细介绍过自动驾驶点云标注的背景,就不再赘述了,这里只稍微再补充一点领域知识:
常见的点云标注任务有 动态帧(连续帧),静态帧(叠帧),2D&3D融合 等等。
不同的任务场景有不同的技术难点,我们今天针对动&静态帧标注这两个场景下的点云渲染和加载性能优化来展开。
挑战
挑战1: 数据量大
每个PCD[1]的点云数量高达几十万量级,而3D框体调整需要实时渲染,全量扫描点云极度消耗机器资源,产生交互卡顿,如何优化?
挑战2: 文件体积大
每个PCD文件包含大量数据,ASCII编码模式下单文件大小高达20多MB,在静态帧标注场景,单帧能达到几百MB,用户光加载个文件都要等很久,如何优化?
静态帧:将N个PCD数据叠加在同一个场景(scene)下进行处理,主要用于标注一些建筑物和路标等静止物体。
方法论
在进入实际问题解决之前,我们先引入几个思想模型(方法论):
分治
分治[2],字面意思就是“分而治之”,就是把复杂问题拆分成多个简单问题来处理,最后再合并处理结果。
这个思想在计算机领域极其常见,本身就是计算机诞生的原理性支点。
编码
编解码在计算机领域也是极其常见的,在不同场景下切换不同的编解码方式,可以在易用和高效之间灵活切换。
流式
从微观视角看没有绝对的流式,一切都是批处理,是离散的。但我们在顶层应用的开发时,从宏观视角看,就会出现流式现象,本质上就是粒度更小的批处理。
实战效果
先简单讲下基本思路,其实不管是解决什么问题,多大规模的问题,最本质的方法论都是普适的。比如解决规模问题,无非就是采用“分治”的策略嘛,分而治之,多大的问题都能被拆解为若干个相似的小问题,再逐一治理。
上面我们已经介绍了三种最常用的思想模型,接下来我们看看如何在遇到的两个挑战里进行实操。
挑战1
挑战1(数据量大)明显是个规模问题,既然是规模问题,就可以用分治思想解决。
我们先把整个点云所覆盖的XY平面,拆分为N个矩形单元,比如10 x 10一个单元,那如果整体覆盖面大小是1000 x 1000 的话,就会被分拆为10000个处理单元,每个单元都有自己的坐标边界(Xmin,Xmax,Ymin,Ymax),当我们绘制3D框体时候,可以先用哈希表找出该框体所占用的单元面积,做一个标记,等整体用户操作完成后,再统一渲染,并且只渲染被标记为“活动” 的处理单元即可。
这样下来,其实每次渲染只需要重新更新10 x 10范围内的点云,这个数量级基本上可以从十万级降低到百级(取决于处理单元的大小),处理速度也会快很多。
目前这个方案的代码尚未开发完成,暂时不放出来了,感兴趣的朋友也可以自己试着实现一版。
挑战2
挑战2(文件体积大)其实就是解决资源文件过大问题,在前端这里早就司空见惯了,无非就是下面几种方式:
- 压缩文件 —— 对应编解码模型
- 拆分文件 —— 对应分治模型
- 流式加载 —— 对应流式模型
编码压缩
先来说压缩,PCD文件有很多种编码格式,其中ASCII格式比较直观,我们可以直接读懂文件,明文看到该文件点位的信息,方便我们及时纠错,但是缺点就是太大了。
ASCII编码的PCD文件
所以我们将生产环境用的PCD文件,统一重新进行了二进制编码,采用binary方式写文件,这就极大的缩小了文件体积(压缩到原来的20%)。