python
主页 > 脚本 > python >

Python实现统计图像连通域

2023-12-03 | 佚名 | 点击:

数组统计函数

ndimage提供一系列函数,可以计算标注后的数组的相关特征,比如最值、均值、均方根等。

下列函数,如果未作其他说明,那么就有3个参数,分别是(input, labels=None, index=None),其中input为输入数组;labels为input的标签,形状和input相同;index为整数或者整数数列,为用于计算的label。

函数 物理量 函数 物理量
mean 平均值 center_of_mass 质心
maximum 最大值 maximum_position 最大值位置
minimum 最小值 minimum_position 最小值位置
median 中位数 extrema 最大值、最小值,及其位置
sum_labels 求和    
variance 方差 standard_deviation 标准差

示例如下

1

2

3

4

5

6

7

8

9

10

11

12

import numpy as np

import scipy.ndimage as sn

 

x = np.random.randint(10, size=(3,3))

print(x)

'''

[[0 3 5]

 [9 3 1]

 [1 5 7]]

'''

sn.center_of_mass(x)    # (1.1470588235294117, 1.088235294117647)

sn.extrema(x)           # (0, 9, (0, 0), (1, 0))

连通域标记

通过label函数,可以对数组中的连通区域进行标注,效果如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

from scipy.ndimage import label

import numpy as np

a = np.array([[0,0,1,1,0,0],

              [0,0,0,1,0,0],

              [1,1,0,0,1,0],

              [0,0,0,1,0,0]])

labels, N = label(a)

print(labels)

'''

[[0 0 1 1 0 0]

 [0 0 0 1 0 0]

 [2 2 0 0 3 0]

 [0 0 0 4 0 0]]

'''

print(N)    4

在label函数中,还有一个用于规范何为“连通”的参数,即structure,其数据类型为二值数组,其维度与输入的input相同。

在上面的示例中,连通域1,3,4尽管没有上下左右的联系,但在对角线上是有交集的,通过调整structure参数,可以提供一种将这三个区域连在一起的连通域方案。

1

2

3

4

5

6

7

8

9

stru = np.ones([3,3])

bLab, bN = label(a, stru)

print(bLab)

‘'‘

[[0 0 1 1 0 0]

 [0 0 0 1 0 0]

 [2 2 0 0 1 0]

 [0 0 0 1 0 0]]

'‘'

可见,这次只选出了两组连通域。

连通域统计

前面提到的所有统计函数,形参都有三个,分别是input, labels, index,其中input为输入数组,labels为将要处理的连通域,index为准备处理的连通域序号。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

np.random.seed(42)

test = np.random.rand(5,5)

test[test<0.8] = 0

labels, N = sn.label(test)

print(N)        # 2

print(labels)    #

‘'‘

[[0 1 0 0 0]

 [0 0 2 0 0]

 [0 2 2 0 0]

 [0 0 0 0 0]

 [0 0 0 0 0]]

'‘'

print(test)

‘'‘

[[0.         0.95071431 0.         0.         0.        ]

 [0.         0.         0.86617615 0.         0.        ]

 [0.         0.96990985 0.83244264 0.         0.        ]

 [0.         0.         0.         0.         0.        ]

 [0.         0.         0.         0.         0.        ]]

'‘'

接下来通过连通域统计函数,针对某个连通域进行计算

1

2

3

4

5

6

>>> sn.mean(test, labels, 1)

0.9507143064099162

>>> sn.mean(test, labels, 2)

0.8895095462457837

>>> sn.mean(test, labels, 0)

0.0

当index=1时,会找出labels中为1的位置,然后把test中这些位置的元素求平均。

原文链接:
相关文章
最新更新