skimage.measure.label

skimage.measure.label(input, connectivity=None, return_num=False)

measure.label函数主要用来寻找图片中的连通区域,并对其进行标记

  • input: 要被标记的图片
  • connectivity: 1或者2,1的话默认通过四联通来寻找,2是八连通,如果None则使用八连通
  • return_num: 找到的连通区域的数量

返回

  • labels: 和input形状相同,数值是标记号,即一个被标记的图片
  • num: 标记的种类数,如果全是0则为背景,如果其他数字则代表有n个连通区域
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
from skimage import measure


x = np.array([[1,0,0,0,0],
[0,1,8,8,0],
[0,0,1,1,8],
[0,0,0,0,1]])
y1, n1 = measure.label(x, connectivity=1, return_num=True)
y2, n2 = measure.label(x, connectivity=2, return_num=True)
'''
y1
[[1 0 0 0 0]
[0 2 3 3 0]
[0 0 4 4 5]
[0 0 0 0 6]]
n1: 6

y2
[[1 0 0 0 0]
[0 1 2 2 0]
[0 0 1 1 2]
[0 0 0 0 1]]
n2: 2
'''

对于x中的1和8,本身就不属于同一类别,所以分开处理
对于1

  • 四联通:可以划分为4个不同连通域
  • 八连通:可以划分为一个连通域

对于8

  • 四联通:可以划分为2个不同连通域
  • 八连通:可以划分为一个连通域

skimage.measure.regionprops

上面的label函数一般与regionprops一起使用,此函数能提供每一个连通区域的属性列表,包括area,label等,下面通过例子来描述一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
properties = measure.regionprops(y2)  # 返回连通区域的属性
valid_label = set()
for prop in properties:
if prop.area >= 1: # 连通区域的所有像素和
valid_label.add(prop.label) # 连通区域的label


# 找到连通区域后,我们将不同的区域分别编码mask并输出
valid_label = np.array(list(valid_label))
one_hot_mask = (y2[None,:,:]==valid_label[:,None,None])
region_num = one_hot_mask.shape[0]
for i in range(region_num):
print(one_hot_mask[i].astype(np.int8))

'''
[[1 0 0 0 0]
[0 1 0 0 0]
[0 0 1 1 0]
[0 0 0 0 1]]

[[0 0 0 0 0]
[0 0 1 1 0]
[0 0 0 0 1]
[0 0 0 0 0]]
'''

如上所示,对于y2,他一共有两个连通域,我们分别对其输出,得到了每个区域的mask