ENH: Allow choice between 4 and 8 neighbor mode. Improve documentation.

This commit is contained in:
Stefan van der Walt
2011-12-16 23:47:32 -08:00
parent 6cd01885d3
commit b83ece8b05
2 changed files with 55 additions and 10 deletions
+45 -10
View File
@@ -66,16 +66,27 @@ cdef join_trees(np.int_t *work, np.int_t n, np.int_t m):
# Connected components search as described in Fiorio et al.
def label(np.ndarray[DTYPE_t, ndim=2] input):
def label(np.ndarray[DTYPE_t, ndim=2] input,
int neighbors=8):
"""Label connected regions of an integer array.
Connectivity is defined as two (8-connected) neighboring entries
having equal value.
Two pixels are connected when they are neighbors and have the same value.
They can be neighbors either in a 4- or 8-connected sense::
4-connectivity 8-connectivity
[ ] [ ] [ ] [ ]
| \ | /
[ ]--[ ]--[ ] [ ]--[ ]--[ ]
| / | \
[ ] [ ] [ ] [ ]
Parameters
----------
input : ndarray of dtype int
Image to label.
neighbors : {4, 8}, int
Whether to use 4- or 8-connectivity.
Returns
-------
@@ -83,6 +94,24 @@ def label(np.ndarray[DTYPE_t, ndim=2] input):
Labeled array, where all connected regions are assigned the
same integer value.
Examples
--------
>>> x = np.eye(3).astype(int)
>>> print x
[[1 0 0]
[0 1 0]
[0 0 1]]
>>> print m.label(x, neighbors=4)
[[0 1 1]
[2 3 1]
[2 2 4]]
>>> print m.label(x, neighbors=8)
[[0 1 1]
[1 0 1]
[1 1 0]]
"""
cdef np.int_t rows = input.shape[0]
cdef np.int_t cols = input.shape[1]
@@ -97,6 +126,9 @@ def label(np.ndarray[DTYPE_t, ndim=2] input):
cdef np.int_t i, j
if neighbors != 4 and neighbors != 8:
raise ValueError('Neighbors must be either 4 or 8.')
# Initialize the first row
for j in range(1, cols):
if data[0, j] == data[0, j-1]:
@@ -107,19 +139,22 @@ def label(np.ndarray[DTYPE_t, ndim=2] input):
if data[i, 0] == data[i-1, 0]:
join_trees(work_p, i*cols, (i-1)*cols)
if data[i, 0] == data[i-1, 1]:
join_trees(work_p, i*cols, (i-1)*cols + 1)
if neighbors == 8:
if data[i, 0] == data[i-1, 1]:
join_trees(work_p, i*cols, (i-1)*cols + 1)
for j in range(1, cols):
if data[i, j] == data[i-1, j-1]:
join_trees(work_p, i*cols + j, (i-1)*cols + j - 1)
if neighbors == 8:
if data[i, j] == data[i-1, j-1]:
join_trees(work_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)
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)
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)
if data[i, j] == data[i, j-1]:
join_trees(work_p, i*cols + j, i*cols + j - 1)
+10
View File
@@ -37,5 +37,15 @@ class TestConnectedComponents:
assert_array_equal(label(x),
x)
def test_4_vs_8(self):
x = np.array([[0, 1],
[1, 0]], dtype=int)
assert_array_equal(label(x, 4),
[[0, 1],
[2, 3]])
assert_array_equal(label(x, 8),
[[0, 1],
[1, 0]])
if __name__ == "__main__":
run_module_suite()