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