Преобразование расстояния с расстоянием Манхэттена - Python / NumPy / SciPy - PullRequest
2 голосов
/ 31 января 2020

Я хотел бы сгенерировать 2-мерный массив, как это, используя Python и Numpy:

[
  [0, 1, 2, 3, 4, 4, 3, 4],
  [1, 2, 3, 4, 4, 3, 2, 3],
  [2, 3, 4, 4, 3, 2, 1, 2],
  [3, 4, 4, 3, 2, 1, 0, 1],
  [4, 5, 5, 4, 3, 2, 1, 2]
]

Практически все числа разбросаны влево и вправо, начиная с нулей. Эта матрица позволяет увидеть расстояние любой точки до ближайшего нуля. Я думал, что эта матрица была распространена, но я не мог найти ничего в Интернете, даже ее название. Если у вас есть код для эффективной генерации такой матрицы или вы хотя бы знаете, как она называется, сообщите мне.

Спасибо

1 Ответ

5 голосов
/ 31 января 2020

Вот один с Scipy cdist -

from scipy.spatial.distance import cdist

def bwdist_manhattan(a, seedval=1):
    seed_mask = a==seedval
    z = np.argwhere(seed_mask)
    nz = np.argwhere(~seed_mask)

    out = np.zeros(a.shape, dtype=int)
    out[tuple(nz.T)] = cdist(z, nz, 'cityblock').min(0).astype(int)
    return out

В MATLAB он называется Distance transform of binary image, поэтому здесь дается производное имя.

Пробный прогон -

In [60]: a # input binary image with 1s at "seed" positions
Out[60]: 
array([[1, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 0, 0, 0]])

In [61]: bwdist_manhattan(a)
Out[61]: 
array([[0, 1, 2, 3, 4, 4, 3, 4],
       [1, 2, 3, 4, 4, 3, 2, 3],
       [2, 3, 4, 4, 3, 2, 1, 2],
       [3, 4, 4, 3, 2, 1, 0, 1],
       [4, 5, 5, 4, 3, 2, 1, 2]])
...