From b83ece8b0583093ea1692af4bcf84f0fb8f53066 Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Fri, 16 Dec 2011 23:47:32 -0800 Subject: [PATCH] ENH: Allow choice between 4 and 8 neighbor mode. Improve documentation. --- skimage/morphology/ccomp.pyx | 55 +++++++++++++++++++++----- skimage/morphology/tests/test_ccomp.py | 10 +++++ 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/skimage/morphology/ccomp.pyx b/skimage/morphology/ccomp.pyx index 54585f3a..b1fdc828 100644 --- a/skimage/morphology/ccomp.pyx +++ b/skimage/morphology/ccomp.pyx @@ -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) diff --git a/skimage/morphology/tests/test_ccomp.py b/skimage/morphology/tests/test_ccomp.py index 5bf4cfdc..04c21feb 100644 --- a/skimage/morphology/tests/test_ccomp.py +++ b/skimage/morphology/tests/test_ccomp.py @@ -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()