Напротив двоичного_дилатации - PullRequest
1 голос
/ 12 апреля 2019

Есть ли функция, которая противоположна binary_dilation? Я ищу, чтобы удалить «острова» из массива 0 и 1. То есть, если значение 1 в двумерном массиве не имеет по крайней мере 1 соседнего соседа, который также равен 1, его значение устанавливается равным 0 (вместо того, чтобы значения его соседа были установлены равными 1, как в binary_dilation). Так, например:

test = np.zeros((5,5))
test[1,1] = test[1,2] = test[3,3] = test[4,3] = test[0,3] = test[3,1] = 1

test
array([[0., 0., 0., 1., 0.],
       [0., 1., 1., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 1., 0., 1., 0.],
       [0., 0., 0., 1., 0.]])

И функция, которую я ищу, вернется:

array([[0., 0., 0., 0., 0.],
       [0., 1., 1., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 1., 0.]])

Обратите внимание, что значения, измененные в местоположениях [0,3] и [3,1] с 1 на 0, поскольку у них нет соседних соседей со значением, равным 1 (диагональ не считается соседом).

1 Ответ

2 голосов
/ 12 апреля 2019

Вы можете создать маску с ячейками для проверки и выполнить 2-мерную свертку с test, чтобы идентифицировать ячейки с 1 s рядом с ними.Логические и свертки и test должны дать желаемый результат.

Сначала определите свою маску.Поскольку вы ищете только смешение вверх / вниз и влево / вправо, вам нужно следующее:

mask = np.ones((3, 3))
mask[1,1] = mask[0, 0] = mask[0, 2] = mask[2, 0] = mask[2, 2] = 0
print(mask)
#array([[0., 1., 0.],
#       [1., 0., 1.],
#       [0., 1., 0.]])

Если вы хотите включить диагональные элементы, вы просто обновите mask, чтобы включить 1s в углах.

Теперь примените двумерную свертку test с mask.Это умножит и добавит значения из двух матриц.С этой маской будет возвращаться сумма всех смежных значений для каждой ячейки.

from scipy.signal import convolve2d
print(convolve2d(test, mask, mode='same'))
#array([[0., 1., 2., 0., 1.],
#       [1., 1., 1., 2., 0.],
#       [0., 2., 1., 1., 0.],
#       [1., 0., 2., 1., 1.],
#       [0., 1., 1., 1., 1.]])

Вы должны указать mode='same', так что результат будет того же размера, что и первый вход (test).Обратите внимание, что две ячейки, которые вы хотели удалить из test, - это 0 в выводе свертки.

Наконец, выполните поэлементную and операцию с этим выводом и test, чтобы найти нужные ячейки:

res = np.logical_and(convolve2d(test, mask, mode='same'), test).astype(int)
print(res)
#array([[0, 0, 0, 0, 0],
#       [0, 1, 1, 0, 0],
#       [0, 0, 0, 0, 0],
#       [0, 0, 0, 1, 0],
#       [0, 0, 0, 1, 0]])

Обновление

Для последнего шага вы также можете просто clip значения в свертке между 0 и 1 и выполнить поэлементное умножение.

res = convolve2d(test, mask, mode='same').clip(0, 1)*test
#array([[0., 0., 0., 0., 0.],
#       [0., 1., 1., 0., 0.],
#       [0., 0., 0., 0., 0.],
#       [0., 0., 0., 1., 0.],
#       [0., 0., 0., 1., 0.]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...