PCL kd-tree实现速度极慢

时间:2014-08-22 18:24:16

标签: nearest-neighbor point-cloud-library cgal kdtree

我正在使用基于点云库(PCL)的kd-tree最近邻居(NN)搜索的C ++实现。该数据集包含约220万个点。我正在寻找每个点的NN点。搜索半径设置为2.0。要完全计算,大约需要12个小时!我正在使用带有4GB RAM的Windows 64位机器。 kd-tree搜索是否很常见?我想知道是否还有其他用于3D点云数据的c ++库,这种方法更快。我听说过ANN C ++库& CGAL,但不确定这些是多快。

1 个答案:

答案 0 :(得分:4)

简而言之:

你只能确定自己是否经历了时间测量。

你应该确保NN库是否比蛮力更快,这可能就是你的数据。

作为评论中提到的anderas,搜索半径也起着重要作用。如果很多点落入搜索半径,搜索可能变得非常慢。

完整答案:

3个维度并不多。由于您拥有的点数,会出现问题。

ANN代表近似最近邻搜索。在NNS(最近邻搜索)方面,接受准确度和速度之间的权衡是很常见的。

这意味着您可以更快地执行搜索,但是您可能找不到精确的NN,而是一个非常接近的NN(例如,不是最近的点,而是第二个最接近的点,依此类推)。速度越快意味着精度越低,反之亦然。

CGAL还有一个参数epsilon,它代表精度(ε= 0表示完全准确度)。 CGAL意味着要达到3个维度,所以你可以试一试。

我可以测试自己并发布答案。但是,这不是100%安全,因为你拥有的点可能有一些关系。如果要利用点(可能)彼此之间的关系,这对于库的性能非常重要。

要考虑的另一个因素是安装的简便性。

CGAL很难安装。当我这样做时,我遵循these步骤。 ANN易于安装。 我还建议你看看BOOST Geometry,这可能会派上用场。

FLANN在该领域也是一个强大的参与者,但我不建议,因为它意味着处理更大尺寸的数据集(例如128)。

...

好的,我承认,我现在很好奇,我将进行一些测试!

...

<强> ANN

(我没有发布代码,所以答案不会太大。文档中有一些例子,你当然可以问你是否想要!)。 输出:

//对于Klein瓶

samaras@samaras-A15:~/Inria/nn_libs/ANN/ann_1.1.2/code$ g++ main.cpp -O3 -I ../include/ -L../lib -lANN -std=c++0x -o myExe
samaras@samaras-A15:~/Inria/nn_libs/ANN/ann_1.1.2/code$ ./myExe
N = 1000000
D = 3
ε = 0 // full accuracy
Misses: 0
creation of the tree took 1.06638 seconds.
Brute force for min: 0.009985598 seconds.
NN for 0.0           0.000078551 seconds.
Speedup of ANN for NN = 8.721533780

对于ε = 0.1我得到了:

Misses: 1000
creation of the tree took 0.727613 seconds.
Brute force for min: 0.006351318 seconds.
NN for 0.0           0.000004260 seconds.
Speedup of ANN for NN = 8.678169573

// for shpere

ε = 0
Misses: 0
creation of the tree took 1.28098 seconds.
Brute force for min: 0.006382912 seconds.
NN for 0.0           0.000022341 seconds.
Speedup of ANN for NN = 4.897436311

ε = 0.1
Misses: 1000
creation of the tree took 1.25572 seconds.
Brute force for min: 0.006482465 seconds.
NN for 0.0           0.000004379 seconds.
Speedup of ANN for NN = 5.144413371

注意加速的差异!这与数据集的性质有关,如上所述(点的关系)。

<强> CGAL:

// Klein bottle

samaras@samaras-A15:~/code/NN$ ./myExe
ε = 0
SplitingRule = Sliding_midpoint, N = 1000000, D = 3
creation of the tree took 0.02478 seconds.
Tree statistics:
Number of items stored: 1000000
Number of nodes: 471492
 Tree depth: 34
0x80591e4
Brute force for min: 0.007979495 seconds.
NN for 0.0           0.008085704 seconds.
Speedup of cgal for NN = 0.983849423

ε = 0.1
SplitingRule = Sliding_midpoint, N = 1000000, D = 3
creation of the tree took 0.02628 seconds.
Tree statistics:
Number of items stored: 1000000
Number of nodes: 471492
 Tree depth: 34
0x80591e4
Brute force for min: 0.007852951 seconds.
NN for 0.0           0.007856228 seconds.
Speedup of cgal for NN = 0.996250305

//球体

samaras@samaras-A15:~/code/NN$ ./myExe
ε = 0
SplitingRule = Sliding_midpoint, N = 1000000, D = 3
creation of the tree took 0.025502 seconds.
Tree statistics:
Number of items stored: 1000000
Number of nodes: 465002
 Tree depth: 32
0x80591e4
Brute force for min: 0.007946504 seconds.
NN for 0.0           0.007981456 seconds.
Speedup of cgal for NN = 0.992449817


samaras@samaras-A15:~/code/NN$ ./myExe
ε = 0.1
SplitingRule = Sliding_midpoint, N = 1000000, D = 3
creation of the tree took 0.025106 seconds.
Tree statistics:
Number of items stored: 1000000
Number of nodes: 465002
 Tree depth: 32
0x80591e4
Brute force for min: 0.008115519 seconds.
NN for 0.0           0.008117261 seconds.
Speedup of cgal for NN = 0.996702679

对于我的测试,ANN比CGAL更快,也许对你来说也是如此!


附注:

你实际上要求每个点的NN。但是,图书馆并不知道这一点,也没有考虑到以前为每一点所做的工作,这很可惜。但是,我不知道有任何库可以做到这一点。