如何有效地处理三维体素

How to handle 3D voxels efficiently?

本文关键字:三维 处理 有效地      更新时间:2023-10-16

我有一个包含数百万个点的3D点云。我想把这些点存储在三维体素空间中。对于总共3000*4000*1500个体素,沿坐标轴的体素数量超过3000(x)、4000(y)、1500(z)。我需要存储在体素中;最大点数、最小高度、最大高度和centorid。但是,90%的体素是空的。所以存储这个需要大量的内存。实际上,我想稍后搜索每个体素的26个相邻体素。那么,在体素空间中存储这些数据并有效访问这些数据的最佳方式是什么?

就性能而言,创建多维数组不是最佳解决方案。。。有什么提示吗?

这类数据的经典数据结构是kd树和八叉树。。

此外,您还应该了解CGAL中实现的空间搜索和排序数据结构。

如果真的"只有"数百万个点,那么90%以上的体素将为空。我会尝试一个从体素坐标到点的散列多映射(C++11中的std::unordered_multimap)。这给了你O(1)的查找,就像一个数组。虽然这会带来很多开销,但这可能是最好的折衷方案。

唯一需要的就是体素类中的相等比较和模板专用化std::hash<voxel>。你不会以任何自动的方式实现"最大点数",但这真的有用吗?

一种方法是使用集合中的数据来支持实际数据。

举例说明:

struct t_voxel {
  size_t nPoints, minHeight, maxHeight, centorid;
};
struct t_voxel_id {
  uint16_t index;
};
// one dimension
class t_voxel_collection {
  // the actual voxel data needed for the indices represented by the collection of voxelId
  std::vector<t_voxel> d_voxel;
  // here, empty voxel is designated by t_voxel.index = 0
  // this collection is your primary array representation
  // these elements just refer to a unique or shared index in this->d_voxel
  std::vector<t_voxel_id> d_voxelId;
public:
  // >> the interface to access and set, which abstracts the backing collection.
  // and prohibits the client from accessing the actual data.
  t_voxel get(const size_t& idx) const {
    return this->d_voxel[this->d_voxelId[idx].index];
  }
  // ...
};

通过这种方式,您可以实现内存消耗的大幅下降(假设您看到了这一趋势)。

这不是一个完整的答案,但在这种情况下可能会有所帮助。

根据您的使用情况,有几种方法可以进一步优化和共享此集合中的体素数据。

无论你做什么,即使你为你的稀疏网格找到了一个完美的内存布局,你都会变得一团糟——这仍然需要太多的内存。真正的问题是能够有效地将其存储在磁盘上,并智能地缓存感兴趣的区域。

谢天谢地,Field3D正是为此而开发的。