C++ 如何有效地处理三维体素?

C++ 如何有效地处理三维体素?,c++,3d,computational-geometry,C++,3d,Computational Geometry,我有一个三维点云,有一百万个点。我想将这些点存储在三维体素空间中。坐标轴上的体轴数量超过3000(x)、4000(y)、1500(z),总共有3000*4000*1500个体素。我需要存储在体素中;最大点数、最小高度、最大高度和centorid。但是,90%的体素是空的。所以存储这个需要很多内存。实际上,我想在后面搜索每个体素的26个相邻体素。那么,在体素空间中存储这些数据并有效访问这些数据的最佳方法是什么 就性能而言,创建多维数组并不是最好的解决方案……请给出任何提示?如果它真的“只是”数百万

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

就性能而言,创建多维数组并不是最好的解决方案……请给出任何提示?

如果它真的“只是”数百万个点,那么超过90%的体素将为空。我会尝试从体素坐标到点的散列多重映射(C++11中的无序多重映射)。这将提供O(1)查找,就像数组一样。虽然它有很多开销,但它可能是最好的折衷方案


要实现这一点,唯一需要的是体素类中的相等比较,以及模板专门化
std::hash
。您不会以任何自动方式实现“最大点数”,但这真的有用吗?

这类数据的经典数据结构是和


另外,您一定要看看CGAL中实现的数据结构。

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

举例说明:

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];
  }
  // ...
};
struct\u体素{
尺寸点、最小高度、最大高度、百分位;
};
结构体素id{
uint16_t指数;
};
//一维
类t_体素集合{
//由体素ID集合表示的索引所需的实际体素数据
std::向量d_体素;
//这里,空体素由t_voxel.index=0指定
//此集合是您的主要数组表示形式
//这些元素仅引用此->d_体素中的唯一或共享索引
std::向量d_体素;
公众:
//>>访问和设置的接口,它抽象了备份集合。
//并禁止客户端访问实际数据。
体素获取(常量大小\u t&idx)常量{
返回this->d_体素[this->d_体素id[idx].index];
}
// ...
};
通过这种方式,您可以实现内存消耗的大幅下降(假设您看到了这一趋势)

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


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

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


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

在90%为空时,仍然有1.800.000.000个体素。那无论如何都不会飞。您可以沿一维存储体素的运行,但查找成本很高。@leftaroundabout,它可能是4D体素,也可能不是?@usr voxel=体积图片元素,体积按定义为3D体积未定义为3D。至少根据维基百科,当处理几何数据时,0D是空间中的任意点,可以驻留在任意维空间中;即使矢量2、矢量3等用作位置而非方向,其大小也是0D空间。换句话说,0D空间是空间中任意点的坐标。1D空间是两点(距离)之间的连接,可以是空间中的2D或3D向量,其中方向和/或大小被视为有效的重要信息。另一个词1D是到区域设置或两点之间的距离或测量范围……但是查找邻居的成本会很高。@usr:不太可能。正如我所说,对于任何一点,查找都是O(1)。邻居的速度并不比其他任何一点都快。他们有26个,这使得一个昂贵的O(1)。是的。。。但你不能到处做这些。在基于树的结构中,查找将包含一些O(ld n),对于数百万个点来说,这也是20多个点。你希望通过在树上彼此接近的查找来绕过这个问题,但这在数学上是不可能的,因为,这也意味着,位于相邻体素中的k-d树中的某些节点仍将被树中较高的平面隔开。别误会:我同意,在没有固定离散体素光栅的情况下,八叉树和k-d树是正确的选择,因为这样就需要按距离计算相邻点,这在哈希中是不可能的。但是一旦你有了一个光栅,从而有了一个离散的度量,就有可能使用散列,甚至更好。对于这个,什么是最好的数据结构,kd树还是八叉树?我们可以使用八叉树或…的体素数据结构吗。。。。很抱歉,我对这些数据结构没有清晰的认识。@user1286780在您最初的问题中,您只询问了体素数据结构,所以我不会将此作为单独的答案。但是您对这个答案的评论表明您对其他数据结构持开放态度。既然你说,你想看看邻居,你可能想看看我们2012年发表在《机器人软件工程杂志》(JOSER)上的论文“最近邻搜索策略和有效形状注册实现的比较”,谢谢你的想法。希望您解释的方式将有助于节省内存分配问题。我想知道有效的方法,以获得他们的邻居的三维体素,即26个体素!!!有什么想法吗?…@user1286780使用这种方法,
t_voxel_collection
表示一维。引入维度的简单方法是使用容器,例如
std::vector
。与
t\u voxel\u collection
的实现类似,可能有更优化的方法来表示集合的维度,具体取决于h