I'm assuming that your matrix is binary where non-zero values represent the extracted segments and zero values are values you don't care about. The scikit-image
label
function from the measure
module may be of interest: http://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.label
It essentially performs a connected components analysis and labels all separately closed components together with an integer number. You need to be careful though with regards to how you specify connectivity. There is 4-connectedness and 8-connectedness where the former finds connected regions using only the North, South, East and West directions whereas 8-connectedness uses all 8 directions (North, South, East, West, Northeast, Southeast, Northwest, Southwest). You would use the connectivity
option and specify 1
for the 4-connectedness and 2
for the 8-connectedness.
However, the default connectivity would be a full connectivity, so for the case of 2D it would be the 2
option. I suspect for you it would be this way. Any blobs in your matrix that are zero would be labelled as zero. Without further ado, here's a very simple reproducible example:
In [1]: from skimage.measure import label
In [2]: import numpy as np
In [3]: x = np.zeros((8,8))
In [4]: x[0:4,0:4] = 1
In [5]: x[6:8,6:8] = 1
In [6]: x
Out[6]:
array([[ 1., 1., 1., 1., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 0., 0., 0., 0.],
[ 1., 1., 1., 1., 0., 0., 0., 0.],
[ 1., 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., 1., 1.],
[ 0., 0., 0., 0., 0., 0., 1., 1.]])
In [7]: label(x)
Out[7]:
array([[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0, 0],
[1, 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, 2, 2],
[0, 0, 0, 0, 0, 0, 2, 2]], dtype=int64)
We can see that there are two separate islands that I created on the top left and bottom right corner. Once you run the label
function, it returns a label matrix identifying regions of pixels that belong to each other. Pixels that have the same ID mean that the belong to the same region.
To show you how the connectivity comes into play, here's another simple example:
In [1]: import numpy as np
In [2]: from skimage.measure import label
In [3]: y = np.array([[0,1,0,0],[1,1,1,0],[0,1,0,1]])
In [4]: y
Out[4]:
array([[0, 1, 0, 0],
[1, 1, 1, 0],
[0, 1, 0, 1]])
In [5]: label(y, connectivity=1)
Out[5]:
array([[0, 1, 0, 0],
[1, 1, 1, 0],
[0, 1, 0, 2]], dtype=int64)
In [6]: label(y)
Out[6]:
array([[0, 1, 0, 0],
[1, 1, 1, 0],
[0, 1, 0, 1]], dtype=int64)
The input has a cross pattern on the top left corner and a separate non-zero value at the bottom right corner. If we use 4-connectivity, the bottom right corner would be classified as a different label but if we use the default connectivity (full), every pixel would be classified as the same label.