【问题标题】:Python: distance from index to 1s in binary maskPython:二进制掩码中从索引到 1 的距离
【发布时间】:2020-02-21 21:23:04
【问题描述】:

我有一个像这样的二进制掩码:

X = [[0, 0, 0, 0, 0, 1],
     [0, 0, 0, 0, 1, 1],
     [0, 0, 0, 1, 1, 1],
     [0, 0, 1, 1, 1, 1],
     [0, 0, 1, 1, 1, 1],
     [0, 0, 0, 1, 1, 1]]

我在这个数组中有一个特定的索引,并且想要计算从该索引到掩码中最近的1 的距离。如果该索引处已经存在1,则距离应为零。 示例(假设曼哈顿距离):

distance(X, idx=(0, 5)) == 0 # already is a 1 -> distance is zero
distance(X, idx=(1, 2)) == 2 # second row, third column
distance(X, idx=(0, 0)) == 5 # upper left corner

在 Python/NumPy/SciPy 中是否已经存在类似的功能?欧几里得距离和曼哈顿距离都可以。 我宁愿避免计算整个矩阵的距离(因为这在我的情况下相当大),并且只获得我的一个索引的距离。

【问题讨论】:

  • 什么距离?曼哈顿?欧几里得?
  • I have an index in this array 什么意思?
  • 你的意思类似于distance transform?
  • IIUC For manhattan one,使用bwdist_manhattan(X)[0,5] 等等。这使用cdist,因此您可以简单地更改欧几里得的距离度量。

标签: python numpy scipy


【解决方案1】:

这是manhattan 一个条目的距离度量 -

def bwdist_manhattan_single_entry(X, idx):
    nz = np.argwhere(X==1)
    return np.abs((idx-nz).sum(1)).min()

示例运行 -

In [143]: bwdist_manhattan_single_entry(X, idx=(0,5))
Out[143]: 0

In [144]: bwdist_manhattan_single_entry(X, idx=(1,2))
Out[144]: 2

In [145]: bwdist_manhattan_single_entry(X, idx=(0,0))
Out[145]: 5

通过仅从 1s 的 blob 中提取边界元素来进一步优化性能 -

from scipy.ndimage.morphology import binary_erosion

def bwdist_manhattan_single_entry_v2(X, idx):
    k = np.ones((3,3),dtype=int)
    nz = np.argwhere((X==1) & (~binary_erosion(X,k,border_value=1)))
    return np.abs((idx-nz).sum(1)).min()

使用这种方法nz 中的元素数量会比之前的少,因此会有所改进。

【讨论】:

    【解决方案2】:

    您可以使用scipy.ndimage.morphology.distance_transform_cdt 来计算“出租车”(曼哈顿)距离变换:

    import numpy as np
    import scipy.ndimage.morphology
    
    x = np.array([[0, 0, 0, 0, 0, 1],
                  [0, 0, 0, 0, 1, 1],
                  [0, 0, 0, 1, 1, 1],
                  [0, 0, 1, 1, 1, 1],
                  [0, 0, 1, 1, 1, 1],
                  [0, 0, 0, 1, 1, 1]])
    d = scipy.ndimage.morphology.distance_transform_cdt(1 - x, 'taxicab')
    print(d[0, 5])
    # 0
    print(d[1, 2])
    # 2
    print(d[0, 0])
    # 5
    

    【讨论】:

    • 看起来不错!有没有办法避免计算整个矩阵x 的距离?我的矩阵很大,我只需要一个索引的距离,所以理论上算法可以提前停止。
    • @knub 啊,我明白了,我以为你想要整个地图......不,我不认为提供这样的功能,你最好使用类似 Divakar's solution 的东西(在在这种情况下,如果您想计算几个点而不是单个点的距离,您至少可以保存 np.argwhere 的结果。
    【解决方案3】:

    你可以这样做:

    def Manhattan_distance(X, idx):
        dist = min([ abs(i-idx[0]) + abs(j-idx[1]) for i, row in enumerate(X) for j, val in enumerate(X[i]) if val == 1])
        return dist
    

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-17
      • 1970-01-01
      • 2013-09-25
      • 2017-03-19
      • 1970-01-01
      • 2016-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多