【问题标题】:The most efficient way to processing images (mahalanobis distances)处理图像的最有效方法(马氏距离)
【发布时间】:2016-07-11 11:36:14
【问题描述】:

我已经根据description 编写了一个脚本。

2D numpy 数组的图像很少,如果图像很大,计算每个值需要很长时间。有没有比我的解决方案更好的方法?

考虑三幅图像,均值向量和反协方差矩阵:

a = image1
b = image2
c = image3 # numpy arrays, NxM size
m = np.array([m1, m2, m3]) # means vector
covariance = np.cov([a.ravel(), b.ravel(), c.ravel()])
inv_cov = np.linalg.inv(covariance) # inv. covariance matrix

我用双循环解决了这个问题:

result = np.zeros((y,x)) # y,x are sizes of images

for i in xrange(y):
    for j in xrange(x):
        v = np.array([a[i,j], b[i,j], c[i,j]]) # array with particular pixels from each image
        result[i,j] = mahalanobis(v,m,inv_cov) # calculate mahalanobis distance and insert value as a pixel

我认为可能有更好的方法可以更快地做到这一点。也许没有循环?

【问题讨论】:

    标签: python numpy image-processing mahalanobis


    【解决方案1】:

    使用scipy.spatial.distance.cdist 计算来自 2 个输入集合的每对点之间的距离。

    import numpy as np
    import scipy.spatial.distance as SSD
    h, w = 40, 60
    A = np.random.random((h, w))
    B = np.random.random((h, w))
    C = np.random.random((h, w))
    M = np.array([A.mean(), B.mean(), C.mean()])  # means vector
    covariance = np.cov([A.ravel(), B.ravel(), C.ravel()])
    inv_cov = np.linalg.inv(covariance)  # inv. covariance matrix
    
    def orig(A, B, C, M, inv_cov):
        h, w = A.shape
        result = np.zeros_like(A, dtype='float64')
    
        for i in range(h):
            for j in range(w):
                # array with particular pixels from each image
                v = np.array([A[i, j], B[i, j], C[i, j]])
                # calculate mahalanobis distance and insert value as a pixel
                result[i, j] = SSD.mahalanobis(v, M, inv_cov)
        return result
    
    def using_cdist(A, B, C, M, inv_cov):
        D = np.dstack([A, B, C]).reshape(-1, 3)
        result = SSD.cdist(D, M[None, :], metric='mahalanobis', VI=inv_cov)
        result = result.reshape(A.shape)
        return result
    
    expected = orig(A, B, C, M, inv_cov)
    result = using_cdist(A, B, C, M, inv_cov)
    assert np.allclose(result, expected)
    

    即使对于三个小 (40x60) 图像,using_cdist 的速度也快了约 285 倍:

    In [49]: expected = orig(A, B, C, M, inv_cov)
    
    In [76]: result = using_cdist(A, B, C, M, inv_cov)
    
    In [78]: np.allclose(result, expected)
    Out[78]: True
    
    In [79]: %timeit orig(A, B, C, M, inv_cov)
    10 loops, best of 3: 36.3 ms per loop
    
    In [80]: %timeit using_cdist(A, B, C, M, inv_cov)
    10000 loops, best of 3: 127 µs per loop
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-21
      • 2013-09-10
      • 1970-01-01
      • 2012-07-31
      • 2019-08-01
      • 1970-01-01
      • 2012-04-13
      相关资源
      最近更新 更多