Используя диагональную структуру, как подробно описано в этом ответе относительно «Построить матрицу смежности в MATLAB», я создаю только верхние диагонали и добавьте их в соответствующие позиции в разреженную диагональную матрицу, используя scipy.sparse.diags. Эта разреженная матрица добавляется к транспонированной, чтобы получить матрицу смежности.
При работе с изображениями часто бывает желательно разбить изображение на неперекрывающиеся прямоугольные фрагменты изображения или участки. Параметр patch_size - это кортеж (rows, cols), который описывает прямоугольный патч размером «rows x cols».
import numpy as np
import scipy.sparse as s
def connected_adjacency(image, connect, patch_size=(1, 1)):
"""
Creates an adjacency matrix from an image where nodes are considered adjacent
based on 4-connected or 8-connected pixel neighborhoods.
:param image: 2 or 3 dim array
:param connect: string, either '4' or '8'
:param patch_size: tuple (n,m) used if the image will be decomposed into
contiguous, non-overlapping patches of size n x m. The
adjacency matrix will be formed from the smaller sized array
e.g. original image size = 256 x 256, patch_size=(8, 8),
then the image under consideration is of size 32 x 32 and
the adjacency matrix will be of size
32**2 x 32**2 = 1024 x 1024
:return: adjacency matrix as a sparse matrix (type=scipy.sparse.csr.csr_matrix)
"""
r, c = image.shape[:2]
r = r / patch_size[0]
c = c / patch_size[1]
if connect == '4':
# constructed from 2 diagonals above the main diagonal
d1 = np.tile(np.append(np.ones(c-1), [0]), r)[:-1]
d2 = np.ones(c*(r-1))
upper_diags = s.diags([d1, d2], [1, c])
return upper_diags + upper_diags.T
elif connect == '8':
# constructed from 4 diagonals above the main diagonal
d1 = np.tile(np.append(np.ones(c-1), [0]), r)[:-1]
d2 = np.append([0], d1[:c*(r-1)])
d3 = np.ones(c*(r-1))
d4 = d2[1:-1]
upper_diags = s.diags([d1, d2, d3, d4], [1, c-1, c, c+1])
return upper_diags + upper_diags.T
else:
raise ValueError('Invalid parameter \'connect\'={connect}, must be "4" or "8".'
.format(connect=repr(connect)))
Простой пример:
a = np.arange(9).reshape((3, 3))
adj = connected_adjacency(a, '4').toarray()
print a
[[0 1 2]
[3 4 5]
[6 7 8]]
print adj
[[ 0. 1. 0. 1. 0. 0. 0. 0. 0.]
[ 1. 0. 1. 0. 1. 0. 0. 0. 0.]
[ 0. 1. 0. 0. 0. 1. 0. 0. 0.]
[ 1. 0. 0. 0. 1. 0. 1. 0. 0.]
[ 0. 1. 0. 1. 0. 1. 0. 1. 0.]
[ 0. 0. 1. 0. 1. 0. 0. 0. 1.]
[ 0. 0. 0. 1. 0. 0. 0. 1. 0.]
[ 0. 0. 0. 0. 1. 0. 1. 0. 1.]
[ 0. 0. 0. 0. 0. 1. 0. 1. 0.]]
Использование networkx + matplotlib для построения матрицы смежности в виде графика:
person
Scott
schedule
12.05.2015