我一直在尝试验证我的代码,以计算用Python编写的Mahalanobis距离(并在OpenCV中进行双重检查以比较结果)我的数据点每个都有1个维度(5行x 1列)。
在OpenCV(C++)中,当数据点的维度具有上述维度时,我成功地计算了Mahalanobis距离。
当矩阵的维数为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
一维马氏距离真的很容易手动计算:
import numpy as np
s = np.array([[20], [123], [113], [103], [123]])
std = s.std()
print np.abs(s[0] - s[1]) / std
(将公式简化为一维情况)。
但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
协方差需要2个数组进行比较。在np.cov()和Opencv CalcCovarMatrix中,它都希望这两个数组堆叠在一起(使用vstack)。如果在numpy中将Rowvar更改为false或在opencv中使用COVAR_COL,也可以将这两个数组并排放置。如果你的数组是多维的,只需先展平()。
因此,如果我想比较两个24x24的图像,我将它们都展平为2个1x1024的图像,然后将两者叠加以获得2x1024,这是np.cov()的第一个参数。
然后,您应该得到一个大的方形矩阵,其中显示了将array1中的每个元素与array2中的每个元件进行比较的结果。在我的示例中,它将是1024x1024。这就是你传递到反转函数中的内容。