From d8cc148d8c19337be987bd2e72787303eb08e20c Mon Sep 17 00:00:00 2001 From: Juan Nunez-Iglesias Date: Thu, 3 Sep 2015 20:12:35 +0200 Subject: [PATCH] Replace individual errors by 2D decorator --- skimage/measure/_regionprops.py | 105 ++++++++++++++++---------------- 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/skimage/measure/_regionprops.py b/skimage/measure/_regionprops.py index 3d5d6c6b..a130601b 100644 --- a/skimage/measure/_regionprops.py +++ b/skimage/measure/_regionprops.py @@ -74,6 +74,16 @@ def _cached(f): return wrapper +def only2d(method): + def func2d(self, *args, **kwargs): + if self._ndim > 2: + raise NotImplementedError('Property %s is not implemented for ' + '3D images' % method.__name__) + return method(self, *args, **kwargs) + func2d.__name__ = method.__name__ + return func2d + + class _RegionProperties(object): """Please refer to `skimage.measure.regionprops` for more information on the available region properties. @@ -109,15 +119,14 @@ class _RegionProperties(object): np.array([self._slice[i].start for i in range(self._ndim)])) + @property + @only2d def convex_area(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') return np.sum(self.convex_image) - @_cached + @_cached_property + @only2d def convex_image(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') from ..morphology.convex_hull import convex_hull_image return convex_hull_image(self.image) @@ -126,9 +135,9 @@ class _RegionProperties(object): return np.vstack([indices[i] + self._slice[i].start for i in range(self._ndim)]).T + @property + @only2d def eccentricity(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') l1, l2 = self.inertia_tensor_eigvals if l1 == 0: return 0 @@ -163,20 +172,19 @@ class _RegionProperties(object): def image(self): return self._label_image[self._slice] == self.label - @_cached + @_cached_property + @only2d def inertia_tensor(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') mu = self.moments_central a = mu[2, 0] / mu[0, 0] b = -mu[1, 1] / mu[0, 0] c = mu[0, 2] / mu[0, 0] return np.array([[a, b], [b, c]]) - @_cached + @_cached_property + @only2d +>>>>>>> Replace individual errors by 2D decorator def inertia_tensor_eigvals(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') a, b, b, c = self.inertia_tensor.flat # eigen values of inertia tensor l1 = (a + c) / 2 + sqrt(4 * b ** 2 + (a - c) ** 2) / 2 @@ -192,9 +200,9 @@ class _RegionProperties(object): def _intensity_image_double(self): return self.intensity_image.astype(np.double) + @property + @only2d def local_centroid(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') m = self.moments row = m[0, 1] / m[0, 0] col = m[1, 0] / m[0, 0] @@ -209,46 +217,43 @@ class _RegionProperties(object): def min_intensity(self): return np.min(self.intensity_image[self.image]) + @property + @only2d def major_axis_length(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') l1, _ = self.inertia_tensor_eigvals return 4 * sqrt(l1) + @property + @only2d def minor_axis_length(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') _, l2 = self.inertia_tensor_eigvals return 4 * sqrt(l2) - @_cached + @_cached_property + @only2d def moments(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') return _moments.moments(self.image.astype(np.uint8), 3) - @_cached + @_cached_property + @only2d def moments_central(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') row, col = self.local_centroid return _moments.moments_central(self.image.astype(np.uint8), row, col, 3) + @property + @only2d def moments_hu(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') return _moments.moments_hu(self.moments_normalized) - @_cached + @_cached_property + @only2d def moments_normalized(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') return _moments.moments_normalized(self.moments_central, 3) + @property + @only2d def orientation(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') a, b, b, c = self.inertia_tensor.flat b = -b if a - c == 0: @@ -259,52 +264,50 @@ class _RegionProperties(object): else: return - 0.5 * atan2(2 * b, (a - c)) + @property + @only2d def perimeter(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') return perimeter(self.image, 4) + @property + @only2d def solidity(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') return self.moments[0, 0] / np.sum(self.convex_image) + @property + @only2d def weighted_centroid(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') row, col = self.weighted_local_centroid return row + self._slice[0].start, col + self._slice[1].start + @property + @only2d def weighted_local_centroid(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') m = self.weighted_moments row = m[0, 1] / m[0, 0] col = m[1, 0] / m[0, 0] return row, col - @_cached + @_cached_property + @only2d def weighted_moments(self): - return _moments.moments_central(self._intensity_image_double(), - 0, 0, 3) + return _moments.moments_central(self._intensity_image_double, 0, 0, 3) - @_cached + @_cached_property + @only2d def weighted_moments_central(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') row, col = self.weighted_local_centroid return _moments.moments_central(self._intensity_image_double(), row, col, 3) + @property + @only2d def weighted_moments_hu(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') return _moments.moments_hu(self.weighted_moments_normalized) - @_cached + @_cached_property + @only2d def weighted_moments_normalized(self): - if self._ndim > 2: - raise NotImplementedError('not implemented for 3D images') return _moments.moments_normalized(self.weighted_moments_central, 3) def __iter__(self):