diff --git a/skimage/__init__.py b/skimage/__init__.py index a48ce4b2..a3deb6c6 100644 --- a/skimage/__init__.py +++ b/skimage/__init__.py @@ -63,7 +63,6 @@ except ImportError: def _setup_test(verbose=False): - import gzip import functools args = ['', '--exe', '-w', pkg_dir] diff --git a/skimage/data/__init__.py b/skimage/data/__init__.py index 5a01a493..7e351293 100644 --- a/skimage/data/__init__.py +++ b/skimage/data/__init__.py @@ -49,7 +49,7 @@ def lena(): def text(): - """ Gray-level "text" image used for corner detection. + """ Gray-level "text" image used for corner detection. Notes ----- @@ -60,7 +60,8 @@ def text(): """ - return load("text.png") + return load("text.png") + def checkerboard(): """Checkerboard image. diff --git a/skimage/data/tests/test_data.py b/skimage/data/tests/test_data.py index c4c57f86..1d85802b 100644 --- a/skimage/data/tests/test_data.py +++ b/skimage/data/tests/test_data.py @@ -1,6 +1,5 @@ import skimage.data as data -from numpy.testing import assert_equal, assert_array_equal -import numpy as np +from numpy.testing import assert_equal def test_lena(): @@ -17,7 +16,7 @@ def test_camera(): def test_checkerboard(): """ Test that checkerboard image can be loaded. """ - checkerboard = data.checkerboard() + data.checkerboard() if __name__ == "__main__": from numpy.testing import run_module_suite diff --git a/skimage/filter/edges.py b/skimage/filter/edges.py index b6a800c9..cd91effb 100644 --- a/skimage/filter/edges.py +++ b/skimage/filter/edges.py @@ -70,7 +70,7 @@ def hsobel(image, mask=None): mask = np.ones(image.shape, bool) big_mask = binary_erosion(mask, generate_binary_structure(2, 2), - border_value = 0) + border_value=0) result = np.abs(convolve(image, np.array([[ 1, 2, 1], [ 0, 0, 0], @@ -78,6 +78,7 @@ def hsobel(image, mask=None): result[big_mask == False] = 0 return result + def vsobel(image, mask=None): """Find the vertical edges of an image using the Sobel transform. diff --git a/skimage/measure/find_contours.py b/skimage/measure/find_contours.py index a64d63ea..68e1d53c 100755 --- a/skimage/measure/find_contours.py +++ b/skimage/measure/find_contours.py @@ -5,6 +5,7 @@ from collections import deque _param_options = ('high', 'low') + def find_contours(array, level, fully_connected='low', positive_orientation='low'): """Find iso-valued contours in a 2D array for a given level value. @@ -83,10 +84,10 @@ def find_contours(array, level, This means that to find reasonable contours, it is best to find contours midway between the expected "light" and "dark" values. In particular, - given a binarized array, *do not* choose to find contours at the low or high - value of the array. This will often yield degenerate contours, especially - around structures that are a single array element wide. Instead choose - a middle value, as above. + given a binarized array, *do not* choose to find contours at the low or + high value of the array. This will often yield degenerate contours, + especially around structures that are a single array element wide. Instead + choose a middle value, as above. References ---------- @@ -129,7 +130,8 @@ def _assemble_contours(points_iterator): # This happens when (and only when) one vertex of the square is # exactly the contour level, and the rest are above or below. # This degnerate vertex will be picked up later by neighboring squares. - if from_point == to_point: continue + if from_point == to_point: + continue tail_data = starts.get(to_point) head_data = ends.get(from_point) diff --git a/skimage/measure/tests/test_find_contours.py b/skimage/measure/tests/test_find_contours.py index 3de7acc4..fbc502f7 100644 --- a/skimage/measure/tests/test_find_contours.py +++ b/skimage/measure/tests/test_find_contours.py @@ -21,39 +21,40 @@ r = np.sqrt(x**2 + y**2) def test_binary(): - contours = find_contours(a, 0.5) - assert len(contours) == 1 - assert_array_equal(contours[0], - [[ 6. , 1.5], - [ 5. , 1.5], - [ 4. , 1.5], - [ 3. , 1.5], - [ 2. , 1.5], - [ 1.5, 2. ], - [ 1.5, 3. ], - [ 1.5, 4. ], - [ 1.5, 5. ], - [ 1.5, 6. ], - [ 1. , 6.5], - [ 0.5, 6. ], - [ 0.5, 5. ], - [ 0.5, 4. ], - [ 0.5, 3. ], - [ 0.5, 2. ], - [ 0.5, 1. ], - [ 1. , 0.5], - [ 2. , 0.5], - [ 3. , 0.5], - [ 4. , 0.5], - [ 5. , 0.5], - [ 6. , 0.5], - [ 6.5, 1. ], - [ 6. , 1.5]]) + contours = find_contours(a, 0.5) + assert len(contours) == 1 + assert_array_equal(contours[0], + [[6. , 1.5], + [5. , 1.5], + [4. , 1.5], + [3. , 1.5], + [2. , 1.5], + [1.5, 2. ], + [1.5, 3. ], + [1.5, 4. ], + [1.5, 5. ], + [1.5, 6. ], + [1. , 6.5], + [0.5, 6. ], + [0.5, 5. ], + [0.5, 4. ], + [0.5, 3. ], + [0.5, 2. ], + [0.5, 1. ], + [1. , 0.5], + [2. , 0.5], + [3. , 0.5], + [4. , 0.5], + [5. , 0.5], + [6. , 0.5], + [6.5, 1. ], + [6. , 1.5]]) + def test_float(): - contours = find_contours(r, 0.5) - assert len(contours) == 1 - assert_array_equal(contours[0], + contours = find_contours(r, 0.5) + assert len(contours) == 1 + assert_array_equal(contours[0], [[ 2., 3.], [ 1., 2.], [ 2., 1.], @@ -61,7 +62,6 @@ def test_float(): [ 2., 3.]]) - if __name__ == '__main__': from numpy.testing import run_module_suite run_module_suite() diff --git a/skimage/morphology/skeletonize.py b/skimage/morphology/skeletonize.py index bfa7525c..a8d31bdd 100644 --- a/skimage/morphology/skeletonize.py +++ b/skimage/morphology/skeletonize.py @@ -79,7 +79,7 @@ def skeletonize(image): [0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8) - + """ # look up table - there is one entry for each of the 2^8=256 possible # combinations of 8 binary neighbours. 1's, 2's and 3's are candidates @@ -318,9 +318,9 @@ def _pattern_of(index): def _table_lookup(image, table): """ - Perform a morphological transform on an image, directed by its + Perform a morphological transform on an image, directed by its neighbors - + Parameters ---------- image : ndarray @@ -330,7 +330,7 @@ def _table_lookup(image, table): the values of that pixel and its 8-connected neighbors. border_value : bool The value of pixels beyond the border of the image. - + Returns ------- result : ndarray of same shape as `image` @@ -340,7 +340,7 @@ def _table_lookup(image, table): ----- The pixels are numbered like this:: - + 0 1 2 3 4 5 6 7 8 @@ -358,11 +358,11 @@ def _table_lookup(image, table): indexer[1:, 1:] += image[:-1, :-1] * 2**0 indexer[1:, :] += image[:-1, :] * 2**1 indexer[1:, :-1] += image[:-1, 1:] * 2**2 - + indexer[:, 1:] += image[:, :-1] * 2**3 indexer[:, :] += image[:, :] * 2**4 indexer[:, :-1] += image[:, 1:] * 2**5 - + indexer[:-1, 1:] += image[1:, :-1] * 2**6 indexer[:-1, :] += image[1:, :] * 2**7 indexer[:-1, :-1] += image[1:, 1:] * 2**8 @@ -370,4 +370,3 @@ def _table_lookup(image, table): indexer = _table_lookup_index(np.ascontiguousarray(image, np.uint8)) image = table[indexer] return image - diff --git a/skimage/morphology/tests/test_ccomp.py b/skimage/morphology/tests/test_ccomp.py index cb092b4c..1e0829ca 100644 --- a/skimage/morphology/tests/test_ccomp.py +++ b/skimage/morphology/tests/test_ccomp.py @@ -3,6 +3,7 @@ from numpy.testing import assert_array_equal, run_module_suite from skimage.morphology import label + class TestConnectedComponents: def setup(self): self.x = np.array([[0, 0, 3, 2, 1, 9], diff --git a/skimage/morphology/tests/test_watershed.py b/skimage/morphology/tests/test_watershed.py index c6671d7a..46298ae5 100644 --- a/skimage/morphology/tests/test_watershed.py +++ b/skimage/morphology/tests/test_watershed.py @@ -43,7 +43,6 @@ Original author: Lee Kamentsky import math -import time import unittest import numpy as np @@ -54,6 +53,7 @@ from skimage.morphology.watershed import watershed, \ eps = 1e-12 + def diff(a, b): if not isinstance(a, np.ndarray): a = np.asarray(a) @@ -122,28 +122,27 @@ class TestWatershed(unittest.TestCase): def test_watershed02(self): "watershed 2" data = np.array([[0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 1, 1, 1, 0], + [0, 1, 0, 0, 0, 1, 0], + [0, 1, 0, 0, 0, 1, 0], + [0, 1, 0, 0, 0, 1, 0], + [0, 1, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0]], np.uint8) + markers = np.array([[-1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], - [0, 1, 1, 1, 1, 1, 0], - [0, 1, 0, 0, 0, 1, 0], - [0, 1, 0, 0, 0, 1, 0], - [0, 1, 0, 0, 0, 1, 0], - [0, 1, 1, 1, 1, 1, 0], - [0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0]], np.uint8) - markers = np.array([[ -1, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 1, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0]], - np.int8) + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0]], np.int8) out = watershed(data, markers) error = diff([[-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1], @@ -161,26 +160,25 @@ class TestWatershed(unittest.TestCase): def test_watershed03(self): "watershed 3" data = np.array([[0, 0, 0, 0, 0, 0, 0], - [0, 1, 1, 1, 1, 1, 0], - [0, 1, 0, 1, 0, 1, 0], - [0, 1, 0, 1, 0, 1, 0], - [0, 1, 0, 1, 0, 1, 0], - [0, 1, 1, 1, 1, 1, 0], - [0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0]], np.uint8) - markers = np.array([[ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 2, 0, 3, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, -1]], - np.int8) + [0, 1, 1, 1, 1, 1, 0], + [0, 1, 0, 1, 0, 1, 0], + [0, 1, 0, 1, 0, 1, 0], + [0, 1, 0, 1, 0, 1, 0], + [0, 1, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0]], np.uint8) + markers = np.array([[0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 2, 0, 3, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, -1]], np.int8) out = watershed(data, markers) error = diff([[-1, -1, -1, -1, -1, -1, -1], [-1, 0, 2, 0, 3, 0, -1], @@ -202,21 +200,20 @@ class TestWatershed(unittest.TestCase): [0, 1, 0, 1, 0, 1, 0], [0, 1, 0, 1, 0, 1, 0], [0, 1, 1, 1, 1, 1, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]], np.uint8) - markers = np.array([[ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 2, 0, 3, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, -1]], - np.int8) + markers = np.array([[0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 2, 0, 3, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, -1]], np.int8) out = watershed(data, markers, self.eight) error = diff([[-1, -1, -1, -1, -1, -1, -1], [-1, 2, 2, 0, 3, 3, -1], @@ -224,35 +221,34 @@ class TestWatershed(unittest.TestCase): [-1, 2, 2, 0, 3, 3, -1], [-1, 2, 2, 0, 3, 3, -1], [-1, 2, 2, 0, 3, 3, -1], - [-1, -1, -1, -1, -1, -1, -1], - [-1, -1, -1, -1, -1, -1, -1], - [-1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1], + [-1, -1, -1, -1, -1, -1, -1], [-1, -1, -1, -1, -1, -1, -1]], out) self.failUnless(error < eps) def test_watershed05(self): "watershed 5" data = np.array([[0, 0, 0, 0, 0, 0, 0], - [0, 1, 1, 1, 1, 1, 0], - [0, 1, 0, 1, 0, 1, 0], - [0, 1, 0, 1, 0, 1, 0], - [0, 1, 0, 1, 0, 1, 0], - [0, 1, 1, 1, 1, 1, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0]], np.uint8) - markers = np.array([[ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 3, 0, 2, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, -1]], - np.int8) + [0, 1, 1, 1, 1, 1, 0], + [0, 1, 0, 1, 0, 1, 0], + [0, 1, 0, 1, 0, 1, 0], + [0, 1, 0, 1, 0, 1, 0], + [0, 1, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0]], np.uint8) + markers = np.array([[0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 3, 0, 2, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, -1]], np.int8) out = watershed(data, markers, self.eight) error = diff([[-1, -1, -1, -1, -1, -1, -1], [-1, 3, 3, 0, 2, 2, -1], @@ -269,24 +265,23 @@ class TestWatershed(unittest.TestCase): def test_watershed06(self): "watershed 6" data = np.array([[0, 1, 0, 0, 0, 1, 0], - [0, 1, 0, 0, 0, 1, 0], - [0, 1, 0, 0, 0, 1, 0], - [0, 1, 1, 1, 1, 1, 0], - [0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0]], np.uint8) - markers = np.array([[ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 1, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ 0, 0, 0, 0, 0, 0, 0], - [ -1, 0, 0, 0, 0, 0, 0]], - np.int8) + [0, 1, 0, 0, 0, 1, 0], + [0, 1, 0, 0, 0, 1, 0], + [0, 1, 1, 1, 1, 1, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0]], np.uint8) + markers = np.array([[0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0], + [-1, 0, 0, 0, 0, 0, 0]], np.int8) out = watershed(data, markers, self.eight) error = diff([[-1, 1, 1, 1, 1, 1, -1], [-1, 1, 1, 1, 1, 1, -1], @@ -302,28 +297,28 @@ class TestWatershed(unittest.TestCase): def test_watershed07(self): "A regression test of a competitive case that failed" data = np.array([[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], - [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], - [255,255,255,255,255,204,204,204,204,204,204,255,255,255,255,255], - [255,255,255,204,204,183,153,153,153,153,183,204,204,255,255,255], - [255,255,204,183,153,141,111,103,103,111,141,153,183,204,255,255], - [255,255,204,153,111, 94, 72, 52, 52, 72, 94,111,153,204,255,255], - [255,255,204,153,111, 72, 39, 1, 1, 39, 72,111,153,204,255,255], - [255,255,204,183,141,111, 72, 39, 39, 72,111,141,183,204,255,255], - [255,255,255,204,183,141,111, 72, 72,111,141,183,204,255,255,255], - [255,255,255,255,204,183,141, 94, 94,141,183,204,255,255,255,255], - [255,255,255,255,255,204,153,103,103,153,204,255,255,255,255,255], - [255,255,255,255,204,183,141, 94, 94,141,183,204,255,255,255,255], - [255,255,255,204,183,141,111, 72, 72,111,141,183,204,255,255,255], - [255,255,204,183,141,111, 72, 39, 39, 72,111,141,183,204,255,255], - [255,255,204,153,111, 72, 39, 1, 1, 39, 72,111,153,204,255,255], - [255,255,204,153,111, 94, 72, 52, 52, 72, 94,111,153,204,255,255], - [255,255,204,183,153,141,111,103,103,111,141,153,183,204,255,255], - [255,255,255,204,204,183,153,153,153,153,183,204,204,255,255,255], - [255,255,255,255,255,204,204,204,204,204,204,255,255,255,255,255], - [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], - [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]]) + [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], + [255,255,255,255,255,204,204,204,204,204,204,255,255,255,255,255], + [255,255,255,204,204,183,153,153,153,153,183,204,204,255,255,255], + [255,255,204,183,153,141,111,103,103,111,141,153,183,204,255,255], + [255,255,204,153,111, 94, 72, 52, 52, 72, 94,111,153,204,255,255], + [255,255,204,153,111, 72, 39, 1, 1, 39, 72,111,153,204,255,255], + [255,255,204,183,141,111, 72, 39, 39, 72,111,141,183,204,255,255], + [255,255,255,204,183,141,111, 72, 72,111,141,183,204,255,255,255], + [255,255,255,255,204,183,141, 94, 94,141,183,204,255,255,255,255], + [255,255,255,255,255,204,153,103,103,153,204,255,255,255,255,255], + [255,255,255,255,204,183,141, 94, 94,141,183,204,255,255,255,255], + [255,255,255,204,183,141,111, 72, 72,111,141,183,204,255,255,255], + [255,255,204,183,141,111, 72, 39, 39, 72,111,141,183,204,255,255], + [255,255,204,153,111, 72, 39, 1, 1, 39, 72,111,153,204,255,255], + [255,255,204,153,111, 94, 72, 52, 52, 72, 94,111,153,204,255,255], + [255,255,204,183,153,141,111,103,103,111,141,153,183,204,255,255], + [255,255,255,204,204,183,153,153,153,153,183,204,204,255,255,255], + [255,255,255,255,255,204,204,204,204,204,204,255,255,255,255,255], + [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], + [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]]) mask = (data != 255) - markers = np.zeros(data.shape,int) + markers = np.zeros(data.shape, int) markers[6, 7] = 1 markers[14, 7] = 2 out = watershed(data, markers, self.eight, mask=mask) @@ -338,30 +333,30 @@ class TestWatershed(unittest.TestCase): def test_watershed08(self): "The border pixels + an edge are all the same value" data = np.array([[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], - [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], - [255,255,255,255,255,204,204,204,204,204,204,255,255,255,255,255], - [255,255,255,204,204,183,153,153,153,153,183,204,204,255,255,255], - [255,255,204,183,153,141,111,103,103,111,141,153,183,204,255,255], - [255,255,204,153,111, 94, 72, 52, 52, 72, 94,111,153,204,255,255], - [255,255,204,153,111, 72, 39, 1, 1, 39, 72,111,153,204,255,255], - [255,255,204,183,141,111, 72, 39, 39, 72,111,141,183,204,255,255], - [255,255,255,204,183,141,111, 72, 72,111,141,183,204,255,255,255], - [255,255,255,255,204,183,141, 94, 94,141,183,204,255,255,255,255], - [255,255,255,255,255,204,153,141,141,153,204,255,255,255,255,255], - [255,255,255,255,204,183,141, 94, 94,141,183,204,255,255,255,255], - [255,255,255,204,183,141,111, 72, 72,111,141,183,204,255,255,255], - [255,255,204,183,141,111, 72, 39, 39, 72,111,141,183,204,255,255], - [255,255,204,153,111, 72, 39, 1, 1, 39, 72,111,153,204,255,255], - [255,255,204,153,111, 94, 72, 52, 52, 72, 94,111,153,204,255,255], - [255,255,204,183,153,141,111,103,103,111,141,153,183,204,255,255], - [255,255,255,204,204,183,153,153,153,153,183,204,204,255,255,255], - [255,255,255,255,255,204,204,204,204,204,204,255,255,255,255,255], - [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], - [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]]) + [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], + [255,255,255,255,255,204,204,204,204,204,204,255,255,255,255,255], + [255,255,255,204,204,183,153,153,153,153,183,204,204,255,255,255], + [255,255,204,183,153,141,111,103,103,111,141,153,183,204,255,255], + [255,255,204,153,111, 94, 72, 52, 52, 72, 94,111,153,204,255,255], + [255,255,204,153,111, 72, 39, 1, 1, 39, 72,111,153,204,255,255], + [255,255,204,183,141,111, 72, 39, 39, 72,111,141,183,204,255,255], + [255,255,255,204,183,141,111, 72, 72,111,141,183,204,255,255,255], + [255,255,255,255,204,183,141, 94, 94,141,183,204,255,255,255,255], + [255,255,255,255,255,204,153,141,141,153,204,255,255,255,255,255], + [255,255,255,255,204,183,141, 94, 94,141,183,204,255,255,255,255], + [255,255,255,204,183,141,111, 72, 72,111,141,183,204,255,255,255], + [255,255,204,183,141,111, 72, 39, 39, 72,111,141,183,204,255,255], + [255,255,204,153,111, 72, 39, 1, 1, 39, 72,111,153,204,255,255], + [255,255,204,153,111, 94, 72, 52, 52, 72, 94,111,153,204,255,255], + [255,255,204,183,153,141,111,103,103,111,141,153,183,204,255,255], + [255,255,255,204,204,183,153,153,153,153,183,204,204,255,255,255], + [255,255,255,255,255,204,204,204,204,204,204,255,255,255,255,255], + [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255], + [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]]) mask = (data != 255) - markers = np.zeros(data.shape,int) - markers[6,7] = 1 - markers[14,7] = 2 + markers = np.zeros(data.shape, int) + markers[6, 7] = 1 + markers[14, 7] = 2 out = watershed(data, markers, self.eight, mask=mask) # # The two objects should be the same size, except possibly for the @@ -379,20 +374,17 @@ class TestWatershed(unittest.TestCase): """ image = np.zeros((1000, 1000)) coords = np.random.uniform(0, 1000, (100, 2)).astype(int) - markers = np.zeros((1000, 1000),int) + markers = np.zeros((1000, 1000), int) idx = 1 - for x,y in coords: - image[x,y] = 1 + for x, y in coords: + image[x, y] = 1 markers[x, y] = idx idx += 1 image = scipy.ndimage.gaussian_filter(image, 4) - before = time.clock() - out = watershed(image, markers, self.eight) - elapsed = time.clock() - before - before = time.clock() - out = scipy.ndimage.watershed_ift(image.astype(np.uint16), markers, self.eight) - elapsed = time.clock() - before + watershed(image, markers, self.eight) + scipy.ndimage.watershed_ift(image.astype(np.uint16), markers, + self.eight) class TestIsLocalMaximum(unittest.TestCase): @@ -431,48 +423,48 @@ class TestIsLocalMaximum(unittest.TestCase): self.assertTrue(np.all(result == expected)) def test_01_04_not_adjacent_and_different(self): - image = np.zeros((10,20)) - labels = np.zeros((10,20), int) - image[5,5] = 1 - image[5,8] = .5 + image = np.zeros((10, 20)) + labels = np.zeros((10, 20), int) + image[5, 5] = 1 + image[5, 8] = .5 labels[image > 0] = 1 expected = (labels == 1) - result = is_local_maximum(image, labels, np.ones((3,3), bool)) + result = is_local_maximum(image, labels, np.ones((3, 3), bool)) self.assertTrue(np.all(result == expected)) def test_01_05_two_objects(self): - image = np.zeros((10,20)) - labels = np.zeros((10,20), int) - image[5,5] = 1 - image[5,15] = .5 - labels[5,5] = 1 - labels[5,15] = 2 + image = np.zeros((10, 20)) + labels = np.zeros((10, 20), int) + image[5, 5] = 1 + image[5, 15] = .5 + labels[5, 5] = 1 + labels[5, 15] = 2 expected = (labels > 0) - result = is_local_maximum(image, labels, np.ones((3,3), bool)) + result = is_local_maximum(image, labels, np.ones((3, 3), bool)) self.assertTrue(np.all(result == expected)) def test_01_06_adjacent_different_objects(self): - image = np.zeros((10,20)) - labels = np.zeros((10,20), int) - image[5,5] = 1 - image[5,6] = .5 - labels[5,5] = 1 - labels[5,6] = 2 + image = np.zeros((10, 20)) + labels = np.zeros((10, 20), int) + image[5, 5] = 1 + image[5, 6] = .5 + labels[5, 5] = 1 + labels[5, 6] = 2 expected = (labels > 0) - result = is_local_maximum(image, labels, np.ones((3,3), bool)) + result = is_local_maximum(image, labels, np.ones((3, 3), bool)) self.assertTrue(np.all(result == expected)) def test_02_01_four_quadrants(self): np.random.seed(21) - image = np.random.uniform(size=(40,60)) - i,j = np.mgrid[0:40,0:60] + image = np.random.uniform(size=(40, 60)) + i, j = np.mgrid[0:40, 0:60] labels = 1 + (i >= 20) + (j >= 30) * 2 - i,j = np.mgrid[-3:4,-3:4] + i, j = np.mgrid[-3:4, -3:4] footprint = (i * i + j * j <= 9) expected = np.zeros(image.shape, float) for imin, imax in ((0, 20), (20, 40)): for jmin, jmax in ((0, 30), (30, 60)): - expected[imin:imax,jmin:jmax] = scipy.ndimage.maximum_filter( + expected[imin:imax, jmin:jmax] = scipy.ndimage.maximum_filter( image[imin:imax, jmin:jmax], footprint=footprint) expected = (expected == image) result = is_local_maximum(image, labels, footprint) @@ -484,9 +476,9 @@ class TestIsLocalMaximum(unittest.TestCase): Test is_local_maximum when every point is a local maximum ''' np.random.seed(31) - image = np.random.uniform(size=(10,20)) + image = np.random.uniform(size=(10, 20)) footprint = np.array([[1]]) - result = is_local_maximum(image, np.ones((10,20)), footprint) + result = is_local_maximum(image, np.ones((10, 20)), footprint) self.assertTrue(np.all(result)) result = is_local_maximum(image, footprint=footprint) self.assertTrue(np.all(result)) diff --git a/skimage/morphology/watershed.py b/skimage/morphology/watershed.py index 71eaf113..c0b1b34b 100644 --- a/skimage/morphology/watershed.py +++ b/skimage/morphology/watershed.py @@ -24,13 +24,12 @@ All rights reserved. Original author: Lee Kamentsky """ -from _heapq import heapify, heappush, heappop +from _heapq import heappush, heappop import numpy as np import scipy.ndimage from ..filter import rank_order from . import _watershed -import warnings def watershed(image, markers, connectivity=None, offset=None, mask=None): @@ -123,17 +122,17 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None): The algorithm works also for 3-D images, and can be used for example to separate overlapping spheres. """ - + if connectivity == None: c_connectivity = scipy.ndimage.generate_binary_structure(image.ndim, 1) else: c_connectivity = np.array(connectivity, bool) if c_connectivity.ndim != image.ndim: - raise ValueError,"Connectivity dimension must be same as image" + raise ValueError("Connectivity dimension must be same as image") if offset == None: - if any([x%2==0 for x in c_connectivity.shape]): - raise ValueError,"Connectivity array must have an unambiguous \ - center" + if any([x % 2 == 0 for x in c_connectivity.shape]): + raise ValueError("Connectivity array must have an unambiguous " + "center") # # offset to center of connectivity array # @@ -144,7 +143,7 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None): pads = offset def pad(im): - new_im = np.zeros([i + 2*p for i, p in zip(im.shape, pads)], im.dtype) + new_im = np.zeros([i + 2 * p for i, p in zip(im.shape, pads)], im.dtype) new_im[[slice(p, -p, None) for p in pads]] = im return new_im @@ -158,9 +157,8 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None): c_image = rank_order(image)[0].astype(np.int32) c_markers = np.ascontiguousarray(markers, dtype=np.int32) if c_markers.ndim != c_image.ndim: - raise ValueError,\ - "markers (ndim=%d) must have same # of dimensions "\ - "as image (ndim=%d)"%(c_markers.ndim, cimage.ndim) + raise ValueError("markers (ndim=%d) must have same # of dimensions " + "as image (ndim=%d)" % (c_markers.ndim, c_image.ndim)) if c_markers.shape != c_image.shape: raise ValueError("image and markers must have the same shape") if mask != None: @@ -190,7 +188,6 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None): indexes = [] ignore = True for j in range(len(c_connectivity.shape)): - elems = c_image.shape[j] idx = (i // multiplier) % c_connectivity.shape[j] off = idx - offset[j] if off: @@ -231,7 +228,7 @@ def watershed(image, markers, connectivity=None, offset=None, mask=None): def is_local_maximum(image, labels=None, footprint=None): """ Return a boolean array of points that are local maxima - + Parameters ---------- image: ndarray (2-D, 3-D, ...) diff --git a/skimage/transform/radon_transform.py b/skimage/transform/radon_transform.py index d185c0fc..b94414c2 100644 --- a/skimage/transform/radon_transform.py +++ b/skimage/transform/radon_transform.py @@ -140,7 +140,6 @@ def iradon(radon_image, theta=None, output_size=None, # zero pad input image img.resize((order, img.shape[1])) # construct the fourier filter - freqs = np.zeros((order, 1)) f = fftshift(abs(np.mgrid[-1:1:2 / order])).reshape(-1, 1) w = 2 * np.pi * f diff --git a/skimage/transform/tests/test_hough_transform.py b/skimage/transform/tests/test_hough_transform.py index 7472ebe0..03b63d07 100644 --- a/skimage/transform/tests/test_hough_transform.py +++ b/skimage/transform/tests/test_hough_transform.py @@ -59,8 +59,9 @@ def test_probabilistic_hough(): img[i, i] = 100 # decrease default theta sampling because similar orientations may confuse # as mentioned in article of Galambos et al - theta=np.linspace(0, np.pi, 45) - lines = probabilistic_hough(img, theta=theta, threshold=10, line_length=10, line_gap=1) + theta = np.linspace(0, np.pi, 45) + lines = probabilistic_hough(img, theta=theta, threshold=10, line_length=10, + line_gap=1) # sort the lines according to the x-axis sorted_lines = [] for line in lines: @@ -73,4 +74,3 @@ def test_probabilistic_hough(): if __name__ == "__main__": run_module_suite() - diff --git a/skimage/transform/tests/test_project.py b/skimage/transform/tests/test_project.py index 011c6e9c..25ebda20 100644 --- a/skimage/transform/tests/test_project.py +++ b/skimage/transform/tests/test_project.py @@ -6,6 +6,7 @@ from skimage.transform import homography, fast_homography from skimage import data from skimage.color import rgb2gray + def test_stackcopy(): layers = 4 x = np.empty((3, 3, layers)) @@ -17,10 +18,10 @@ def test_stackcopy(): def test_homography(): x = np.arange(9, dtype=np.uint8).reshape((3, 3)) + 1 - theta = -np.pi/2 - M = np.array([[np.cos(theta),-np.sin(theta),0], - [np.sin(theta), np.cos(theta),2], - [0, 0, 1]]) + theta = -np.pi / 2 + M = np.array([[np.cos(theta), -np.sin(theta), 0], + [np.sin(theta), np.cos(theta), 2], + [0, 0, 1]]) x90 = homography(x, M, order=1) assert_array_almost_equal(x90, np.rot90(x)) diff --git a/skimage/transform/tests/test_radon_transform.py b/skimage/transform/tests/test_radon_transform.py index 0c783651..f8e9416f 100644 --- a/skimage/transform/tests/test_radon_transform.py +++ b/skimage/transform/tests/test_radon_transform.py @@ -40,6 +40,7 @@ def test_radon_iradon(): image = np.tri(size) + np.tri(size)[::-1] reconstructed = iradon(radon(image), filter="ramp", interpolation="nearest") + def test_iradon_angles(): """ Test with different number of projections @@ -62,10 +63,12 @@ def test_iradon_angles(): s = radon_image_80.sum(axis=0) assert np.allclose(s, s[0], rtol=0.01) reconstructed = iradon(radon_image_80) - delta_80 = np.mean(abs(image/np.max(image) - reconstructed/np.max(reconstructed))) + delta_80 = np.mean(abs(image / np.max(image) - + reconstructed / np.max(reconstructed))) # Loss of quality when the number of projections is reduced assert delta_80 > delta_200 + def test_radon_minimal(): """ Test for small images for various angles