2012-03-29 267 views
4

我一直在试图验证我的代码来计算写在的Python马氏距离(双重校验的结果OpenCV的比较) 我的数据点是一维的每个(5行×1列)。一维马氏距离在Python

的OpenCV(C++),我成功地计算马哈拉诺比斯距离时,数据点的尺寸是与上述尺寸。

以下代码是未成功在计算矩阵的维数为5行x 1列时的Mahalanobis距离。 但它的工作原理,当列的矩阵中的数量都超过1

import numpy; 
import scipy.spatial.distance; 
s = numpy.array([[20],[123],[113],[103],[123]]); 
covar = numpy.cov(s, rowvar=0); 
invcovar = numpy.linalg.inv(covar) 
print scipy.spatial.distance.mahalanobis(s[0],s[1],invcovar); 

我收到以下错误:

Traceback (most recent call last): 
    File "/home/abc/Desktop/Return.py", line 6, in <module> 
    invcovar = numpy.linalg.inv(covar) 
    File "/usr/lib/python2.6/dist-packages/numpy/linalg/linalg.py", line 355, in inv 
    return wrap(solve(a, identity(a.shape[0], dtype=a.dtype))) 
IndexError: tuple index out of range 
+0

如果我正确理解,在'numpy.linalg.inv'方法需要[方阵](http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.inv.html# numpy.linalg.inv),但你似乎给它一个单一的元素数组。 – srgerg 2012-03-30 00:17:55

+0

我明白这一点。那么,有没有解决? – garak 2012-03-30 00:28:22

回答

3

一维马氏距离是很容易的手动计算:

import numpy as np 
s = np.array([[20], [123], [113], [103], [123]]) 
std = s.std() 
print np.abs(s[0] - s[1])/std 

(减少the formula到一维的情况)。

scipy.spatial.distance的问题在于,由于某些原因,当给定一组1d变量时,np.cov返回标量,即零维数组。你想通过一个二维数组:

>>> covar = np.cov(s, rowvar=0) 

>>> covar.shape 
() 

>>> invcovar = np.linalg.inv(covar.reshape((1,1))) 

>>> invcovar.shape 
(1, 1) 

>>> mahalanobis(s[0], s[1], invcovar) 
2.3674720531046645 
+0

这很有帮助。但是,我似乎没有把握。您所描述的上述手动技术使我得到了与以下使用'scipy.spatial.distance.mahalanobis'的答案不同的答案。我能够将这个(第二技巧)结果与OpenCV中的结果进行匹配。我在这里错过了什么吗? – garak 2012-03-30 01:16:32

+0

@raul_w那是因为我很愚蠢。 :)(你需要用标准差来划分,而不是方差 - 我忘了采取的开方了。) – Dougal 2012-03-30 02:49:09

+0

很好,但它仍然不匹配:对。使用标准偏差给出了2.64的结果...并使用内置的功能重塑矩阵后,给出了2.36(我假设是正确的,因为它相匹配的结果OpenCV的)。谢谢您的帮助。 – garak 2012-03-30 12:46:42

0

协方差需要2个数组进行比较。在这两种np.cov()和OpenCV CalcCovarMatrix,它期望两个阵列被彼此堆叠(使用vstack)的顶部。如果您将n Rowy中的Rowvar更改为false,或者使用opencv中的COVAR_COL,则还可以将2个数组并排排列。如果你的数组是多维的,那么先将它们展平()。因此,如果我想比较两个24x24图像,我将它们都拼合成2个1x1024的图像,然后将两个图像叠加得到2x1024,这是np.cov()的第一个参数。

那么你应该得到一个大方阵,它显示了每个元素在阵列1在每个数组2元相比较的结果。在我的例子中它将是1024x1024。这是你通过你的反转功能。