From 8ebe073ad592fe3bb3a5904a0ae884240418bcd2 Mon Sep 17 00:00:00 2001 From: Jonathan Helmus Date: Wed, 21 Jan 2015 16:01:13 -0600 Subject: [PATCH 1/6] BUG: unwrap_phase on compressed masked array unwrap_phase works on masked arrays with a compressed mask (no elements masked) Closes #1346 --- skimage/restoration/tests/test_unwrap.py | 9 +++++++++ skimage/restoration/unwrap.py | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/skimage/restoration/tests/test_unwrap.py b/skimage/restoration/tests/test_unwrap.py index e628f4fe..7d22d5b2 100644 --- a/skimage/restoration/tests/test_unwrap.py +++ b/skimage/restoration/tests/test_unwrap.py @@ -156,5 +156,14 @@ def test_unwrap_3d_middle_wrap_around(): unwrap = unwrap_phase(image, wrap_around=[False, True, False]) assert np.all(unwrap == 0) + +def test_unwrap_2d_compressed_mask(): + # ValueError when image is masked array with a compressed mask (no masked + # elments). GitHub issue #1346 + image = np.ma.zeros((10, 10)) + unwrap = unwrap_phase(image) + assert np.all(unwrap == 0) + + if __name__ == "__main__": run_module_suite() diff --git a/skimage/restoration/unwrap.py b/skimage/restoration/unwrap.py index c6810229..6dd7c7ef 100644 --- a/skimage/restoration/unwrap.py +++ b/skimage/restoration/unwrap.py @@ -88,8 +88,8 @@ def unwrap_phase(image, wrap_around=False, seed=None): 'algorithm') if np.ma.isMaskedArray(image): - mask = np.require(image.mask, np.uint8, ['C']) - image = image.data + mask = np.require(np.ma.getmaskarray(image), np.uint8, ['C']) + image = np.ma.getdata(image) else: mask = np.zeros_like(image, dtype=np.uint8, order='C') From eef3734bfe326e2a3c0601b0bd104e7a5133f1cb Mon Sep 17 00:00:00 2001 From: Jonathan Helmus Date: Wed, 21 Jan 2015 16:03:18 -0600 Subject: [PATCH 2/6] Remove end of line whitespace in test_unwrap.py --- skimage/restoration/tests/test_unwrap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/restoration/tests/test_unwrap.py b/skimage/restoration/tests/test_unwrap.py index 7d22d5b2..979cd80c 100644 --- a/skimage/restoration/tests/test_unwrap.py +++ b/skimage/restoration/tests/test_unwrap.py @@ -138,7 +138,7 @@ def test_mask(): image_wrapped_3d = image_wrapped.reshape(shape) image_unwrapped_3d = unwrap_phase(image_wrapped_3d) # remove phase shift - image_unwrapped_3d -= image_unwrapped_3d[0, 0, 0] + image_unwrapped_3d -= image_unwrapped_3d[0, 0, 0] assert_array_almost_equal_nulp(image_unwrapped_3d[:, :, -1], image[i, -1]) From de01ea56ae0fdf451bb417d60b8545c065ddaa1c Mon Sep 17 00:00:00 2001 From: Jonathan Helmus Date: Wed, 21 Jan 2015 16:23:50 -0600 Subject: [PATCH 3/6] unwrap_phase returns masked array when image is masked With commit e3b84ed the unwrap_phase function would always return an ndarray even when image was masked. This restores the pre-e3b84ed behavior of returning a masked array when the image is masked. --- skimage/restoration/tests/test_unwrap.py | 1 + skimage/restoration/unwrap.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/skimage/restoration/tests/test_unwrap.py b/skimage/restoration/tests/test_unwrap.py index 979cd80c..ca4cfe32 100644 --- a/skimage/restoration/tests/test_unwrap.py +++ b/skimage/restoration/tests/test_unwrap.py @@ -131,6 +131,7 @@ def test_mask(): # The end of the unwrapped array should have value equal to the # endpoint of the unmasked ramp assert_array_almost_equal_nulp(image_unwrapped[:, -1], image[i, -1]) + assert np.ma.isMaskedArray(image_unwrapped) # Same tests, but forcing use of the 3D unwrapper by reshaping with expected_warnings(['length 1 dimension']): diff --git a/skimage/restoration/unwrap.py b/skimage/restoration/unwrap.py index 6dd7c7ef..36fe0d9d 100644 --- a/skimage/restoration/unwrap.py +++ b/skimage/restoration/unwrap.py @@ -89,11 +89,11 @@ def unwrap_phase(image, wrap_around=False, seed=None): if np.ma.isMaskedArray(image): mask = np.require(np.ma.getmaskarray(image), np.uint8, ['C']) - image = np.ma.getdata(image) else: mask = np.zeros_like(image, dtype=np.uint8, order='C') - image_not_masked = np.asarray(image, dtype=np.double, order='C') + image_not_masked = np.asarray( + np.ma.getdata(image), dtype=np.double, order='C') image_unwrapped = np.empty_like(image, dtype=np.double, order='C') if image.ndim == 1: From d3024b5c738c47bdab89235bced1fb12c1656e93 Mon Sep 17 00:00:00 2001 From: Jonathan Helmus Date: Wed, 21 Jan 2015 16:36:58 -0600 Subject: [PATCH 4/6] No SegFault when unwrapping a 2D fully masked array The unwrap_phase function no longer causes a Segmentation fault when passed a 2D array in which all elements are masked. --- skimage/restoration/tests/test_unwrap.py | 20 ++++++++++++++++++++ skimage/restoration/unwrap_2d_ljmu.c | 9 +++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/skimage/restoration/tests/test_unwrap.py b/skimage/restoration/tests/test_unwrap.py index ca4cfe32..4353dc20 100644 --- a/skimage/restoration/tests/test_unwrap.py +++ b/skimage/restoration/tests/test_unwrap.py @@ -166,5 +166,25 @@ def test_unwrap_2d_compressed_mask(): assert np.all(unwrap == 0) +def test_unwrap_2d_all_masked(): + # Segmentation fault when image is masked array with a all elements masked + # GitHub issue #1347 + # all elements masked + image = np.ma.zeros((10, 10)) + image[:] = np.ma.masked + unwrap = unwrap_phase(image) + assert np.ma.isMaskedArray(unwrap) + assert np.all(unwrap.mask) + + # 1 unmasked element, still zero edges + image = np.ma.zeros((10, 10)) + image[:] = np.ma.masked + image[0, 0] = 0 + unwrap = unwrap_phase(image) + assert np.ma.isMaskedArray(unwrap) + assert np.sum(unwrap.mask) == 99 # all but one masked + assert unwrap[0, 0] == 0 + + if __name__ == "__main__": run_module_suite() diff --git a/skimage/restoration/unwrap_2d_ljmu.c b/skimage/restoration/unwrap_2d_ljmu.c index 605c7993..690a8d77 100644 --- a/skimage/restoration/unwrap_2d_ljmu.c +++ b/skimage/restoration/unwrap_2d_ljmu.c @@ -718,10 +718,11 @@ void unwrap2D(double *wrapped_image, double *UnwrappedImage, horizontalEDGEs(pixel, edge, image_width, image_height, ¶ms); verticalEDGEs(pixel, edge, image_width, image_height, ¶ms); - // sort the EDGEs depending on their reiability. The PIXELs with higher - // relibility (small value) first - quicker_sort(edge, edge + params.no_of_edges - 1); - + if (params.no_of_edges != 0) { + // sort the EDGEs depending on their reiability. The PIXELs with higher + // relibility (small value) first + quicker_sort(edge, edge + params.no_of_edges - 1); + } // gather PIXELs into groups gatherPIXELs(edge, ¶ms); From 8eebb17bac2492061ed6feeb7404f8c3791aa0f4 Mon Sep 17 00:00:00 2001 From: Jonathan Helmus Date: Wed, 21 Jan 2015 16:43:39 -0600 Subject: [PATCH 5/6] No SegFault when unwrapping a 3D fully masked array The unwrap_phase function no longer causes a Segmentation fault when passed a 3D array in which all elements are masked. Closes #1347 --- skimage/restoration/tests/test_unwrap.py | 17 +++++++++++++++++ skimage/restoration/unwrap_3d_ljmu.c | 8 +++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/skimage/restoration/tests/test_unwrap.py b/skimage/restoration/tests/test_unwrap.py index 4353dc20..f5ff2c76 100644 --- a/skimage/restoration/tests/test_unwrap.py +++ b/skimage/restoration/tests/test_unwrap.py @@ -186,5 +186,22 @@ def test_unwrap_2d_all_masked(): assert unwrap[0, 0] == 0 +def test_unwrap_3d_all_masked(): + # all elements masked + image = np.ma.zeros((10, 10, 10)) + image[:] = np.ma.masked + unwrap = unwrap_phase(image) + assert np.ma.isMaskedArray(unwrap) + assert np.all(unwrap.mask) + + # 1 unmasked element, still zero edges + image = np.ma.zeros((10, 10, 10)) + image[:] = np.ma.masked + image[0, 0, 0] = 0 + unwrap = unwrap_phase(image) + assert np.ma.isMaskedArray(unwrap) + assert np.sum(unwrap.mask) == 999 # all but one masked + assert unwrap[0, 0, 0] == 0 + if __name__ == "__main__": run_module_suite() diff --git a/skimage/restoration/unwrap_3d_ljmu.c b/skimage/restoration/unwrap_3d_ljmu.c index be47f926..fdd9847a 100644 --- a/skimage/restoration/unwrap_3d_ljmu.c +++ b/skimage/restoration/unwrap_3d_ljmu.c @@ -1136,9 +1136,11 @@ void unwrap3D(double *wrapped_volume, double *unwrapped_volume, ¶ms); normalEDGEs(voxel, edge, volume_width, volume_height, volume_depth, ¶ms); - // sort the EDGEs depending on their reiability. The VOXELs with higher - // relibility (small value) first - quicker_sort(edge, edge + params.no_of_edges - 1); + if (params.no_of_edges != 0) { + // sort the EDGEs depending on their reiability. The VOXELs with higher + // relibility (small value) first + quicker_sort(edge, edge + params.no_of_edges - 1); + } // gather VOXELs into groups gatherVOXELs(edge, ¶ms); From 738953b9461bb6753ae70e39c488b98d1121cba1 Mon Sep 17 00:00:00 2001 From: Jonathan Helmus Date: Wed, 21 Jan 2015 19:37:23 -0600 Subject: [PATCH 6/6] image_unwrapped created as ndarray always In unwrap_phase the image_unwrapped variable is created as an ndarray even when image is a masked array. --- skimage/restoration/unwrap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skimage/restoration/unwrap.py b/skimage/restoration/unwrap.py index 36fe0d9d..14f1eafa 100644 --- a/skimage/restoration/unwrap.py +++ b/skimage/restoration/unwrap.py @@ -94,7 +94,8 @@ def unwrap_phase(image, wrap_around=False, seed=None): image_not_masked = np.asarray( np.ma.getdata(image), dtype=np.double, order='C') - image_unwrapped = np.empty_like(image, dtype=np.double, order='C') + image_unwrapped = np.empty_like(image, dtype=np.double, order='C', + subok=False) if image.ndim == 1: unwrap_1d(image_not_masked, image_unwrapped)