Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用python numpy在三维空间中查找点的k个最近邻_Python_Numpy_Knn - Fatal编程技术网

使用python numpy在三维空间中查找点的k个最近邻

使用python numpy在三维空间中查找点的k个最近邻,python,numpy,knn,Python,Numpy,Knn,我有一个由n个点组成的3d点云,格式为np.arrayn,3。e、 g这可能类似于: P = [[x1,y1,z1],[x2,y2,z2],[x3,y3,z3],[x4,y4,z4],[x5,y5,z5],.....[xn,yn,zn]] 我希望能够得到每个点的K近邻 例如,P1的k近邻可能是P2、P3、P4、P5、P6,P2的KNN可能是P100、P150、P2等 如何在python中实现这一点 这可以通过以下方法巧妙地解决 首先,让我们创建一个在三维空间中存储点的示例阵列: import

我有一个由n个点组成的3d点云,格式为np.arrayn,3。e、 g这可能类似于:

P = [[x1,y1,z1],[x2,y2,z2],[x3,y3,z3],[x4,y4,z4],[x5,y5,z5],.....[xn,yn,zn]]
我希望能够得到每个点的K近邻

例如,P1的k近邻可能是P2、P3、P4、P5、P6,P2的KNN可能是P100、P150、P2等


如何在python中实现这一点

这可以通过以下方法巧妙地解决

首先,让我们创建一个在三维空间中存储点的示例阵列:

import numpy as np
N = 10  # The number of points
points = np.random.rand(N, 3)
print(points)
输出:

array([[ 0.23087546,  0.56051787,  0.52412935],
       [ 0.42379506,  0.19105237,  0.51566572],
       [ 0.21961949,  0.14250733,  0.61098618],
       [ 0.18798019,  0.39126363,  0.44501143],
       [ 0.24576538,  0.08229354,  0.73466956],
       [ 0.26736447,  0.78367342,  0.91844028],
       [ 0.76650234,  0.40901879,  0.61249828],
       [ 0.68905082,  0.45289896,  0.69096152],
       [ 0.8358694 ,  0.61297944,  0.51879837],
       [ 0.80963247,  0.1680279 ,  0.87744732]])
array([[ 0. ,  0.4,  0.4,  0.2,  0.5,  0.5,  0.6,  0.5,  0.6,  0.8],
       [ 0.4,  0. ,  0.2,  0.3,  0.3,  0.7,  0.4,  0.4,  0.6,  0.5],
       [ 0.4,  0.2,  0. ,  0.3,  0.1,  0.7,  0.6,  0.6,  0.8,  0.6],
       [ 0.2,  0.3,  0.3,  0. ,  0.4,  0.6,  0.6,  0.6,  0.7,  0.8],
       [ 0.5,  0.3,  0.1,  0.4,  0. ,  0.7,  0.6,  0.6,  0.8,  0.6],
       [ 0.5,  0.7,  0.7,  0.6,  0.7,  0. ,  0.7,  0.6,  0.7,  0.8],
       [ 0.6,  0.4,  0.6,  0.6,  0.6,  0.7,  0. ,  0.1,  0.2,  0.4],
       [ 0.5,  0.4,  0.6,  0.6,  0.6,  0.6,  0.1,  0. ,  0.3,  0.4],
       [ 0.6,  0.6,  0.8,  0.7,  0.8,  0.7,  0.2,  0.3,  0. ,  0.6],
       [ 0.8,  0.5,  0.6,  0.8,  0.6,  0.8,  0.4,  0.4,  0.6,  0. ]])
[[0 3 1 2 5 7 4 6 8 9]
 [1 2 4 3 7 0 6 9 8 5]
 [2 4 1 3 0 7 6 9 5 8]
 [3 0 2 1 4 7 6 5 8 9]
 [4 2 1 3 0 7 9 6 5 8]
 [5 0 7 3 6 2 8 4 1 9]
 [6 7 8 9 1 0 3 2 4 5]
 [7 6 8 9 1 0 3 2 4 5]
 [8 6 7 9 1 0 3 5 2 4]
 [9 6 7 1 8 4 2 0 3 5]]
[[3 1 2]
 [2 4 3]
 [4 1 3]
 [0 2 1]
 [2 1 3]
 [0 7 3]
 [7 8 9]
 [6 8 9]
 [6 7 9]
 [6 7 1]]
我们计算每个点到所有其他点的距离:

from scipy.spatial import distance
D = distance.squareform(distance.pdist(points))
print(np.round(D, 1))  # Rounding to fit the array on screen
输出:

array([[ 0.23087546,  0.56051787,  0.52412935],
       [ 0.42379506,  0.19105237,  0.51566572],
       [ 0.21961949,  0.14250733,  0.61098618],
       [ 0.18798019,  0.39126363,  0.44501143],
       [ 0.24576538,  0.08229354,  0.73466956],
       [ 0.26736447,  0.78367342,  0.91844028],
       [ 0.76650234,  0.40901879,  0.61249828],
       [ 0.68905082,  0.45289896,  0.69096152],
       [ 0.8358694 ,  0.61297944,  0.51879837],
       [ 0.80963247,  0.1680279 ,  0.87744732]])
array([[ 0. ,  0.4,  0.4,  0.2,  0.5,  0.5,  0.6,  0.5,  0.6,  0.8],
       [ 0.4,  0. ,  0.2,  0.3,  0.3,  0.7,  0.4,  0.4,  0.6,  0.5],
       [ 0.4,  0.2,  0. ,  0.3,  0.1,  0.7,  0.6,  0.6,  0.8,  0.6],
       [ 0.2,  0.3,  0.3,  0. ,  0.4,  0.6,  0.6,  0.6,  0.7,  0.8],
       [ 0.5,  0.3,  0.1,  0.4,  0. ,  0.7,  0.6,  0.6,  0.8,  0.6],
       [ 0.5,  0.7,  0.7,  0.6,  0.7,  0. ,  0.7,  0.6,  0.7,  0.8],
       [ 0.6,  0.4,  0.6,  0.6,  0.6,  0.7,  0. ,  0.1,  0.2,  0.4],
       [ 0.5,  0.4,  0.6,  0.6,  0.6,  0.6,  0.1,  0. ,  0.3,  0.4],
       [ 0.6,  0.6,  0.8,  0.7,  0.8,  0.7,  0.2,  0.3,  0. ,  0.6],
       [ 0.8,  0.5,  0.6,  0.8,  0.6,  0.8,  0.4,  0.4,  0.6,  0. ]])
[[0 3 1 2 5 7 4 6 8 9]
 [1 2 4 3 7 0 6 9 8 5]
 [2 4 1 3 0 7 6 9 5 8]
 [3 0 2 1 4 7 6 5 8 9]
 [4 2 1 3 0 7 9 6 5 8]
 [5 0 7 3 6 2 8 4 1 9]
 [6 7 8 9 1 0 3 2 4 5]
 [7 6 8 9 1 0 3 2 4 5]
 [8 6 7 9 1 0 3 5 2 4]
 [9 6 7 1 8 4 2 0 3 5]]
[[3 1 2]
 [2 4 3]
 [4 1 3]
 [0 2 1]
 [2 1 3]
 [0 7 3]
 [7 8 9]
 [6 8 9]
 [6 7 9]
 [6 7 1]]
你可以这样读这个距离矩阵:点1和点5之间的距离是距离[0,4]。您还可以看到每个点与自身之间的距离为0,例如距离[6,6]==0

我们对距离矩阵的每一行进行argsort排序,以获得每个点的最近点列表:

closest = np.argsort(D, axis=1)
print(closest)
输出:

array([[ 0.23087546,  0.56051787,  0.52412935],
       [ 0.42379506,  0.19105237,  0.51566572],
       [ 0.21961949,  0.14250733,  0.61098618],
       [ 0.18798019,  0.39126363,  0.44501143],
       [ 0.24576538,  0.08229354,  0.73466956],
       [ 0.26736447,  0.78367342,  0.91844028],
       [ 0.76650234,  0.40901879,  0.61249828],
       [ 0.68905082,  0.45289896,  0.69096152],
       [ 0.8358694 ,  0.61297944,  0.51879837],
       [ 0.80963247,  0.1680279 ,  0.87744732]])
array([[ 0. ,  0.4,  0.4,  0.2,  0.5,  0.5,  0.6,  0.5,  0.6,  0.8],
       [ 0.4,  0. ,  0.2,  0.3,  0.3,  0.7,  0.4,  0.4,  0.6,  0.5],
       [ 0.4,  0.2,  0. ,  0.3,  0.1,  0.7,  0.6,  0.6,  0.8,  0.6],
       [ 0.2,  0.3,  0.3,  0. ,  0.4,  0.6,  0.6,  0.6,  0.7,  0.8],
       [ 0.5,  0.3,  0.1,  0.4,  0. ,  0.7,  0.6,  0.6,  0.8,  0.6],
       [ 0.5,  0.7,  0.7,  0.6,  0.7,  0. ,  0.7,  0.6,  0.7,  0.8],
       [ 0.6,  0.4,  0.6,  0.6,  0.6,  0.7,  0. ,  0.1,  0.2,  0.4],
       [ 0.5,  0.4,  0.6,  0.6,  0.6,  0.6,  0.1,  0. ,  0.3,  0.4],
       [ 0.6,  0.6,  0.8,  0.7,  0.8,  0.7,  0.2,  0.3,  0. ,  0.6],
       [ 0.8,  0.5,  0.6,  0.8,  0.6,  0.8,  0.4,  0.4,  0.6,  0. ]])
[[0 3 1 2 5 7 4 6 8 9]
 [1 2 4 3 7 0 6 9 8 5]
 [2 4 1 3 0 7 6 9 5 8]
 [3 0 2 1 4 7 6 5 8 9]
 [4 2 1 3 0 7 9 6 5 8]
 [5 0 7 3 6 2 8 4 1 9]
 [6 7 8 9 1 0 3 2 4 5]
 [7 6 8 9 1 0 3 2 4 5]
 [8 6 7 9 1 0 3 5 2 4]
 [9 6 7 1 8 4 2 0 3 5]]
[[3 1 2]
 [2 4 3]
 [4 1 3]
 [0 2 1]
 [2 1 3]
 [0 7 3]
 [7 8 9]
 [6 8 9]
 [6 7 9]
 [6 7 1]]
我们再次看到,每个点都离自己最近。因此,忽略这一点,我们现在可以选择k个最近点:

k = 3  # For each point, find the 3 closest points
print(closest[:, 1:k+1])
输出:

array([[ 0.23087546,  0.56051787,  0.52412935],
       [ 0.42379506,  0.19105237,  0.51566572],
       [ 0.21961949,  0.14250733,  0.61098618],
       [ 0.18798019,  0.39126363,  0.44501143],
       [ 0.24576538,  0.08229354,  0.73466956],
       [ 0.26736447,  0.78367342,  0.91844028],
       [ 0.76650234,  0.40901879,  0.61249828],
       [ 0.68905082,  0.45289896,  0.69096152],
       [ 0.8358694 ,  0.61297944,  0.51879837],
       [ 0.80963247,  0.1680279 ,  0.87744732]])
array([[ 0. ,  0.4,  0.4,  0.2,  0.5,  0.5,  0.6,  0.5,  0.6,  0.8],
       [ 0.4,  0. ,  0.2,  0.3,  0.3,  0.7,  0.4,  0.4,  0.6,  0.5],
       [ 0.4,  0.2,  0. ,  0.3,  0.1,  0.7,  0.6,  0.6,  0.8,  0.6],
       [ 0.2,  0.3,  0.3,  0. ,  0.4,  0.6,  0.6,  0.6,  0.7,  0.8],
       [ 0.5,  0.3,  0.1,  0.4,  0. ,  0.7,  0.6,  0.6,  0.8,  0.6],
       [ 0.5,  0.7,  0.7,  0.6,  0.7,  0. ,  0.7,  0.6,  0.7,  0.8],
       [ 0.6,  0.4,  0.6,  0.6,  0.6,  0.7,  0. ,  0.1,  0.2,  0.4],
       [ 0.5,  0.4,  0.6,  0.6,  0.6,  0.6,  0.1,  0. ,  0.3,  0.4],
       [ 0.6,  0.6,  0.8,  0.7,  0.8,  0.7,  0.2,  0.3,  0. ,  0.6],
       [ 0.8,  0.5,  0.6,  0.8,  0.6,  0.8,  0.4,  0.4,  0.6,  0. ]])
[[0 3 1 2 5 7 4 6 8 9]
 [1 2 4 3 7 0 6 9 8 5]
 [2 4 1 3 0 7 6 9 5 8]
 [3 0 2 1 4 7 6 5 8 9]
 [4 2 1 3 0 7 9 6 5 8]
 [5 0 7 3 6 2 8 4 1 9]
 [6 7 8 9 1 0 3 2 4 5]
 [7 6 8 9 1 0 3 2 4 5]
 [8 6 7 9 1 0 3 5 2 4]
 [9 6 7 1 8 4 2 0 3 5]]
[[3 1 2]
 [2 4 3]
 [4 1 3]
 [0 2 1]
 [2 1 3]
 [0 7 3]
 [7 8 9]
 [6 8 9]
 [6 7 9]
 [6 7 1]]

例如,我们看到,对于第4点,k=3最近点是1、3和2。

@marijn van vliet的解决方案在大多数情况下都能满足要求。但是,它被称为蛮力方法,如果点云相对较大或存在计算/时间限制,则可能需要考虑构建KD树,以快速检索点的K近邻

在python中,sklearn库提供了一个易于使用的实现:

从sklearn.KDTree导入 tree=KDTreepcloud 用于查找形状为1,3的P1的K个邻居 索引,距离=tree.queryP1,K 有关更详细的用法和输出,请参见另一篇文章中的以下答案:


许多其他库都有基于KD树的KNN检索的实现,包括和。

可能重复的numpy.linalg.norm和numpy.argsort可能会有所帮助。看,我昨晚自己也得出了同样的解决方案,但非常感谢你的详细解决方案。我相信将来会有人觉得这很有帮助。