Вычислить количество равных соседних ячеек в массиве numpy

У меня есть двумерный двоичный файл numpy arrays разного размера, который содержит определенные шаблоны. Именно так:

import numpy
a = numpy.zeros((6,6), dtype=numpy.int)
a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1

Здесь «изображение» содержит два фрагмента: один с 2, а другой с 3 соединенными ячейками.

print a
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 1, 0],
       [0, 0, 0, 0, 1, 0]])


Я хочу знать, как часто ненулевая ячейка граничит с другой ненулевой ячейкой ( соседи определяются как ладья, то есть ячейки слева, справа, ниже и выше каждой ячейки), включая их псевдорепликация (и наоборот).

Предыдущий подход для внутренних границ возвращает неправильные значения (5), поскольку он был предназначен для вычисления внешние границы.

numpy.abs(numpy.diff(a, axis=1)).sum()

Таким образом, для приведенного выше тестового массива правильный общий результат будет 6 (верхний патч имеет две внутренние границы, нижний четыре).

Благодарен за любые советы!

РЕДАКТИРОВАТЬ:

  • Ошибка: Нижний явно имеет 4 внутренних ребра (соседние ячейки с одинаковым значением)

  • Объяснил желаемое соседство немного больше


person Curlew    schedule 01.04.2016    source источник
comment
Что означают соседи, определенные как случай ладьи?   -  person user2357112 supports Monica    schedule 02.04.2016
comment
Почему нижняя шестерка?   -  person HYRY    schedule 02.04.2016
comment
Что ж, очевидным решением было бы просто выполнить двойной цикл по индексам и подсчитать.   -  person Ulf Aslak    schedule 02.04.2016
comment
Мне нужно проверить, равны ли соседи слева, справа, снизу и сверху каждой клетки (ладьи) центральной клетке. @HYRY: ошибка, извините. Нижний имеет 4 внутренних границы (ячейки, соседние ячейки с одинаковым значением)   -  person Curlew    schedule 02.04.2016


Ответы (1)


Я думаю, что результат равен 8, если это 8-связная окрестность. Вот код:

import numpy
a = numpy.zeros((6,6), dtype=numpy.int)
a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1

from scipy.ndimage import convolve

kernel = np.ones((3, 3))
kernel[1, 1] = 0
b = convolve(a, kernel, mode="constant")
b[a != 0].sum()

но вы сказали дело ладьи.

изменить

Вот код для 4-связной окрестности:

import numpy as np
a = np.zeros((6,6), dtype=np.int)
a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1

from scipy import ndimage
kernel = ndimage.generate_binary_structure(2, 1)
kernel[1, 1] = 0

b = convolve(a, kernel, mode="constant")
b[a != 0].sum()
person HYRY    schedule 01.04.2016
comment
Извините за недопонимание. Я хочу знать простое соседство 4x4 (чтобы не было диагональных соединений, например, слева, справа, сверху, снизу). Я отредактировал свой вопрос выше, поскольку правильный ответ действительно 6, а не 8 (общее количество равных соседей в нижней половине равно 4) - person Curlew; 02.04.2016
comment
Я пытался адаптировать ваш пример, но это оказалось не так просто... s = ndimage.generate_binary_structure(2,2) s[0,0] = s[0,2] = s[2,0] = s[2,2] = 0 b = ndimage.convolve(a, s, mode="constant") b[a != 0].sum() # equals 11 - person Curlew; 02.04.2016
comment
Ого, это помогает. Забыл заменить центральную ячейку... Спасибо! - person Curlew; 02.04.2016