2 #cython: cdivision=True
10 Christophe Fiorio and Jens Gustedt,
11 "Two linear time Union-Find strategies for image processing",
12 Theoretical Computer Science 154 (1996), pp. 165-181.
14 Kensheng Wu, Ekow Otoo and Arie Shoshani,
15 "Optimizing connected component labeling algorithms",
16 Paper LBNL-56864, 2005,
17 Lawrence Berkeley National Laboratory
18 (University of California),
19 http://repositories.cdlib.org/lbnl/LBNL-56864.
23 # Tree operations implemented by an array as described in Wu et al.
26 ctypedef np.int_t DTYPE_t
28 cdef DTYPE_t find_root(np.int_t *work, np.int_t n):
29 """Find the root of node n.
32 cdef np.int_t root = n
33 while (work[root] < root):
37 cdef set_root(np.int_t *work, np.int_t n, np.int_t root):
39 Set all nodes on a path to point to new_root.
51 cdef join_trees(np.int_t *work, np.int_t n, np.int_t m):
52 """Join two trees containing nodes n and m.
55 cdef np.int_t root = find_root(work, n)
59 root_m = find_root(work, m)
64 set_root(work, n, root)
65 set_root(work, m, root)
67 # Connected components search as described in Fiorio et al.
69 def label(np.ndarray[DTYPE_t, ndim=2] input):
70 """Label connected regions of an integer array.
73 cdef np.int_t rows = input.shape[0]
74 cdef np.int_t cols = input.shape[1]
76 cdef np.ndarray[DTYPE_t, ndim=2] data = input.copy()
77 cdef np.ndarray[DTYPE_t, ndim=2] work
79 work = np.arange(data.size, dtype=DTYPE).reshape((rows, cols))
81 cdef np.int_t *work_p = <np.int_t*>work.data
82 cdef np.int_t *data_p = <np.int_t*>data.data
86 # Initialize the first row
87 for j in range(1, cols):
88 if data[0, j] == data[0, j-1]:
89 join_trees(work_p, j, j-1)
91 for i in range(1, rows):
92 # Handle the first column
93 if data[i, 0] == data[i-1, 0]:
94 join_trees(work_p, i*cols, (i-1)*cols)
96 if data[i, 0] == data[i-1, 1]:
97 join_trees(work_p, i*cols, (i-1)*cols + 1)
99 for j in range(1, cols):
100 if data[i, j] == data[i-1, j-1]:
101 join_trees(work_p, i*cols + j, (i-1)*cols + j - 1)
103 if data[i, j] == data[i-1, j]:
104 join_trees(work_p, i*cols + j, (i-1)*cols + j)
107 if data[i, j] == data[i - 1, j + 1]:
108 join_trees(work_p, i*cols + j, (i-1)*cols + j + 1)
110 if data[i, j] == data[i, j-1]:
111 join_trees(work_p, i*cols + j, i*cols + j - 1)
115 cdef np.int_t ctr = 0
116 for i in range(rows):
117 for j in range(cols):
118 if (i*cols + j) == work[i, j]:
122 data[i, j] = data_p[work[i, j]]