mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-19 11:27:45 +08:00
ENH: Cleanups as suggested by Tony.
This commit is contained in:
@@ -16,63 +16,64 @@ See also:
|
||||
Paper LBNL-56864, 2005,
|
||||
Lawrence Berkeley National Laboratory
|
||||
(University of California),
|
||||
http://repositories.cdlib.org/lbnl/LBNL-56864.
|
||||
http://repositories.cdlib.org/lbnl/LBNL-56864
|
||||
|
||||
"""
|
||||
|
||||
# Tree operations implemented by an array as described in Wu et al.
|
||||
# The term "forest" is used to indicate an array that stores one or more trees
|
||||
|
||||
DTYPE = np.int
|
||||
ctypedef np.int_t DTYPE_t
|
||||
|
||||
cdef DTYPE_t find_root(np.int_t *work, np.int_t n):
|
||||
cdef DTYPE_t find_root(np.int_t *forest, np.int_t n):
|
||||
"""Find the root of node n.
|
||||
|
||||
"""
|
||||
cdef np.int_t root = n
|
||||
while (work[root] < root):
|
||||
root = work[root]
|
||||
while (forest[root] < root):
|
||||
root = forest[root]
|
||||
return root
|
||||
|
||||
cdef set_root(np.int_t *work, np.int_t n, np.int_t root):
|
||||
cdef set_root(np.int_t *forest, np.int_t n, np.int_t root):
|
||||
"""
|
||||
Set all nodes on a path to point to new_root.
|
||||
|
||||
"""
|
||||
cdef np.int_t j
|
||||
while (work[n] < n):
|
||||
j = work[n]
|
||||
work[n] = root
|
||||
while (forest[n] < n):
|
||||
j = forest[n]
|
||||
forest[n] = root
|
||||
n = j
|
||||
|
||||
work[n] = root
|
||||
forest[n] = root
|
||||
|
||||
|
||||
cdef join_trees(np.int_t *work, np.int_t n, np.int_t m):
|
||||
cdef join_trees(np.int_t *forest, np.int_t n, np.int_t m):
|
||||
"""Join two trees containing nodes n and m.
|
||||
|
||||
"""
|
||||
cdef np.int_t root = find_root(work, n)
|
||||
cdef np.int_t root = find_root(forest, n)
|
||||
cdef np.int_t root_m
|
||||
|
||||
if (n != m):
|
||||
root_m = find_root(work, m)
|
||||
root_m = find_root(forest, m)
|
||||
|
||||
if (root > root_m):
|
||||
root = root_m
|
||||
|
||||
set_root(work, n, root)
|
||||
set_root(work, m, root)
|
||||
set_root(forest, n, root)
|
||||
set_root(forest, m, root)
|
||||
|
||||
cdef link_bg(np.int_t *work, np.int_t n, np.int_t *background_node):
|
||||
cdef link_bg(np.int_t *forest, np.int_t n, np.int_t *background_node):
|
||||
"""
|
||||
Link a node to the background node.
|
||||
|
||||
"""
|
||||
if background_node[0] == -1:
|
||||
if background_node[0] == -999:
|
||||
background_node[0] = n
|
||||
|
||||
join_trees(work, n, background_node[0])
|
||||
join_trees(forest, n, background_node[0])
|
||||
|
||||
# Connected components search as described in Fiorio et al.
|
||||
|
||||
@@ -139,16 +140,16 @@ def label(np.ndarray[DTYPE_t, ndim=2] input,
|
||||
cdef np.int_t cols = input.shape[1]
|
||||
|
||||
cdef np.ndarray[DTYPE_t, ndim=2] data = input.copy()
|
||||
cdef np.ndarray[DTYPE_t, ndim=2] work
|
||||
cdef np.ndarray[DTYPE_t, ndim=2] forest
|
||||
|
||||
work = np.arange(data.size, dtype=DTYPE).reshape((rows, cols))
|
||||
forest = np.arange(data.size, dtype=DTYPE).reshape((rows, cols))
|
||||
|
||||
cdef np.int_t *work_p = <np.int_t*>work.data
|
||||
cdef np.int_t *forest_p = <np.int_t*>forest.data
|
||||
cdef np.int_t *data_p = <np.int_t*>data.data
|
||||
|
||||
cdef np.int_t i, j
|
||||
|
||||
cdef np.int_t background_node = -1
|
||||
cdef np.int_t background_node = -999
|
||||
|
||||
if neighbors != 4 and neighbors != 8:
|
||||
raise ValueError('Neighbors must be either 4 or 8.')
|
||||
@@ -156,41 +157,41 @@ def label(np.ndarray[DTYPE_t, ndim=2] input,
|
||||
# Initialize the first row
|
||||
for j in range(1, cols):
|
||||
if data[0, j] == background:
|
||||
link_bg(work_p, j, &background_node)
|
||||
link_bg(forest_p, j, &background_node)
|
||||
|
||||
if data[0, j] == data[0, j-1]:
|
||||
join_trees(work_p, j, j-1)
|
||||
join_trees(forest_p, j, j-1)
|
||||
|
||||
for i in range(1, rows):
|
||||
# Handle the first column
|
||||
if data[i, 0] == background:
|
||||
link_bg(work_p, i * cols, &background_node)
|
||||
link_bg(forest_p, i * cols, &background_node)
|
||||
|
||||
if data[i, 0] == data[i-1, 0]:
|
||||
join_trees(work_p, i*cols, (i-1)*cols)
|
||||
join_trees(forest_p, i*cols, (i-1)*cols)
|
||||
|
||||
if neighbors == 8:
|
||||
if data[i, 0] == data[i-1, 1]:
|
||||
join_trees(work_p, i*cols, (i-1)*cols + 1)
|
||||
join_trees(forest_p, i*cols, (i-1)*cols + 1)
|
||||
|
||||
for j in range(1, cols):
|
||||
if data[i, j] == background:
|
||||
link_bg(work_p, i * cols + j, &background_node)
|
||||
link_bg(forest_p, i * cols + j, &background_node)
|
||||
|
||||
if neighbors == 8:
|
||||
if data[i, j] == data[i-1, j-1]:
|
||||
join_trees(work_p, i*cols + j, (i-1)*cols + j - 1)
|
||||
join_trees(forest_p, i*cols + j, (i-1)*cols + j - 1)
|
||||
|
||||
if data[i, j] == data[i-1, j]:
|
||||
join_trees(work_p, i*cols + j, (i-1)*cols + j)
|
||||
join_trees(forest_p, i*cols + j, (i-1)*cols + j)
|
||||
|
||||
if neighbors == 8:
|
||||
if j < cols - 1:
|
||||
if data[i, j] == data[i - 1, j + 1]:
|
||||
join_trees(work_p, i*cols + j, (i-1)*cols + j + 1)
|
||||
join_trees(forest_p, i*cols + j, (i-1)*cols + j + 1)
|
||||
|
||||
if data[i, j] == data[i, j-1]:
|
||||
join_trees(work_p, i*cols + j, i*cols + j - 1)
|
||||
join_trees(forest_p, i*cols + j, i*cols + j - 1)
|
||||
|
||||
# Label output
|
||||
|
||||
@@ -199,10 +200,10 @@ def label(np.ndarray[DTYPE_t, ndim=2] input,
|
||||
for j in range(cols):
|
||||
if (i*cols + j) == background_node:
|
||||
data[i, j] = -1
|
||||
elif (i*cols + j) == work[i, j]:
|
||||
elif (i*cols + j) == forest[i, j]:
|
||||
data[i, j] = ctr
|
||||
ctr = ctr + 1
|
||||
else:
|
||||
data[i, j] = data_p[work[i, j]]
|
||||
data[i, j] = data_p[forest[i, j]]
|
||||
|
||||
return data
|
||||
|
||||
Reference in New Issue
Block a user