From 67cbb0221db8419a18bd5e6b677aa9b29e1eb489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Mon, 21 Oct 2013 13:34:55 +0200 Subject: [PATCH 1/7] Fix bug in homography detection --- skimage/transform/_geometric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skimage/transform/_geometric.py b/skimage/transform/_geometric.py index 25a13765..339ffaaf 100644 --- a/skimage/transform/_geometric.py +++ b/skimage/transform/_geometric.py @@ -1038,7 +1038,7 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1, if isinstance(inverse_map, np.ndarray) and inverse_map.shape == (3, 3): matrix = inverse_map - elif inverse_map in HOMOGRAPHY_TRANSFORMS: + elif isinstance(inverse_map, HOMOGRAPHY_TRANSFORMS): matrix = inverse_map._matrix elif (hasattr(inverse_map, '__name__') From 5873159f1dcd0e754a984886e0ce6881a8a8b789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Mon, 21 Oct 2013 14:01:47 +0200 Subject: [PATCH 2/7] Explicitly cast image shape to integer value --- skimage/transform/_warps_cy.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/skimage/transform/_warps_cy.pyx b/skimage/transform/_warps_cy.pyx index b3136c22..433c586d 100644 --- a/skimage/transform/_warps_cy.pyx +++ b/skimage/transform/_warps_cy.pyx @@ -89,11 +89,11 @@ def _warp_fast(cnp.ndarray image, cnp.ndarray H, output_shape=None, cdef Py_ssize_t out_r, out_c if output_shape is None: - out_r = img.shape[0] - out_c = img.shape[1] + out_r = int(img.shape[0]) + out_c = int(img.shape[1]) else: - out_r = output_shape[0] - out_c = output_shape[1] + out_r = int(output_shape[0]) + out_c = int(output_shape[1]) cdef double[:, ::1] out = np.zeros((out_r, out_c), dtype=np.double) From 0b98803f0f4ff3879021f8f26e2f795d15397055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Mon, 21 Oct 2013 14:14:20 +0200 Subject: [PATCH 3/7] Add some more comments --- skimage/transform/_geometric.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/skimage/transform/_geometric.py b/skimage/transform/_geometric.py index 339ffaaf..93ac800e 100644 --- a/skimage/transform/_geometric.py +++ b/skimage/transform/_geometric.py @@ -1031,21 +1031,24 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1, out = None - # use fast Cython version for specific interpolation orders + # use fast Cython version for specific interpolation orders and input if order in range(4) and not map_args: + matrix = None + # inverse_map is a transformation matrix as numpy array if isinstance(inverse_map, np.ndarray) and inverse_map.shape == (3, 3): matrix = inverse_map + # inverse_map is a homography elif isinstance(inverse_map, HOMOGRAPHY_TRANSFORMS): matrix = inverse_map._matrix + # inverse_map is the inverse of a homography elif (hasattr(inverse_map, '__name__') and inverse_map.__name__ == 'inverse' and get_bound_method_class(inverse_map) in HOMOGRAPHY_TRANSFORMS): - matrix = np.linalg.inv(six.get_method_self(inverse_map)._matrix) if matrix is not None: @@ -1067,6 +1070,7 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1, rows, cols = output_shape[:2] + # inverse_map is a transformation matrix as numpy array if isinstance(inverse_map, np.ndarray) and inverse_map.shape == (3, 3): inverse_map = ProjectiveTransform(matrix=inverse_map) @@ -1075,7 +1079,7 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1, coords = warp_coords(coord_map, (rows, cols, bands)) - # Prefilter not necessary for order 0, 1 interpolation + # Pre-filtering not necessary for order 0, 1 interpolation prefilter = order > 1 out = ndimage.map_coordinates(image, coords, prefilter=prefilter, mode=mode, order=order, cval=cval) From 638d43c859f7f5f204bb9dac9b076bebeecf44d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Mon, 21 Oct 2013 14:15:00 +0200 Subject: [PATCH 4/7] Re-enable clipping which was accidentally removed --- skimage/transform/_geometric.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/skimage/transform/_geometric.py b/skimage/transform/_geometric.py index 93ac800e..7ef8591b 100644 --- a/skimage/transform/_geometric.py +++ b/skimage/transform/_geometric.py @@ -1084,14 +1084,14 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1, out = ndimage.map_coordinates(image, coords, prefilter=prefilter, mode=mode, order=order, cval=cval) - # The spline filters sometimes return results outside [0, 1], - # so clip to ensure valid data - clipped = np.clip(out, 0, 1) + # The spline filters sometimes return results outside [0, 1], + # so clip to ensure valid data + clipped = np.clip(out, 0, 1) - if mode == 'constant' and not (0 <= cval <= 1): - clipped[out == cval] = cval + if mode == 'constant' and not (0 <= cval <= 1): + clipped[out == cval] = cval - out = clipped + out = clipped if out.ndim == 3 and orig_ndim == 2: # remove singleton dimension introduced by atleast_3d From 114bb36ef36ebe28bc325fd4921ed22c69763486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Mon, 21 Oct 2013 16:26:40 +0200 Subject: [PATCH 5/7] Do not derive piecewise affine from projective transform --- skimage/transform/_geometric.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skimage/transform/_geometric.py b/skimage/transform/_geometric.py index 7ef8591b..c1f49fa5 100644 --- a/skimage/transform/_geometric.py +++ b/skimage/transform/_geometric.py @@ -341,7 +341,7 @@ class AffineTransform(ProjectiveTransform): return self._matrix[0:2, 2] -class PiecewiseAffineTransform(ProjectiveTransform): +class PiecewiseAffineTransform(GeometricTransform): """2D piecewise affine transformation. @@ -1047,8 +1047,8 @@ def warp(image, inverse_map=None, map_args={}, output_shape=None, order=1, # inverse_map is the inverse of a homography elif (hasattr(inverse_map, '__name__') and inverse_map.__name__ == 'inverse' - and get_bound_method_class(inverse_map) - in HOMOGRAPHY_TRANSFORMS): + and isinstance(get_bound_method_class(inverse_map), + HOMOGRAPHY_TRANSFORMS)): matrix = np.linalg.inv(six.get_method_self(inverse_map)._matrix) if matrix is not None: From e45aee33698a4b6a7448ced38eaa18b5a95a32dc Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Mon, 28 Oct 2013 18:29:46 +1100 Subject: [PATCH 6/7] Modify mpl_image_to_rgba to allow RGB input image mpl_image_to_rgba produces a image of shape (M, N, 3, 4) when the input image is already RGB. This is understandably confusing for downstream processes, and this commit fixes it. --- skimage/viewer/viewers/core.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/skimage/viewer/viewers/core.py b/skimage/viewer/viewers/core.py index c3ffeb1e..8b5eb7ba 100644 --- a/skimage/viewer/viewers/core.py +++ b/skimage/viewer/viewers/core.py @@ -20,12 +20,28 @@ __all__ = ['ImageViewer', 'CollectionViewer'] def mpl_image_to_rgba(mpl_image): """Return RGB image from the given matplotlib image object. - Each image in a matplotlib figure has it's own colormap and normalization + Each image in a matplotlib figure has its own colormap and normalization function. Return RGBA (RGB + alpha channel) image with float dtype. + + Parameters + ---------- + mpl_image : matplotlib.image.AxesImage object + The image being converted. + + Returns + ------- + img : array of float, shape (M, N, 4) + An image of float values in [0, 1]. """ - input_range = (mpl_image.norm.vmin, mpl_image.norm.vmax) - image = rescale_intensity(mpl_image.get_array(), in_range=input_range) - image = mpl_image.cmap(img_as_float(image)) # cmap complains on bool arrays + image = mpl_image.get_array() + if image.ndim == 2: + input_range = (mpl_image.norm.vmin, mpl_image.norm.vmax) + image = rescale_intensity(image, in_range=input_range) + # cmap complains on bool arrays + image = mpl_image.cmap(img_as_float(image)) + elif image.ndim == 3 and image.shape[2] == 3: + # add alpha channel if it's missing + image = np.dstack((image, np.ones_like(image))) return img_as_float(image) From eff276c99b00d9ba8653b821bc87569b4f35d342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jostein=20B=C3=B8=20Fl=C3=B8ystad?= Date: Tue, 29 Oct 2013 11:58:59 +0100 Subject: [PATCH 7/7] Bug: Fix label sequence in regionprops. Closes gh-806. --- skimage/measure/_regionprops.py | 3 +++ skimage/measure/tests/test_regionprops.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/skimage/measure/_regionprops.py b/skimage/measure/_regionprops.py index 798e04cc..dfb7eb8c 100644 --- a/skimage/measure/_regionprops.py +++ b/skimage/measure/_regionprops.py @@ -503,6 +503,9 @@ def regionprops(label_image, properties=None, objects = ndimage.find_objects(label_image) for i, sl in enumerate(objects): + if sl is None: + continue + label = i + 1 props = _RegionProperties(sl, label, label_image, diff --git a/skimage/measure/tests/test_regionprops.py b/skimage/measure/tests/test_regionprops.py index c0c6443d..5a4dd117 100644 --- a/skimage/measure/tests/test_regionprops.py +++ b/skimage/measure/tests/test_regionprops.py @@ -347,6 +347,20 @@ def test_old_dict_interface(): assert_equal(len(feats[0]), 8) +def test_label_sequence(): + a = np.empty((2, 2), dtype=np.int) + a[:, :] = 2 + ps = regionprops(a) + assert len(ps) == 1 + assert ps[0].label == 2 + + +def test_pure_background(): + a = np.zeros((2, 2), dtype=np.int) + ps = regionprops(a) + assert len(ps) == 0 + + if __name__ == "__main__": from numpy.testing import run_module_suite run_module_suite()