如何在Python中用np.linalg.norm替换scipy.spatial.distance

2024-05-19 01:35:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我遵循本教程为我的项目实现对象跟踪-https://www.pyimagesearch.com/2018/07/23/simple-object-tracking-with-opencv/

该方法是在初始帧中找到检测对象的质心,然后计算到下一帧中显示的其他检测对象质心的最短距离。假设最近的质心是同一个物体

在教程中-

from scipy.spatial import distance as dist
...
D = dist.cdist(np.array(objectCentroids), newCentroids)

用于计算距离(欧几里德距离)。不幸的是,我无法使用scipy模块,因为我正试图将其部署到AWS Lambda(大小限制)。在这种情况下,建议使用此-https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.norm.html

D = np.linalg.norm(objectCentroids – newCentroids)

问题是,与dist.cdist不同,它计算所有矩阵和任何矩阵,np.linalg.norm只输出1个值,该值是在从objectCentroids矩阵减去newCentroids后计算的。我将循环n次(不管矩阵有多大),然后附加到另一个矩阵来构造我需要的结果。然而,我不确定我对这个概念的理解是否正确,所以我想寻求一些帮助。如果有人知道更好的方法,我将不胜感激

更新

根据我得到的反馈/回答,我对代码进行了一些更新,然后。。。它似乎在起作用-

n = arrayObjectCentroids.shape[0]
m = inputCentroids.shape[0]

T = []

for i in range(0,n):
    for z in range(0,m):
        Tv = np.linalg.norm(arrayObjectCentroids[i] - inputCentroids[z])
        # print(f'Tv is \n {Tv}')
        T = np.append(T, Tv)
        # print(f'T is \n {T}')
    print(f'new T is \n {T}')   
D = np.reshape(T, (n, m))
print(f'D is \n {D}')

在这种情况下,如果有一个物体移动一点-

新质心是[[224 86]],它的形状是(1,2)。。。 objectCentroids是[[224 86]],形状objectCentroids是(1,2)

D是[[0.]]

如果我有3个对象

新的质心是

 [[228  79]
 [ 45 127]
 [103 123]]

输入质心的形状为(3,2)

物体质心是

 [[228  79]
 [ 45 127]
 [103 123]]

形状对象质心为(3,2)

D是

 [[  0.         189.19038031 132.51792332]
 [189.19038031   0.          58.13776741]
 [132.51792332  58.13776741   0.        ]]

很好,它的工作,但我觉得这可能不是最好的解决方案,如果你有任何指针,我将不胜感激! 谢谢


Tags: 对象normisdistnp矩阵scipytv
2条回答

可以使用Numpy广播创建距离矩阵

阅读herehere

基本思想是:

将质心堆叠(重塑)为(1, n, 3)(n, 1, 3),其中形状为3的最后一个维度为(x,y,z)。然后减去数组并使用np.linalg.norm计算沿轴的距离。。。陛下可能是最后一个。这将产生一个平方距离矩阵

编辑:编辑代码以处理下面的评论

如果在欧几里德空间中有向量,那么np.linalg.norm将返回该向量的长度

所以objectCentroid – newCentroid将给出objectCentroid点和newCentroid点之间的向量。请注意,它介于2个点之间,而不是包含所有点的数组

要获得所有点的组合,我使用了itertools&;然后重新调整数组的形状,以提供与dist相同的输出

import numpy as np
from scipy.spatial import distance as dist
import itertools

# Example data
objectCentroids = np.array([[0,0,0],[1,1,1],[2,2,2], [3,3,3]])
newCentroids    = np.array([[4,4,4],[5,5,5],[6,6,6],[7,7,7]])
comb            = list(itertools.product(objectCentroids, newCentroids))
all_dist        = [] 

for pair in comb:

    dis = np.linalg.norm((pair[0] - pair[1]))
    all_dist.append(dis)

all_dist = np.reshape(all_dist, (len(objectCentroids), len(objectCentroids)))
D        = dist.cdist(objectCentroids, newCentroids)   

print(D)
print(" ")
print(all_dist)

相关问题 更多 >

    热门问题