在 3D 点云、GPU 中查找最近的邻居

Finding nearest neighbours in 3d point cloud, GPU

本文关键字:查找 最近 邻居 GPU 3D 点云      更新时间:2023-10-16

我想通过GPU计算点云中每个点的最近邻。 我的数据集如下所示:

<number of points in column>
<number of columns>
x   y   z
x   y   z
z   y   z
... ... ... 

有近 20^6 点。
我正在使用vector<PointXYZ> Input;来存储数据

class PointXYZ
{
public:
PointXYZ();
~PointXYZ();
PointXYZ(float X, float Y, float Z) : x(X), y(Y), z(Z) {};
float x;
float y;
float z;
};

读取数据是在for循环中,它忽略没有信息的点(

x == 0 && y == 0 && z == 0(。
PointXYZ* NewPoint = new PointXYZ(x, y, z);
Input.push_back(*NewPoint);

这是我的问题:

  1. 在将数据发送到 GPU 之前读取数据的最佳输入结构是什么?(当前读数大约需要 120 秒(。

  2. 我在 2d 图像中没有正确的点索引(因为我忽略了没有信息的点(。每个点都包含 x,y,z 值。找到 3/6/9 最近邻的最准确但不那么先进的算法是什么?通过 GPU 对这个点数进行线性比较(蛮力(效率不高吗?

我正在看八叉树,但我不确定如果没有适当的索引如何划分点云。

我刚刚做了一些测试。我使用了一个具有 10'000'000 个点的聚类 3D 数据集。实现是用Java实现的,我使用了我的qthypercube2实现。

  1. 对于我的测试,我经常将数据作为大型 float[] BLOB 存储在数据库中。将 10'000'000 个点加载到内存中大约需要 0.5 秒。
  2. 将数据加载到四叉树中(我使用自己的特殊实现(大约需要 4 秒。
  3. 执行 1'000'000 个 3-NN 搜索大约需要 20 秒,对于 10'000'000 个 3-N 搜索,大约需要 200 秒或 3.3 分钟。

我从未使用过GPU,但让我们做一些数学运算: 我假设"蛮力"是指将每一点与其他每一点进行比较?10^7 点表示 10^14 次比较操作。每次比较需要 10 个周期(只是为了有一个数字(意味着 10^15 个计算周期。假设 GPU 允许并行执行 1000 个操作,这仍然意味着 10^12 个周期。如果您的 GPU 时钟频率为 1GHz(每秒 10^9 次运算(,则总搜索时间为 10^12/10^9 = 10^3 = 1000 秒。 这没有考虑到:将数据加载到 GPU 中,存储(中间(最近邻,对中间结果进行排序(如果超过 1NN(,......

当然,GPU 和 NN 搜索实现的细节可能会有所不同,数据集的实际大小也可能不同。所有这些都可能会减少或增加这 1000 秒。 同样对于四叉树,数据集特征(聚类等(可能起着很大的作用,搜索的类型也可能发挥很大作用(我测试了 3 个最近邻(。此外,我的实现是"通用",因为它适用于任何维度。专用的 3D 实现可能会更快。

我的猜测:在 10M 点,使用四叉树应该比 GPU 版本更快,而且肯定更容易实现。