发明内容
针对现有技术存在的不足,本发明提出一种海量点云数据多视图渲染方法,以解决现有技术中存在的对于海量点云数据进行多视图渲染时,效率较低的技术问题。
本发明采用的技术方案是,一种海量点云数据多视图渲染方法,包括以下步骤:
对原始点云数据进行多尺度自适应分块和八叉树索引构建;
根据视口范围对各个视图分别筛选需要加载的八叉树,并确定八叉树加载的层次细节模型层级;
层次细节模型加载线程加载层次细节模型数据,得到可供渲染的点云模型,将可供渲染的点云模型放入模型共享队列;
各个视图根据自身需要加载的八叉树,从模型共享队列中查找视图范围内的可供渲染的点云模型,合并可供渲染的点云模型到场景,同时移除过期的可供渲染的点云模型;
删除过期的可供渲染的点云模型。
进一步的,对原始点云数据进行多尺度自适应分块和八叉树索引构建,包括:
根据原始点云数据计算包围盒;
根据包围盒对原始点云数据进行多尺度自适应分块,得到分块点云;
对分块点云构建八叉树索引。
进一步的,包围盒根据原始点云数据的坐标最大值和坐标最小值进行计算。
进一步的,根据包围盒对原始点云数据进行多尺度自适应分块,包括:
将具有相同最小角点坐标的点云作为同一个分块;若同一个分块中的点云数量小于或等于预设的最大点云数量,停止分块;若同一个分块中的点云数量大于预设的最大点云数量,则按照最大分块尺寸的一半将当前块继续划分为多个子块,直到所有子块中的点云数量都不超过预设的最大点云数量。
进一步的,八叉树索引构建,包括:
设定八叉树划分层级及八叉树节点中包含的最大点数;
以当前分块点云的几何中心点作为八叉树的根节点,沿着X,Y和Z三个方向对当前分块点云进行划分,获得八个子节点;
若某个子节点中点云数量小于所述最大点数,则停止划分;
反之,则以该子节点为根节点继续进行划分,划分结束的条件为总层级超过所述划分层级或者八叉树节点中包含的点数小于所述最大点数;
将所有的分块点云保存在叶子节点中。
进一步的,根据视口范围对各个视图分别筛选需要加载的八叉树,包括:
根据当前视图的投影矩阵及视点位置构建当前的视锥体;
求取视锥体外包围盒,并与八叉树包围盒进行初步的位置判断:
若八叉树包围盒与视锥体外包围盒不相交且八叉树包围盒在视锥体包围盒外部,则说明八叉树不在当前视野范围内;反之,则对视锥体与八叉树进行进一步的相交、包含判断;
通过设置标签来标记八叉树是否在视锥体内。
进一步的,八叉树索引、生成的层次细节模型数据存储在文件中;原始点云数据再次打开时,直接从文件读取八叉树索引及其对应的层次细节模型数据。
进一步的,合并可供渲染的点云模型到场景,包括:可供渲染的点云模型可被多个视图所共享,同一可供渲染的点云模型可以被合并到多个场景中。
进一步的,将当前活动视图作为主视图以较高帧率进行渲染,其他视图则以较低帧率进行渲染。
进一步的,删除过期的层次细节模型数据,包括:设置过期时间阈值ΔT2,若访问时间戳与当前时间的差值大于ΔT2,并且引用计数等于0,则将数据从共享队列中删除,释放空间;反之,则暂时不删除该数据。
由上述技术方案可知,本发明的有益技术效果如下:
1.使用基于八叉树层次结构叠加型层次细节模型的生成方法,避免了点云数据的重复存储,节约了存储空间。
2.多视图共享层次细节模型数据,避免了多视图点云渲染时同一数据的多次拷贝,减少了内存空间的占有,提高了点云数据多视图渲染效率。
具体实施方式
下面将结合附图对本发明技术方案的实施例进行详细的描述。以下实施例仅用于更加清楚地说明本发明的技术方案,因此只作为示例,而不能以此来限制本发明的保护范围。
需要注意的是,除非另有说明,本申请使用的技术术语或者科学术语应当为本发明所属领域技术人员所理解的通常意义。
实施例1
本实施例提供了一种海量点云数据多视图渲染方法,如图1所示,包括以下步骤:
S1、对原始点云数据进行多尺度自适应分块和八叉树索引构建
S1-1、根据原始点云数据计算包围盒
具体的,计算原始点云数据的坐标最大值(Xmax,Ymax,Zmax)和坐标最小值(Xmin,Ymin,Zmin)。Xmax和Xmin的计算方法为:
其中,n为点云的个数。按与计算Xmax和Xmin相同的方法,计算Ymax、Ymin、Zmax和Zmin的值,得到包围盒Box(Xmin,Ymin,Zmin,Xmax,Ymax,Zmax)。
S1-2、根据包围盒对原始点云数据进行多尺度自适应分块,得到多个分块点云
原始点云数据具有数据量大、密度分布不均的特点,对原始点云数据进行分块处理将提高点云数据的处理效率,降低计算机内存使用率。在实际的应用过程中,可根据划分块的尺寸及当前分块点数按照由粗到细的原则进行划分。
在具体的实施方式中,设定分块最大尺寸S,分块中最大点云数量N;设定偏移原点为p0(x0,y0,z0),优选的,通常取x0=Xmin,y0=Ymin,z0=Zmin,即包围盒在X、Y、Z方向上的坐标最小值。首先,以初始尺寸S对原始点云数据进行分块,任意点云pi(xi,yi,zi)对应分块最小角点坐标pci(xci,yci,zci)计算公式为:
其中floor(x)含义是向下取整。
将具有相同最小角点坐标的点云作为同一个分块Block。若Block中的点云数量小于或等于N,则无需对该分块再进行划分;若Block中的点云数量大于N,则按照S/2的分块尺寸将当前块继续划分为多个子块subBlock,直到所有subBlock中的点云数量都不超过N。
上述多尺度自适应的分块策略,可以避免因点云数据密度不均而引起的大量空点云块的存在。最大块尺寸及块点数可根据实际情况而定,本发明实施例对此不作具体限定。
S1-3、对分块点云构建八叉树索引
设定八叉树划分层级Level及八叉树节点中包含的最大点数Count,对分块点云建立八叉树索引。具体的,以当前分块点云的几何中心点作为八叉树的根节点,沿着X,Y和Z三个方向对当前分块点云进行划分,获得八个子节点;若某个子节点中点云数量小于Count,则停止划分;反之,则以该子节点为根节点继续进行划分,划分结束的条件为总层级超过Level或者八叉树节点中包含的点数小于Count。将所有的分块点云保存在叶子节点中。
在构建的八叉树索引中包括了叶子节点和非叶子节点,其中未被划分的节点称为叶子节点,被划分的节点称为非叶子节点。
S2、根据视口范围对各个视图分别筛选需要加载的八叉树,并确定八叉树加载的层次细节模型层级
S2-1、八叉树筛选
八叉树筛选的过程是判断八叉树是否在当前视图的视锥体中的过程。对于点云数据的多视图渲染而言,及时释放未在视锥体内的点云数据是提高渲染效率的关键。
八叉树筛选的步骤为:根据当前视图的投影矩阵及视点位置构建当前的视锥体;求取视锥体外包围盒,并与八叉树包围盒进行初步的位置判断,若八叉树包围盒与视锥体外包围盒不相交且八叉树包围盒在视锥体包围盒外部,则说明八叉树不在当前视野范围内;反之,则对视锥体与八叉树进行进一步的相交、包含判断。需要加载的八叉树是位于视锥体内的,以isInCamera标签来标记八叉树是否在视锥体内,在视锥体内的八叉树的isInCamera标签标记为true,否则标记为false。
本实施例中,为了提高多视图点云数据渲染效率,每个视图开启一个单独的线程,用于八叉树的筛选。
S2-2、确定八叉树应加载的层次细节模型层级
为了进一步提高加载效率,基于八叉树索引结构,在本实施例中设计一种叠加型的点云层次细节模型(LOD模型)。示例性的,以八叉树层数Level作为LOD的层数,从叶节点开始,逐层以一定的采样率进行点云采样,直到达到八叉树根节点,最终八叉树的各节点都包括了一定数量的点云数据,且各个节点的点云数量之和为当前块的点云数量。将八叉树每一层的点云作为一个单独的LOD模型,如此便得到Level层LOD模型。每一层的采样率可根据实际情况而定,不做具体限定。
优选的,在具体的实施方式中,点云块的八叉树索引结构及生成的LOD数据将存储在文件中,原始点云数据再次打开时,可直接从该文件读取八叉树索引结构及其对应的LOD数据,避免八叉树索引结构及LOD的重新生成,能够实现原始点云数据的秒开。
对于isInCamera标签为true的八叉树,根据当前视点到八叉树的距离,确定当前八叉树应加载到的LOD层级,按照预设的加载范围逐层向LOD加载线程发送LOD数据加载请求LodRequest。
例如,当前八叉树层级为6层,设顶层为第一层,预设的视点到八叉树距离与加载层级的对应关系如下:
视点到八叉树的距离(单位:米) |
加载的层级 |
[1000,∞) |
1 |
[800,1000) |
1、2 |
[600,800) |
1、2、3 |
[400,600) |
1、2、3、4 |
[200,400) |
1、2、3、4、5 |
[0,200) |
1、2、3、4、5、6 |
若当前视点到八叉树距离为300m,则应加载的层级为1、2、3、4、5,依次判断该层级的LOD数据是否已经加载,若没有加载,则向LOD加载线程依次发送LOD数据加载请求。
在具体的实施方式中,LodRequest结构定义为(datasetID,octreeID,level,distance,timestampRequest,refCount,loadedModel,visitorTime),其中,datasetID为点云数据的编号,用于区分多个点云文件;octreeID表示八叉树的编号,level表示LOD的层级,distance表示该LOD层级中心到视图视点的距离,timestampRequest表示发送该条请求时的时间戳,loadedModel表示LOD数据加载之后可供渲染的点云模型;refCount为引用计数,表示loadedModel被视图引用的次数;visitorTime表示loadedModel被合并到视图中后,场景遍历loadedModel时的时间戳。
S3、层次细节模型加载线程加载层次细节模型数据,得到可供渲染的点云模型,将可供渲染的点云模型放入模型共享队列
LOD加载线程从LOD数据请求队列LodRequestList中按照优先级获取一条记录,进行LOD数据的加载,加载完成得到的loadedModel数据存入模型共享队列LODShareList。
LOD数据请求的优先级可根据请求的时间timestampRequest或者当前视点到Lod层级的距离distance来确定,为了避免LOD加载线程加载已经过期的LOD数据,设置过期时间阈值ΔT1,当LOD请求的时间戳timestampRequest与当前系统的时间currentTime差值大于过期阈值ΔT1时,认为该请求已过期,从LOD数据请求队列LodRequestList中直接删除该请求;反之,则加载LOD数据,将加载成功的点云数据存储在loadedModel可供渲染的点云模型中。过期时间的判断表示如下:
按上述方式加载的层次细节模型数据有多个,得到的可供渲染的点云模型有多个,将可供渲染的点云模型放入模型共享队列中,供各个视图在渲染时直接调用。
S4、各个视图根据自身需要加载的八叉树,从模型共享队列中查找视图范围内的可供渲染的点云模型,合并可供渲染的点云模型到场景,同时移除过期的可供渲染的点云模型
传统的点云数据多视图渲染中,每个视图对点云数据进行单独的加载,同一点云数据可能在内存中被进行了多次拷贝,造成了很大的数据冗余,占用了较大的内存存储空间。
在本实施例中,每个视图根据步骤S2中筛选结果得出自身需要加载的八叉树,然后从模型共享队列LODShareList中查找该视图范围内的loadedModel数据,并合并loadedModel数据到该视图的场景中。合并时即将loadedModel数据作为子节点添加到原场景的根节点下。LODShareList中的loadedModel可被多个视图所共享,同一loadedModel数据可以被合并到多个场景中,减少了LOD数据的内存拷贝,节约了内存空间。
具体的,使用引用计数refCount表示loadedModel数据共享的次数,当loadedModel数据加载到某个视图中时,refCount加1,当loadedModel数据从某个视图中删除时,refCount减1,当refCount=0时,表示该loadedModel数据没有被任何视图共享,此时loadedModel数据才被允许从共享队列LODShareList中删除。
使用visitorTime表示loadedModel数据的访问时间戳,当loadedModel数据被加载到某一视图中后,视图在进行帧渲染时,对加载的loadedModel数据进行遍历,使用visitorTime记录遍历该loadedModel数据的时间。若该loadedModel数据被加载在某一场景中,则visitorTime会随着帧渲染不断的更新,若该loadedModel数据没有被加载到任何场景,则visitorTime记录了该loadedModel数据最后一次遍历的时间。
此外,多视图渲染时,各个视图都以较高的帧率进行渲染会影响渲染的效率。本实施例中,优选的,将当前活动视图作为主视图以较高帧率进行渲染,其他视图则以较低帧率进行渲染,可以进一步提高多视图渲染效率。较高帧率及较低帧率可根据实际情况设置,本实施例不做具体限定。
视图中若有多个点云文件存在时,可按照文件进行场景模型的组织,示例性的,每个视图有根节点root,root节点下可挂接文件节点DS_ROOT,DS_ROOT下再挂接文件对应的点云LOD模型DS_LOD,多视图共享节点的组织方式如图2所示。
S5、删除过期的可供渲染的点云模型
及时的将过期的loadedModel数据从共享队列LODShareList中删除,是提高点云数据多视图渲染效率的关键。
在本实施例中,以visitorTime和refCount来判断loadedModel数据是否被允许从共享队列LODShareList中删除,具体为:设置过期时间阈值ΔT2,若visitorTime与当前时间currentTime的差值大于ΔT2,并且refCount=0,则将loadedModel数据从共享队列中删除,释放空间;反之,则暂时不删除该loadedModel数据。具体表示为:
本实施例中,设置过期时间阈值ΔT2的目的是为了防止loadedModel数据被立即释放,实际应用过程中,根据用户的操作习惯,在loadedModel数据被视图移除后,短时间内可能又需要被立即加载,此时只需要从共享节点列表LODShareList中再次合并该loadedModel数据到视图中即可,而不需要数据的重新加载。过期时间ΔT2的值可根据实际情况设定,本实施例不做具体限定。图3为多视图渲染的多线程加载流程;图4为某一海量点云数据的多视图可视化效果示意图。
通过采用本实施例的技术方案,使用基于八叉树层次结构叠加型层次细节模型的生成方法,避免了点云数据的重复存储,节约了存储空间;多视图共享层次细节模型数据,避免了多视图点云渲染时同一数据的多次拷贝,减少了内存空间的占有,提高了点云数据多视图渲染效率。
最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述各实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分或者全部技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的范围,其均应涵盖在本发明的权利要求和说明书的范围当中。