找到标记对象的平均位置和区域

时间:2015-01-24 10:33:55

标签: python image-processing numpy iteration labeling

我有一个2D标记的图像(numpy数组),每个标签代表一个对象。我必须找到物体的中心及其区域。我目前的解决方案:

centers = [np.mean(np.where(label_2d == i),1) for i in range(1,num_obj+1)]

surface_area = np.array([np.sum(label_2d == i) for i in range(1,num_obj+1)])

请注意,用于中心的label_2d与表面区域的{{1}}不同,因此我无法将两种操作组合在一起。我目前的代码大约要慢10到100倍。

在C ++中,我会迭代图像一次(2 for loops)并填充表格(数组),我将从中计算中心和表面区域。

因为for循环中的循环非常慢,所以我必须找到另一个解决方案。有什么建议吗?

1 个答案:

答案 0 :(得分:1)

您可以使用scipy.ndimage.measurements中的center_of_mass function作为第一个问题,然后使用np.bincount解决第二个问题。因为这些都在主流库中,所以它们将进行大量优化,因此您可以获得适当的速度增益。

示例:

>>> import numpy as np
>>> from scipy.ndimage.measurements import center_of_mass
>>> 
>>> a = np.zeros((10,10), dtype=np.int)
>>> # add some labels:
... a[3:5, 1:3] = 1
>>> a[7:9, 0:3] = 2
>>> a[5:6, 4:9] = 3
>>> print(a)
[[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 1 1 0 0 0 0 0 0 0]
 [0 1 1 0 0 0 0 0 0 0]
 [0 0 0 0 3 3 3 3 3 0]
 [0 0 0 0 0 0 0 0 0 0]
 [2 2 2 0 0 0 0 0 0 0]
 [2 2 2 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 0 0 0]]
>>> 
>>> num_obj = 3
>>> surface_areas = np.bincount(a.flat)[1:]
>>> centers = center_of_mass(a, labels=a, index=range(1, num_obj+1))
>>> print(surface_areas)
[4 6 5]
>>> print(centers)
[(3.5, 1.5), (7.5, 1.0), (5.0, 6.0)]

速度增益取决于输入数据的大小,因此我无法对此做出任何严肃的估计。如果您可以在评论中添加该信息(a的大小,标签的数量,所用方法的时间结果以及这些函数),那将会很不错。