Scipy标签的邻域

2 投票
1 回答
811 浏览
提问于 2025-04-17 09:53

我有一个用 scipy.ndimage.measurements.label 标记的对象数组,叫做 Labels。还有另一个数组 Data,里面存的是和 Labels 相关的东西。我想创建一个第三个数组 Neighbourhoods,用来表示离某个点 x,y 最近的标签是 L

给定 LabelsData,我该如何使用 python/numpy/scipy 来得到 Neighbourhoods 呢?

Labels = array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                [0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
                [0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
                [0, 1, 1, 1, 1, 0, 0, 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, 2, 2, 2, 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]] )

Data = array([[1, 1, 1, 1, 1, 1, 2, 3, 4, 5],
              [1, 0, 0, 0, 0, 1, 2, 3, 4, 5],
              [1, 0, 0, 0, 0, 1, 2, 3, 4, 4],
              [1, 0, 0, 0, 0, 1, 2, 3, 3, 3],
              [1, 0, 0, 0, 0, 1, 2, 2, 2, 2],
              [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
              [2, 2, 2, 2, 2, 1, 0, 0, 0, 1],
              [3, 3, 3, 3, 2, 1, 0, 0, 0, 1],
              [4, 4, 4, 3, 2, 1, 0, 0, 0, 1],
              [5, 5, 4, 3, 2, 1, 1, 1, 1, 1]] )

Neighbourhoods = array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                        [1, 0, 0, 0, 0, 1, 1, 1, 1, 1],
                        [1, 0, 0, 0, 0, 1, 1, 1, 0, 2],
                        [1, 0, 0, 0, 0, 1, 1, 0, 2, 2],
                        [1, 0, 0, 0, 0, 1, 0, 2, 2, 2],
                        [1, 1, 1, 1, 1, 0, 2, 2, 2, 2],
                        [1, 1, 1, 1, 0, 2, 0, 0, 0, 2],
                        [1, 1, 1, 0, 2, 2, 0, 0, 0, 2],
                        [1, 1, 0, 2, 2, 2, 0, 0, 0, 2],
                        [1, 1, 2, 2, 2, 2, 2, 2, 2, 2]] )

注意:我不太确定如果有多个最近的标签该怎么处理,所以在上面的 Neighbourhoods 中用了零。

1 个回答

2

正如David Zaslavsky所建议的,这个任务适合用Voronoi图来解决。这里有一个用numpy实现的例子:http://blancosilva.wordpress.com/2010/12/15/image-processing-with-numpy-scipy-and-matplotlibs-in-sage/

相关的函数是scipy.ndimage.distance_transform_edt。这个函数有一个return_indices的选项,可以用来做你需要的事情(同时也可以计算原始的距离(在你的例子中是data))。

举个例子:

import numpy as np
from scipy.ndimage import distance_transform_edt

labels = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                  [0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
                  [0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
                  [0, 1, 1, 1, 1, 0, 0, 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, 2, 2, 2, 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]] )
i, j = distance_transform_edt(labels == 0, return_distances=False, 
                              return_indices=True) 
neighborhoods = labels[i,j]
print neighborhoods

这样就会得到:

array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 2],
       [1, 1, 1, 1, 1, 1, 1, 1, 2, 2],
       [1, 1, 1, 1, 1, 1, 1, 2, 2, 2],
       [1, 1, 1, 1, 1, 1, 2, 2, 2, 2],
       [1, 1, 1, 1, 1, 2, 2, 2, 2, 2],
       [1, 1, 1, 1, 2, 2, 2, 2, 2, 2],
       [1, 1, 1, 2, 2, 2, 2, 2, 2, 2],
       [1, 1, 2, 2, 2, 2, 2, 2, 2, 2]])

撰写回答