且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在像素阵列中查找连接的组件

更新时间:2023-02-26 15:32:31

考虑到各个组之间永不相互接触,可以使用

Considering that the groups should never touch each other, you can use scipy.ndimage.measurements.label to label the groups:

In [1]: import numpy as np

In [2]: from scipy.ndimage.measurements import label

In [3]: array = np.array(...)  # your example

In [4]: structure = np.ones((3, 3), dtype=np.int)  # this defines the connection filter

In [5]: structure  # in this case we allow any kind of connection
Out[5]: 
array([[1, 1, 1],
       [1, 1, 1],
       [1, 1, 1]])

In [6]: labeled, ncomponents = label(array, structure)

In [7]: labeled
Out[7]: 
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=int32)

In [7]: ncomponents
Out[7]: 2

尽管我还没有阅读特定的实现,但是SciPy倾向于使用在C中实现的高效算法,因此性能应该相对较高.然后,您可以使用NumPy提取每个组的索引:

Although I haven't read the particular implementation, SciPy tends to use highly efficient algorithms implemented in C, hence the performance should be relatively high. You can then extract the indices for each group using NumPy:

In [8]: indices = np.indices(array.shape).T[:,:,[1, 0]]

In [9]: indices[labeled == 1]
Out[9]: 
array([[ 1,  6],
       [ 1,  7],
       [ 2,  6],
       [ 2,  7],
       [ 2,  8],
       [ 2,  9],
       [ 2, 10],
       [ 2, 11],
       [ 2, 12],
       [ 2, 13],
       [ 3, 11],
       [ 3, 12],
       [ 3, 13]])

In [10]: indices[labeled == 2]
Out[10]: 
array([[ 5,  1],
       [ 6,  1],
       [ 7,  1],
       [ 7,  2],
       [ 8,  1],
       [ 8,  2],
       [ 9,  2],
       [10,  2],
       [10,  3],
       [11,  2],
       [11,  3],
       [12,  3],
       [13,  3]])