我有一个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循环中的循环非常慢,所以我必须找到另一个解决方案。有什么建议吗?
答案 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的大小,标签的数量,所用方法的时间结果以及这些函数),那将会很不错。