From e66d73ac7c67e690e4747cba7b50610ebb9ee3cf Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Sat, 18 May 2013 14:32:24 +0530 Subject: [PATCH 01/24] Added convex_hull_object function --- skimage/morphology/convex_hull.py | 50 +++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 08ff0e04..d024ca02 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -1,9 +1,11 @@ -__all__ = ['convex_hull_image'] +__all__ = ['convex_hull_image', 'convex_hull_object'] import numpy as np from ._pnpoly import grid_points_inside_poly from ._convex_hull import possible_hull - +from .selem import square +from skimage.morphology import label, dilation +from skimage.util import img_as_ubyte, img_as_bool def convex_hull_image(image): """Compute the convex hull image of a binary image. @@ -14,21 +16,19 @@ def convex_hull_image(image): Parameters ---------- image : ndarray - Binary input image. This array is cast to bool before processing. + Binary input image. This array is cast to bool before processing. Returns ------- - hull : ndarray of uint8 - Binary image with pixels in convex hull set to 255. + hull : ndarray of bool + Binary image with pixels in convex hull set to True. References ---------- .. [1] http://blogs.mathworks.com/steve/2011/10/04/binary-image-convex-hull-algorithm-notes/ - """ image = image.astype(bool) - # Here we do an optimisation by choosing only pixels that are # the starting or ending pixel of a row or column. This vastly # limits the number of coordinates to examine for the virtual @@ -38,10 +38,10 @@ def convex_hull_image(image): # Add a vertex for the middle of each pixel edge coords_corners = np.empty((N * 4, 2)) - for i, (x_offset, y_offset) in enumerate(zip((0, 0, -0.5, 0.5), + for i, (x_offset, y_offset) in enumerate(zip((0, 0, -0.5, 0.5), (-0.5, 0.5, 0, 0))): coords_corners[i * N:(i + 1) * N] = coords + [x_offset, y_offset] - + coords = coords_corners try: @@ -64,3 +64,35 @@ def convex_hull_image(image): mask = grid_points_inside_poly(image.shape[:2], v) return mask + +def convex_hull_object(image): + """Compute the convex hull image of individual objects in a binary image. + + The convex hull is the set of pixels included in the smallest convex + polygon that surround all white pixels in the input image. + + Parameters + ---------- + image : ndarray + Binary input image. + + Returns + ------- + hull : ndarray of bool + Binary image with pixels in convex hull set to True. + """ + + # Add 1 to the output of label() so as to make the + # background value 0 rather than -1 + labeled_im = label(image, neighbors=8, background=0) + 1 + convex_obj = np.zeros(image.shape, dtype=bool) + mask = np.zeros(image.shape, dtype=np.uint8) + convex_img = np.zeros(image.shape, dtype=bool) + + for i in range(1, labeled_im.max()+1): + mask[:] = i + mask = img_as_ubyte(np.logical_not(np.bitwise_xor(labeled_im, mask))) + convex_obj = convex_hull_image(mask) + convex_img = np.logical_or(convex_img, convex_obj) + + return convex_img From d63ee467eeaf1ef26fd14f85fb2a5310e6f9fd25 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Sat, 18 May 2013 14:38:45 +0530 Subject: [PATCH 02/24] Trailing whitespace --- skimage/morphology/convex_hull.py | 1 + 1 file changed, 1 insertion(+) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index d024ca02..9bb65fbb 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -96,3 +96,4 @@ def convex_hull_object(image): convex_img = np.logical_or(convex_img, convex_obj) return convex_img + \ No newline at end of file From 6fcaaee8077ad950861cf4c4050fcad04176f470 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Tue, 21 May 2013 22:54:47 +0530 Subject: [PATCH 03/24] Added the note in docstring as suggested by Josh --- skimage/morphology/convex_hull.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 9bb65fbb..b904ece7 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -71,6 +71,14 @@ def convex_hull_object(image): The convex hull is the set of pixels included in the smallest convex polygon that surround all white pixels in the input image. + Note that in this function individual masks are generated using the label + function in ``skimage.morphology``. ``convex_hull_image`` is applied on the + extracted object and combined with other hulls using logical OR. This can + however lead to overlapping of hulls, producing inaccurate results. In this + case it is advisable to create a single mask of the objects who's hulls + would otherwise overlap. The ``convex_hull_image`` can be applied on the + extracted objects, rather than individually. + Parameters ---------- image : ndarray @@ -96,4 +104,3 @@ def convex_hull_object(image): convex_img = np.logical_or(convex_img, convex_obj) return convex_img - \ No newline at end of file From 48932b6bb2901537c0a4e275635fd2bb743408b5 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Tue, 21 May 2013 22:56:32 +0530 Subject: [PATCH 04/24] Update convex_hull.py --- skimage/morphology/convex_hull.py | 1 + 1 file changed, 1 insertion(+) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index b904ece7..5c2ed8a2 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -104,3 +104,4 @@ def convex_hull_object(image): convex_img = np.logical_or(convex_img, convex_obj) return convex_img + From db84262ba321dc0f995b4e9f326a22f39013b1d0 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Tue, 21 May 2013 23:47:30 +0530 Subject: [PATCH 05/24] Note and relative import --- skimage/morphology/convex_hull.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 5c2ed8a2..8c2c6113 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -5,7 +5,7 @@ from ._pnpoly import grid_points_inside_poly from ._convex_hull import possible_hull from .selem import square from skimage.morphology import label, dilation -from skimage.util import img_as_ubyte, img_as_bool +from ..util import img_as_ubyte, img_as_bool def convex_hull_image(image): """Compute the convex hull image of a binary image. @@ -71,14 +71,6 @@ def convex_hull_object(image): The convex hull is the set of pixels included in the smallest convex polygon that surround all white pixels in the input image. - Note that in this function individual masks are generated using the label - function in ``skimage.morphology``. ``convex_hull_image`` is applied on the - extracted object and combined with other hulls using logical OR. This can - however lead to overlapping of hulls, producing inaccurate results. In this - case it is advisable to create a single mask of the objects who's hulls - would otherwise overlap. The ``convex_hull_image`` can be applied on the - extracted objects, rather than individually. - Parameters ---------- image : ndarray @@ -88,6 +80,16 @@ def convex_hull_object(image): ------- hull : ndarray of bool Binary image with pixels in convex hull set to True. + + Note + ---- + In this function individual masks are generated using the label + function in ``skimage.morphology``. ``convex_hull_image`` is applied on the + extracted object and combined with other hulls using logical OR. This can + however lead to overlapping of hulls, producing inaccurate results. In this + case it is advisable to create a single mask of the objects who's hulls + would otherwise overlap. The ``convex_hull_image`` can be applied on the + extracted objects, rather than individually. """ # Add 1 to the output of label() so as to make the From 20ca89d8b8e6d097959711e8a10ebcaaa34d1825 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 22 May 2013 00:01:42 +0530 Subject: [PATCH 06/24] Added unit test for convex_hull_object function in test_convex_hull.py --- skimage/morphology/tests/test_convex_hull.py | 23 +++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/skimage/morphology/tests/test_convex_hull.py b/skimage/morphology/tests/test_convex_hull.py index 9ab514d0..1a8b39ef 100644 --- a/skimage/morphology/tests/test_convex_hull.py +++ b/skimage/morphology/tests/test_convex_hull.py @@ -1,7 +1,7 @@ import numpy as np from numpy.testing import assert_array_equal from numpy.testing.decorators import skipif -from skimage.morphology import convex_hull_image +from skimage.morphology import convex_hull_image, convex_hull_object from skimage.morphology._convex_hull import possible_hull try: @@ -65,5 +65,26 @@ def test_possible_hull(): ph = possible_hull(image) assert_array_equal(ph, expected) + +def test_object(): + image = np.array( + [[1, 0, 1, 0, 0, 0, 0, 0, 0], + [1, 0, 1, 0, 1, 0, 0, 0, 1], + [0, 1, 0, 0, 0, 1, 0, 0, 1], + [0, 0, 0, 0, 0, 0, 1, 0, 1], + [0, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=bool) + + expected = np.array( + [[1, 1, 1, 0, 0, 0, 0, 0, 0], + [1, 1, 1, 0, 1, 1, 1, 1, 1], + [0, 1, 0, 0, 0, 1, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 1, 1, 1], + [0, 0, 0, 0, 0, 0, 0, 1, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=bool) + + assert_array_equal(convex_hull_object(image), expected) + + if __name__ == "__main__": np.testing.run_module_suite() From 24192856025c54e5ad8c3631f00115b13c30f5c2 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 22 May 2013 00:05:49 +0530 Subject: [PATCH 07/24] Unit tests added --- skimage/morphology/tests/test_convex_hull.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/morphology/tests/test_convex_hull.py b/skimage/morphology/tests/test_convex_hull.py index 1a8b39ef..9b948237 100644 --- a/skimage/morphology/tests/test_convex_hull.py +++ b/skimage/morphology/tests/test_convex_hull.py @@ -65,7 +65,7 @@ def test_possible_hull(): ph = possible_hull(image) assert_array_equal(ph, expected) - +@skipif(not scipy_spatial) def test_object(): image = np.array( [[1, 0, 1, 0, 0, 0, 0, 0, 0], From 4ff28908d8b5336623809fda29c0ba4eeabab86a Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 22 May 2013 00:07:12 +0530 Subject: [PATCH 08/24] Resolve fast forward --- skimage/morphology/convex_hull.py | 1 - skimage/morphology/tests/test_convex_hull.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 8c2c6113..3594def8 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -106,4 +106,3 @@ def convex_hull_object(image): convex_img = np.logical_or(convex_img, convex_obj) return convex_img - diff --git a/skimage/morphology/tests/test_convex_hull.py b/skimage/morphology/tests/test_convex_hull.py index 9b948237..8b499709 100644 --- a/skimage/morphology/tests/test_convex_hull.py +++ b/skimage/morphology/tests/test_convex_hull.py @@ -65,6 +65,7 @@ def test_possible_hull(): ph = possible_hull(image) assert_array_equal(ph, expected) + @skipif(not scipy_spatial) def test_object(): image = np.array( From 1814cc44ca2a3f8dd388f4265ecfdabee1e93bff Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 22 May 2013 00:25:46 +0530 Subject: [PATCH 09/24] Remove trailing whitespace --- skimage/morphology/convex_hull.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 3594def8..6cb9f653 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -38,7 +38,7 @@ def convex_hull_image(image): # Add a vertex for the middle of each pixel edge coords_corners = np.empty((N * 4, 2)) - for i, (x_offset, y_offset) in enumerate(zip((0, 0, -0.5, 0.5), + for i, (x_offset, y_offset) in enumerate(zip((0, 0, -0.5, 0.5), (-0.5, 0.5, 0, 0))): coords_corners[i * N:(i + 1) * N] = coords + [x_offset, y_offset] From b6d15c91c7b9a04f2edaf5635da986a3f4cb0713 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 22 May 2013 00:26:26 +0530 Subject: [PATCH 10/24] Remove trailing whitespace --- skimage/morphology/convex_hull.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 6cb9f653..24b45db2 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -41,7 +41,7 @@ def convex_hull_image(image): for i, (x_offset, y_offset) in enumerate(zip((0, 0, -0.5, 0.5), (-0.5, 0.5, 0, 0))): coords_corners[i * N:(i + 1) * N] = coords + [x_offset, y_offset] - + coords = coords_corners try: From 7836e2b0122d269a0955a2316665e5cce98368c2 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 22 May 2013 00:34:35 +0530 Subject: [PATCH 11/24] Using labeled_im == i --- skimage/morphology/convex_hull.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 24b45db2..1b63f176 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -94,15 +94,13 @@ def convex_hull_object(image): # Add 1 to the output of label() so as to make the # background value 0 rather than -1 - labeled_im = label(image, neighbors=8, background=0) + 1 + labeled_im = label(image, neighbors=8, background=0) convex_obj = np.zeros(image.shape, dtype=bool) mask = np.zeros(image.shape, dtype=np.uint8) convex_img = np.zeros(image.shape, dtype=bool) - for i in range(1, labeled_im.max()+1): - mask[:] = i - mask = img_as_ubyte(np.logical_not(np.bitwise_xor(labeled_im, mask))) - convex_obj = convex_hull_image(mask) + for i in range(0, labeled_im.max()+1): + convex_obj = convex_hull_image(labeled_im == i) convex_img = np.logical_or(convex_img, convex_obj) return convex_img From 9797ae0e724683094f489599894555d5871bfb34 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 22 May 2013 00:42:47 +0530 Subject: [PATCH 12/24] Blank at the end of docstring --- skimage/morphology/convex_hull.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 1b63f176..e8bb8181 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -26,6 +26,7 @@ def convex_hull_image(image): References ---------- .. [1] http://blogs.mathworks.com/steve/2011/10/04/binary-image-convex-hull-algorithm-notes/ + """ image = image.astype(bool) @@ -90,6 +91,7 @@ def convex_hull_object(image): case it is advisable to create a single mask of the objects who's hulls would otherwise overlap. The ``convex_hull_image`` can be applied on the extracted objects, rather than individually. + """ # Add 1 to the output of label() so as to make the From 14302318ab57c30af954180908f680c363547dba Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 22 May 2013 11:54:07 +0530 Subject: [PATCH 13/24] Add convex_hull_object in __init__.py --- skimage/morphology/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/morphology/__init__.py b/skimage/morphology/__init__.py index 2cbfcd37..aec60ea2 100644 --- a/skimage/morphology/__init__.py +++ b/skimage/morphology/__init__.py @@ -8,7 +8,7 @@ from .selem import square, rectangle, diamond, disk, cube, octahedron, ball from .ccomp import label from .watershed import watershed, is_local_maximum from ._skeletonize import skeletonize, medial_axis -from .convex_hull import convex_hull_image +from .convex_hull import convex_hull_image, convex_hull_object from .greyreconstruct import reconstruction from .misc import remove_small_objects From e49994976dee24fc6756f96c5f8cd49887e17740 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Thu, 23 May 2013 21:39:28 +0530 Subject: [PATCH 14/24] Minor changes --- skimage/morphology/convex_hull.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index e8bb8181..5b8f2c4c 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -3,9 +3,8 @@ __all__ = ['convex_hull_image', 'convex_hull_object'] import numpy as np from ._pnpoly import grid_points_inside_poly from ._convex_hull import possible_hull -from .selem import square -from skimage.morphology import label, dilation -from ..util import img_as_ubyte, img_as_bool +from skimage.morphology import label + def convex_hull_image(image): """Compute the convex hull image of a binary image. @@ -66,6 +65,7 @@ def convex_hull_image(image): return mask + def convex_hull_object(image): """Compute the convex hull image of individual objects in a binary image. @@ -94,11 +94,8 @@ def convex_hull_object(image): """ - # Add 1 to the output of label() so as to make the - # background value 0 rather than -1 labeled_im = label(image, neighbors=8, background=0) convex_obj = np.zeros(image.shape, dtype=bool) - mask = np.zeros(image.shape, dtype=np.uint8) convex_img = np.zeros(image.shape, dtype=bool) for i in range(0, labeled_im.max()+1): From 1ef98dae8c1cabbdc7324109b9a312ac23e7bc40 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Thu, 23 May 2013 23:24:17 +0530 Subject: [PATCH 15/24] Ability to choose the type of connectivity and ValueError --- skimage/morphology/convex_hull.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 5b8f2c4c..b6e1b43a 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -66,7 +66,7 @@ def convex_hull_image(image): return mask -def convex_hull_object(image): +def convex_hull_object(image, neighbors=8): """Compute the convex hull image of individual objects in a binary image. The convex hull is the set of pixels included in the smallest convex @@ -76,6 +76,8 @@ def convex_hull_object(image): ---------- image : ndarray Binary input image. + neighbors : {4, 8}, int + Whether to use 4- or 8-connectivity. Returns ------- @@ -94,7 +96,10 @@ def convex_hull_object(image): """ - labeled_im = label(image, neighbors=8, background=0) + if neighbors != 4 and neighbors != 8: + raise ValueError('Neighbors must be either 4 or 8.') + + labeled_im = label(image, neighbors, background=0) convex_obj = np.zeros(image.shape, dtype=bool) convex_img = np.zeros(image.shape, dtype=bool) From a2a40de83ea01c3959f5760e88dfad6ae5cf3cd9 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Fri, 24 May 2013 00:05:44 +0530 Subject: [PATCH 16/24] Test for the two neighborhood values --- skimage/morphology/convex_hull.py | 2 +- skimage/morphology/tests/test_convex_hull.py | 42 ++++++++++++++------ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index b6e1b43a..d092b122 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -66,7 +66,7 @@ def convex_hull_image(image): return mask -def convex_hull_object(image, neighbors=8): +def convex_hull_object(image, neighbors): """Compute the convex hull image of individual objects in a binary image. The convex hull is the set of pixels included in the smallest convex diff --git a/skimage/morphology/tests/test_convex_hull.py b/skimage/morphology/tests/test_convex_hull.py index 8b499709..67d77a31 100644 --- a/skimage/morphology/tests/test_convex_hull.py +++ b/skimage/morphology/tests/test_convex_hull.py @@ -69,23 +69,41 @@ def test_possible_hull(): @skipif(not scipy_spatial) def test_object(): image = np.array( - [[1, 0, 1, 0, 0, 0, 0, 0, 0], - [1, 0, 1, 0, 1, 0, 0, 0, 1], - [0, 1, 0, 0, 0, 1, 0, 0, 1], - [0, 0, 0, 0, 0, 0, 1, 0, 1], - [0, 0, 0, 0, 0, 0, 0, 1, 0], + [[0, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 1, 1, 1, 0, 0, 1, 0, 1], + [1, 0, 0, 0, 0, 0, 0, 1, 0], + [1, 0, 0, 0, 0, 0, 1, 0, 1], + [1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=bool) - expected = np.array( - [[1, 1, 1, 0, 0, 0, 0, 0, 0], - [1, 1, 1, 0, 1, 1, 1, 1, 1], - [0, 1, 0, 0, 0, 1, 1, 1, 1], - [0, 0, 0, 0, 0, 0, 1, 1, 1], - [0, 0, 0, 0, 0, 0, 0, 1, 0], + expected4 = np.array( + [[0, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 1, 0, 0, 0, 0, 0, 0, 0], + [1, 1, 1, 0, 0, 0, 0, 0, 0], + [1, 1, 1, 1, 0, 0, 1, 0, 1], + [1, 1, 1, 0, 0, 0, 0, 1, 0], + [1, 1, 0, 0, 0, 0, 1, 0, 1], + [1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=bool) - assert_array_equal(convex_hull_object(image), expected) + assert_array_equal(convex_hull_object(image, 4), expected4) + expected8 = np.array( + [[0, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0, 0], + [1, 1, 0, 0, 0, 0, 0, 0, 0], + [1, 1, 1, 0, 0, 0, 0, 0, 0], + [1, 1, 1, 1, 0, 0, 1, 1, 1], + [1, 1, 1, 0, 0, 0, 1, 1, 1], + [1, 1, 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]], dtype=bool) + + assert_array_equal(convex_hull_object(image, 8), expected8) if __name__ == "__main__": np.testing.run_module_suite() From bec3b4e324f78c8bec4b22a59e260cb99fd723a1 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Fri, 24 May 2013 00:23:33 +0530 Subject: [PATCH 17/24] Note rewritten --- skimage/morphology/convex_hull.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index d092b122..1c46c43f 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -66,7 +66,7 @@ def convex_hull_image(image): return mask -def convex_hull_object(image, neighbors): +def convex_hull_object(image, neighbors=8): """Compute the convex hull image of individual objects in a binary image. The convex hull is the set of pixels included in the smallest convex @@ -86,13 +86,12 @@ def convex_hull_object(image, neighbors): Note ---- - In this function individual masks are generated using the label - function in ``skimage.morphology``. ``convex_hull_image`` is applied on the - extracted object and combined with other hulls using logical OR. This can - however lead to overlapping of hulls, producing inaccurate results. In this - case it is advisable to create a single mask of the objects who's hulls - would otherwise overlap. The ``convex_hull_image`` can be applied on the - extracted objects, rather than individually. + This function uses the label function defined in ccomp.pyx. Using this + convex_hull_image of individual objects are extracted and combined using + logical OR. However, OR operation may lead to overlapping of hulls, thus + giving inaccurate results. In such a case, it would be helpful for users + to use the above approach to create a mask of several objects (whose hulls + overlap). """ From ab2a82746ff001b08c0a28298025cc8d4d3b242b Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Fri, 24 May 2013 00:25:21 +0530 Subject: [PATCH 18/24] Endline --- skimage/morphology/convex_hull.py | 1 + 1 file changed, 1 insertion(+) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 1c46c43f..a6321216 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -107,3 +107,4 @@ def convex_hull_object(image, neighbors=8): convex_img = np.logical_or(convex_img, convex_obj) return convex_img + From 8bc70cd2ea3285cb6f31d795d3a51c1626443b65 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Sat, 25 May 2013 19:10:50 +0530 Subject: [PATCH 19/24] Added test for checking ValueError --- skimage/morphology/tests/test_convex_hull.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/skimage/morphology/tests/test_convex_hull.py b/skimage/morphology/tests/test_convex_hull.py index 67d77a31..075762ed 100644 --- a/skimage/morphology/tests/test_convex_hull.py +++ b/skimage/morphology/tests/test_convex_hull.py @@ -1,5 +1,5 @@ import numpy as np -from numpy.testing import assert_array_equal +from numpy.testing import assert_array_equal, assert_raises from numpy.testing.decorators import skipif from skimage.morphology import convex_hull_image, convex_hull_object from skimage.morphology._convex_hull import possible_hull @@ -105,5 +105,7 @@ def test_object(): assert_array_equal(convex_hull_object(image, 8), expected8) + assert_raises(ValueError, convex_hull_object, image, 7) + if __name__ == "__main__": np.testing.run_module_suite() From 054360f834fb1396e50bc1b4fcb1fc33da47d84b Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Sat, 25 May 2013 19:29:54 +0530 Subject: [PATCH 20/24] Note re-worded --- skimage/morphology/convex_hull.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index a6321216..06a6e710 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -86,12 +86,11 @@ def convex_hull_object(image, neighbors=8): Note ---- - This function uses the label function defined in ccomp.pyx. Using this - convex_hull_image of individual objects are extracted and combined using - logical OR. However, OR operation may lead to overlapping of hulls, thus - giving inaccurate results. In such a case, it would be helpful for users - to use the above approach to create a mask of several objects (whose hulls - overlap). + This function uses skimage.morphology.label to define unique objects, + finds the convex hull of each using convex_hull_image, and combines + these regions with logical OR. Be aware the convex hulls of unconnected + objects may overlap in the result. If this is suspected, consider using + convex_hull_image on those objects together. """ From 390a6c664bc00f0507c3175e0249702d75435d8b Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Sun, 26 May 2013 11:44:36 +0530 Subject: [PATCH 21/24] Whitespaces and note --- skimage/morphology/convex_hull.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 06a6e710..6523a669 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -84,26 +84,25 @@ def convex_hull_object(image, neighbors=8): hull : ndarray of bool Binary image with pixels in convex hull set to True. - Note + Note ---- This function uses skimage.morphology.label to define unique objects, finds the convex hull of each using convex_hull_image, and combines these regions with logical OR. Be aware the convex hulls of unconnected objects may overlap in the result. If this is suspected, consider using - convex_hull_image on those objects together. - + convex_hull_image separately on each object. + """ if neighbors != 4 and neighbors != 8: raise ValueError('Neighbors must be either 4 or 8.') - + labeled_im = label(image, neighbors, background=0) convex_obj = np.zeros(image.shape, dtype=bool) convex_img = np.zeros(image.shape, dtype=bool) - + for i in range(0, labeled_im.max()+1): convex_obj = convex_hull_image(labeled_im == i) convex_img = np.logical_or(convex_img, convex_obj) return convex_img - From afd2208ff2eb54f6d7d07eb8975e016fa578b85f Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Tue, 28 May 2013 11:55:26 +0530 Subject: [PATCH 22/24] Space --- skimage/morphology/convex_hull.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 6523a669..93091b4f 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -101,7 +101,7 @@ def convex_hull_object(image, neighbors=8): convex_obj = np.zeros(image.shape, dtype=bool) convex_img = np.zeros(image.shape, dtype=bool) - for i in range(0, labeled_im.max()+1): + for i in range(0, labeled_im.max() + 1): convex_obj = convex_hull_image(labeled_im == i) convex_img = np.logical_or(convex_img, convex_obj) From 7eeda7c9350a0bd9bb46efa8097a4fef0d429365 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 29 May 2013 10:40:45 +0530 Subject: [PATCH 23/24] Add convex_hull_object to __all__ --- skimage/morphology/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/skimage/morphology/__init__.py b/skimage/morphology/__init__.py index aec60ea2..c8fafe6f 100644 --- a/skimage/morphology/__init__.py +++ b/skimage/morphology/__init__.py @@ -42,5 +42,6 @@ __all__ = ['binary_erosion', 'skeletonize', 'medial_axis', 'convex_hull_image', + 'convex_hull_object', 'reconstruction', 'remove_small_objects'] From a6caac07eb846d37cbaaea3a84d4883a016228d3 Mon Sep 17 00:00:00 2001 From: Chintak Sheth Date: Wed, 29 May 2013 10:56:32 +0530 Subject: [PATCH 24/24] new line --- skimage/morphology/convex_hull.py | 1 + 1 file changed, 1 insertion(+) diff --git a/skimage/morphology/convex_hull.py b/skimage/morphology/convex_hull.py index 93091b4f..28ff204b 100644 --- a/skimage/morphology/convex_hull.py +++ b/skimage/morphology/convex_hull.py @@ -29,6 +29,7 @@ def convex_hull_image(image): """ image = image.astype(bool) + # Here we do an optimisation by choosing only pixels that are # the starting or ending pixel of a row or column. This vastly # limits the number of coordinates to examine for the virtual