Floodfill segmented image in numpy/python

前提是你 提交于 2019-12-05 12:44:21

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!