Напротив двоичного_дилатации

1

Есть ли функция, которая делает противоположное 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 (диагональ не считается соседом).

  • 0
    Как описано, это не является прямым аналогом бинарной эрозии. Вы, кажется, на самом деле ищете фильтр, который ищет подключенные компоненты (только ортогональное соединение, а не диагональ) и удаляет компоненты с областью == 1. Вместо этого я бы направил ваш поиск на «маркировку подключенных компонентов».
Теги:
numpy

1 ответ

0

Вы можете создать маску с ячейками для проверки и выполнить 2-мерную свертку с test чтобы идентифицировать ячейки с 1 рядом с ними. Логическая и свертка и 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 чтобы включить 1 в углах.

Теперь примените двумерную свертку 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.]])

Ещё вопросы

Сообщество Overcoder
Наверх
Меню