diff --git a/skimage/_shared/_warnings.py b/skimage/_shared/_warnings.py index c4cd0a68..78d38fbd 100644 --- a/skimage/_shared/_warnings.py +++ b/skimage/_shared/_warnings.py @@ -1,9 +1,10 @@ -__all__ = ['all_warnings'] +__all__ = ['all_warnings', 'expected_warnings'] from contextlib import contextmanager import sys import warnings import inspect +import re @contextmanager @@ -61,3 +62,54 @@ def all_warnings(): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") yield w + + +@contextmanager +def expected_warnings(matching): + """Context for use in testing to catch known warnings matching regexes + + Parameters + ---------- + matching : list of strings or compiled regexes + Regexes for the desired warning to catch + + + Examples + -------- + >>> from skimage import data, img_as_ubyte, img_as_float + >>> with expected_warnings(['precision loss']): + ... d = img_as_ubyte(img_as_float(data.coins())) + + Notes + ----- + Uses `all_warnings` to ensure all warnings are raised. + Upon exiting, it checks the recorded warnings for the desired matching + pattern(s). + Raises a ValueError if any match was not found or an unexpected + warning was raised. + Allows for three types of behaviors: "and", "or", and "optional" matches. + This is done to accomodate different build enviroments or loop conditions + that may produce different warnings. The behaviors can be combined. + If you pass multiple patterns, you get an orderless "and", where all of the + warnings must be raised. + If you use the "|" operator in a pattern, you can catch one of several warnings. + Finally, you can use "|\A\Z" in a pattern to signify it as optional. + + """ + with all_warnings() as w: + # enter context + yield w + # exited user context, check the recorded warnings + remaining = [m for m in matching if not '\A\Z' in m.split('|')] + for warn in w: + found = False + for match in matching: + if re.search(match, str(warn.message)) is not None: + found = True + if match in remaining: + remaining.remove(match) + if not found: + raise ValueError('Unexpected warning: %s' % str(warn.message)) + if len(remaining) > 0: + msg = 'No warning raised matching:\n%s' % '\n'.join(remaining) + raise ValueError(msg) diff --git a/skimage/_shared/testing.py b/skimage/_shared/testing.py index 0cf65cb4..0f556acf 100644 --- a/skimage/_shared/testing.py +++ b/skimage/_shared/testing.py @@ -9,6 +9,8 @@ from skimage import ( data, io, img_as_uint, img_as_float, img_as_int, img_as_ubyte) from numpy import testing import numpy as np +from skimage._shared._warnings import expected_warnings +import warnings SKIP_RE = re.compile("(\s*>>>.*?)(\s*)#\s*skip\s+if\s+(.*)$") @@ -115,20 +117,25 @@ def color_check(plugin, fmt='png'): testing.assert_allclose(img2.astype(np.uint8), r2) img3 = img_as_float(img) - r3 = roundtrip(img3, plugin, fmt) + with expected_warnings(['precision loss|unclosed file']): + r3 = roundtrip(img3, plugin, fmt) testing.assert_allclose(r3, img) - img4 = img_as_int(img) + with expected_warnings(['precision loss']): + img4 = img_as_int(img) if fmt.lower() in (('tif', 'tiff')): img4 -= 100 - r4 = roundtrip(img4, plugin, fmt) + with expected_warnings(['sign loss']): + r4 = roundtrip(img4, plugin, fmt) testing.assert_allclose(r4, img4) else: - r4 = roundtrip(img4, plugin, fmt) - testing.assert_allclose(r4, img_as_ubyte(img4)) + with expected_warnings(['sign loss|precision loss|unclosed file']): + r4 = roundtrip(img4, plugin, fmt) + testing.assert_allclose(r4, img_as_ubyte(img4)) img5 = img_as_uint(img) - r5 = roundtrip(img5, plugin, fmt) + with expected_warnings(['precision loss|unclosed file']): + r5 = roundtrip(img5, plugin, fmt) testing.assert_allclose(r5, img) @@ -147,26 +154,53 @@ def mono_check(plugin, fmt='png'): testing.assert_allclose(img2.astype(np.uint8), r2) img3 = img_as_float(img) - r3 = roundtrip(img3, plugin, fmt) + with expected_warnings(['precision|unclosed file|\A\Z']): + r3 = roundtrip(img3, plugin, fmt) if r3.dtype.kind == 'f': testing.assert_allclose(img3, r3) else: testing.assert_allclose(r3, img_as_uint(img)) - img4 = img_as_int(img) + with expected_warnings(['precision loss']): + img4 = img_as_int(img) if fmt.lower() in (('tif', 'tiff')): img4 -= 100 - r4 = roundtrip(img4, plugin, fmt) + with expected_warnings(['sign loss|\A\Z']): + r4 = roundtrip(img4, plugin, fmt) testing.assert_allclose(r4, img4) else: - r4 = roundtrip(img4, plugin, fmt) - testing.assert_allclose(r4, img_as_uint(img4)) + with expected_warnings(['precision loss|sign loss|unclosed file']): + r4 = roundtrip(img4, plugin, fmt) + testing.assert_allclose(r4, img_as_uint(img4)) img5 = img_as_uint(img) r5 = roundtrip(img5, plugin, fmt) testing.assert_allclose(r5, img5) +def setup_test(): + """Default package level setup routine for skimage tests. + + Import packages known to raise errors, and then + force warnings to raise errors. + Set a random seed + """ + warnings.simplefilter('default') + from scipy import signal, ndimage, special, optimize, linalg + from scipy.io import loadmat + from skimage import viewer, filter + np.random.seed(0) + warnings.simplefilter('error') + + +def teardown_test(): + """Default package level teardown routine for skimage tests. + + Restore warnings to default behavior + """ + warnings.simplefilter('default') + + if __name__ == '__main__': color_check('pil') mono_check('pil') diff --git a/skimage/_shared/tests/__init__.py b/skimage/_shared/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/_shared/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/color/tests/__init__.py b/skimage/color/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/color/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/color/tests/test_adapt_rgb.py b/skimage/color/tests/test_adapt_rgb.py index 2f3060c5..9e97b6b6 100644 --- a/skimage/color/tests/test_adapt_rgb.py +++ b/skimage/color/tests/test_adapt_rgb.py @@ -3,54 +3,55 @@ from functools import partial import numpy as np from skimage import img_as_float, img_as_uint -from skimage import color, data, filter +from skimage import color, data, filters from skimage.color.adapt_rgb import adapt_rgb, each_channel, hsv_value - +from skimage._shared._warnings import expected_warnings # Down-sample image for quicker testing. COLOR_IMAGE = data.astronaut()[::5, ::5] GRAY_IMAGE = data.camera()[::5, ::5] SIGMA = 3 -smooth = partial(filter.gaussian_filter, sigma=SIGMA) +smooth = partial(filters.gaussian_filter, sigma=SIGMA) assert_allclose = partial(np.testing.assert_allclose, atol=1e-8) @adapt_rgb(each_channel) def edges_each(image): - return filter.sobel(image) + return filters.sobel(image) @adapt_rgb(each_channel) def smooth_each(image, sigma): - return filter.gaussian_filter(image, sigma) + return filters.gaussian_filter(image, sigma) @adapt_rgb(hsv_value) def edges_hsv(image): - return filter.sobel(image) + return filters.sobel(image) @adapt_rgb(hsv_value) def smooth_hsv(image, sigma): - return filter.gaussian_filter(image, sigma) + return filters.gaussian_filter(image, sigma) @adapt_rgb(hsv_value) def edges_hsv_uint(image): - return img_as_uint(filter.sobel(image)) + with expected_warnings(['precision loss']): + return img_as_uint(filters.sobel(image)) def test_gray_scale_image(): # We don't need to test both `hsv_value` and `each_channel` since # `adapt_rgb` is handling gray-scale inputs. - assert_allclose(edges_each(GRAY_IMAGE), filter.sobel(GRAY_IMAGE)) + assert_allclose(edges_each(GRAY_IMAGE), filters.sobel(GRAY_IMAGE)) def test_each_channel(): filtered = edges_each(COLOR_IMAGE) for i, channel in enumerate(np.rollaxis(filtered, axis=-1)): - expected = img_as_float(filter.sobel(COLOR_IMAGE[:, :, i])) + expected = img_as_float(filters.sobel(COLOR_IMAGE[:, :, i])) assert_allclose(channel, expected) @@ -63,7 +64,7 @@ def test_each_channel_with_filter_argument(): def test_hsv_value(): filtered = edges_hsv(COLOR_IMAGE) value = color.rgb2hsv(COLOR_IMAGE)[:, :, 2] - assert_allclose(color.rgb2hsv(filtered)[:, :, 2], filter.sobel(value)) + assert_allclose(color.rgb2hsv(filtered)[:, :, 2], filters.sobel(value)) def test_hsv_value_with_filter_argument(): @@ -80,4 +81,4 @@ def test_hsv_value_with_non_float_output(): filtered_value = color.rgb2hsv(filtered)[:, :, 2] value = color.rgb2hsv(COLOR_IMAGE)[:, :, 2] # Reduce tolerance because dtype conversion. - assert_allclose(filtered_value, filter.sobel(value), rtol=1e-5, atol=1e-5) + assert_allclose(filtered_value, filters.sobel(value), rtol=1e-5, atol=1e-5) diff --git a/skimage/color/tests/test_colorconv.py b/skimage/color/tests/test_colorconv.py index cf960f4e..094873ae 100644 --- a/skimage/color/tests/test_colorconv.py +++ b/skimage/color/tests/test_colorconv.py @@ -39,12 +39,11 @@ from skimage.color import (rgb2hsv, hsv2rgb, guess_spatial_dimensions ) -from skimage import data_dir, data +from skimage import data_dir +from skimage._shared._warnings import expected_warnings import colorsys -np.random.seed(0) - def test_guess_spatial_dimensions(): im1 = np.zeros((5, 5)) @@ -156,7 +155,9 @@ class TestColorconv(TestCase): # RGB<->HED roundtrip with ubyte image def test_hed_rgb_roundtrip(self): img_rgb = img_as_ubyte(self.img_rgb) - assert_equal(img_as_ubyte(hed2rgb(rgb2hed(img_rgb))), img_rgb) + with expected_warnings(['precision loss']): + new = img_as_ubyte(hed2rgb(rgb2hed(img_rgb))) + assert_equal(new, img_rgb) # RGB<->HED roundtrip with float image def test_hed_rgb_float_roundtrip(self): diff --git a/skimage/color/tests/test_colorlabel.py b/skimage/color/tests/test_colorlabel.py index 4daf3a66..277cec5b 100644 --- a/skimage/color/tests/test_colorlabel.py +++ b/skimage/color/tests/test_colorlabel.py @@ -3,7 +3,7 @@ import itertools import numpy as np from numpy import testing from skimage.color.colorlabel import label2rgb -from skimage._shared.utils import all_warnings +from skimage._shared._warnings import expected_warnings from numpy.testing import (assert_array_almost_equal as assert_close, assert_array_equal, assert_warns) @@ -125,10 +125,9 @@ def test_avg(): def test_negative_intensity(): - with all_warnings(): - labels = np.arange(100).reshape(10, 10) - image = -1 * np.ones((10, 10)) - assert_warns(UserWarning, label2rgb, labels, image) + labels = np.arange(100).reshape(10, 10) + image = -1 * np.ones((10, 10)) + assert_warns(UserWarning, label2rgb, labels, image) if __name__ == '__main__': diff --git a/skimage/data/__init__.py b/skimage/data/__init__.py index a6b39468..81514ce9 100644 --- a/skimage/data/__init__.py +++ b/skimage/data/__init__.py @@ -8,7 +8,7 @@ For more images, see import os as _os -from ..io import imread +from ..io import imread, use_plugin from skimage import data_dir @@ -42,6 +42,7 @@ def load(f): img : ndarray Image loaded from skimage.data_dir. """ + use_plugin('pil') return imread(_os.path.join(data_dir, f)) diff --git a/skimage/data/tests/__init__.py b/skimage/data/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/data/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/draw/tests/__init__.py b/skimage/draw/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/draw/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/exposure/tests/__init__.py b/skimage/exposure/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/exposure/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/exposure/tests/test_exposure.py b/skimage/exposure/tests/test_exposure.py index ec9840ee..1316ea4e 100644 --- a/skimage/exposure/tests/test_exposure.py +++ b/skimage/exposure/tests/test_exposure.py @@ -11,6 +11,7 @@ from skimage import exposure from skimage.exposure.exposure import intensity_range from skimage.color import rgb2gray from skimage.util.dtype import dtype_range +from skimage._shared._warnings import expected_warnings # Test integer histograms @@ -52,7 +53,8 @@ def test_equalize_uint8_approx(): def test_equalize_ubyte(): - img = skimage.img_as_ubyte(test_img) + with expected_warnings(['precision loss']): + img = skimage.img_as_ubyte(test_img) img_eq = exposure.equalize_hist(img) cdf, bin_edges = exposure.cumulative_distribution(img_eq) @@ -209,8 +211,9 @@ def test_adapthist_grayscale(): img = skimage.img_as_float(data.astronaut()) img = rgb2gray(img) img = np.dstack((img, img, img)) - adapted = exposure.equalize_adapthist(img, 10, 9, clip_limit=0.01, - nbins=128) + with expected_warnings(['precision loss|non-contiguous input']): + adapted = exposure.equalize_adapthist(img, 10, 9, clip_limit=0.01, + nbins=128) assert_almost_equal = np.testing.assert_almost_equal assert img.shape == adapted.shape assert_almost_equal(peak_snr(img, adapted), 97.6876, 3) @@ -226,7 +229,8 @@ def test_adapthist_color(): warnings.simplefilter('always') hist, bin_centers = exposure.histogram(img) assert len(w) > 0 - adapted = exposure.equalize_adapthist(img, clip_limit=0.01) + with expected_warnings(['precision loss']): + adapted = exposure.equalize_adapthist(img, clip_limit=0.01) assert_almost_equal = np.testing.assert_almost_equal assert adapted.min() == 0 @@ -244,7 +248,8 @@ def test_adapthist_alpha(): img = skimage.img_as_float(data.astronaut()) alpha = np.ones((img.shape[0], img.shape[1]), dtype=float) img = np.dstack((img, alpha)) - adapted = exposure.equalize_adapthist(img) + with expected_warnings(['precision loss']): + adapted = exposure.equalize_adapthist(img) assert adapted.shape != img.shape img = img[:, :, :3] full_scale = skimage.exposure.rescale_intensity(img) diff --git a/skimage/feature/tests/__init__.py b/skimage/feature/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/feature/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/filters/rank/tests/__init__.py b/skimage/filters/rank/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/filters/rank/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/filters/rank/tests/test_rank.py b/skimage/filters/rank/tests/test_rank.py index 23745ebf..64c3ca97 100644 --- a/skimage/filters/rank/tests/test_rank.py +++ b/skimage/filters/rank/tests/test_rank.py @@ -3,15 +3,19 @@ import numpy as np from numpy.testing import run_module_suite, assert_equal, assert_raises import skimage -from skimage import img_as_ubyte, img_as_uint, img_as_float +from skimage import img_as_ubyte, img_as_float from skimage import data, util, morphology from skimage.morphology import cmorph, disk from skimage.filters import rank - -np.random.seed(0) +from skimage._shared._warnings import expected_warnings def test_all(): + with expected_warnings(['precision loss', 'non-integer|\A\Z']): + check_all() + + +def check_all(): image = np.random.rand(25, 25) selem = morphology.disk(1) refs = np.load(os.path.join(skimage.data_dir, "rank_filter_tests.npz")) @@ -151,8 +155,13 @@ def test_bitdepth(): for i in range(5): image = np.ones((100, 100), dtype=np.uint16) * 255 * 2 ** i - r = rank.mean_percentile(image=image, selem=elem, mask=mask, - out=out, shift_x=0, shift_y=0, p0=.1, p1=.9) + if i > 3: + expected = ["Bitdepth of"] + else: + expected = [] + with expected_warnings(expected): + rank.mean_percentile(image=image, selem=elem, mask=mask, + out=out, shift_x=0, shift_y=0, p0=.1, p1=.9) def test_population(): @@ -261,7 +270,8 @@ def test_compare_ubyte_vs_float(): for method in methods: func = getattr(rank, method) out_u = func(image_uint, disk(3)) - out_f = func(image_float, disk(3)) + with expected_warnings(['precision loss']): + out_f = func(image_float, disk(3)) assert_equal(out_u, out_f) @@ -273,9 +283,9 @@ def test_compare_8bit_unsigned_vs_signed(): image = img_as_ubyte(data.camera()) image[image > 127] = 0 image_s = image.astype(np.int8) - image_u = img_as_ubyte(image_s) - - assert_equal(image_u, img_as_ubyte(image_s)) + with expected_warnings(['sign loss', 'precision loss']): + image_u = img_as_ubyte(image_s) + assert_equal(image_u, img_as_ubyte(image_s)) methods = ['autolevel', 'bottomhat', 'equalize', 'gradient', 'maximum', 'mean', 'subtract_mean', 'median', 'minimum', 'modal', @@ -283,8 +293,10 @@ def test_compare_8bit_unsigned_vs_signed(): for method in methods: func = getattr(rank, method) - out_u = func(image_u, disk(3)) - out_s = func(image_s, disk(3)) + + with expected_warnings(['sign loss', 'precision loss']): + out_u = func(image_u, disk(3)) + out_s = func(image_s, disk(3)) assert_equal(out_u, out_s) @@ -474,10 +486,12 @@ def test_entropy(): selem = np.ones((64, 64), dtype=np.uint8) data = np.tile( np.reshape(np.arange(4096), (64, 64)), (2, 2)).astype(np.uint16) - assert(np.max(rank.entropy(data, selem)) == 12) + with expected_warnings(['Bitdepth of 11']): + assert(np.max(rank.entropy(data, selem)) == 12) # make sure output is of dtype double - out = rank.entropy(data, np.ones((16, 16), dtype=np.uint8)) + with expected_warnings(['Bitdepth of 11']): + out = rank.entropy(data, np.ones((16, 16), dtype=np.uint8)) assert out.dtype == np.double @@ -508,10 +522,14 @@ def test_16bit(): for bitdepth in range(17): value = 2 ** bitdepth - 1 image[10, 10] = value - assert rank.minimum(image, selem)[10, 10] == 0 - assert rank.maximum(image, selem)[10, 10] == value - assert rank.mean(image, selem)[10, 10] == int(value / selem.size) - + if bitdepth > 11: + expected = ['Bitdepth of %s' % (bitdepth - 1)] + else: + expected = [] + with expected_warnings(expected): + assert rank.minimum(image, selem)[10, 10] == 0 + assert rank.maximum(image, selem)[10, 10] == value + assert rank.mean(image, selem)[10, 10] == int(value / selem.size) def test_bilateral(): image = np.zeros((21, 21), dtype=np.uint16) diff --git a/skimage/filters/tests/__init__.py b/skimage/filters/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/filters/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/filters/tests/test_gaussian.py b/skimage/filters/tests/test_gaussian.py index 612dd9e4..c88ee1f8 100644 --- a/skimage/filters/tests/test_gaussian.py +++ b/skimage/filters/tests/test_gaussian.py @@ -1,5 +1,6 @@ import numpy as np from skimage.filters._gaussian import gaussian_filter +from skimage._shared._warnings import expected_warnings def test_null_sigma(): @@ -25,7 +26,8 @@ def test_multichannel(): assert np.allclose([a[..., i].mean() for i in range(3)], [gaussian_rgb_a[..., i].mean() for i in range(3)]) # Test multichannel = None - gaussian_rgb_a = gaussian_filter(a, sigma=1, mode='reflect') + with expected_warnings(['multichannel']): + gaussian_rgb_a = gaussian_filter(a, sigma=1, mode='reflect') # Check that the mean value is conserved in each channel # (color channels are not mixed together) assert np.allclose([a[..., i].mean() for i in range(3)], diff --git a/skimage/filters/thresholding.py b/skimage/filters/thresholding.py index 5a737293..c95e56d2 100644 --- a/skimage/filters/thresholding.py +++ b/skimage/filters/thresholding.py @@ -121,7 +121,7 @@ def threshold_otsu(image, nbins=256): >>> thresh = threshold_otsu(image) >>> binary = image <= thresh """ - hist, bin_centers = histogram(image, nbins) + hist, bin_centers = histogram(image.ravel(), nbins) hist = hist.astype(float) # class probabilities for all possible thresholds @@ -176,7 +176,7 @@ def threshold_yen(image, nbins=256): >>> thresh = threshold_yen(image) >>> binary = image <= thresh """ - hist, bin_centers = histogram(image, nbins) + hist, bin_centers = histogram(image.ravel(), nbins) # On blank images (e.g. filled with 0) with int dtype, `histogram()` # returns `bin_centers` containing only one value. Speed up with it. if bin_centers.size == 1: @@ -246,7 +246,7 @@ def threshold_isodata(image, nbins=256, return_all=False): >>> binary = image > thresh """ - hist, bin_centers = histogram(image, nbins) + hist, bin_centers = histogram(image.ravel(), nbins) # image only contains one unique value if len(bin_centers) == 1: diff --git a/skimage/graph/tests/__init__.py b/skimage/graph/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/graph/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/io/_plugins/pil_plugin.py b/skimage/io/_plugins/pil_plugin.py index 5018be49..9f9118cf 100644 --- a/skimage/io/_plugins/pil_plugin.py +++ b/skimage/io/_plugins/pil_plugin.py @@ -100,7 +100,7 @@ def pil_to_ndarray(im, dtype=None, img_num=None): dtype = '>u2' if im.mode.endswith('B') else '>> from skimage.measure import label - >>> print(label(x, neighbors=4)) + >>> print(label(x, connectivity=1)) [[0 1 1] [2 3 1] [2 2 4]] - >>> print(label(x, neighbors=8)) + >>> print(label(x, connectivity=2)) [[0 1 1] [1 0 1] [1 1 0]] diff --git a/skimage/measure/_label.py b/skimage/measure/_label.py index 47e8af74..e3ac6034 100644 --- a/skimage/measure/_label.py +++ b/skimage/measure/_label.py @@ -1,6 +1,7 @@ from ._ccomp import label as _label -def label(input, neighbors=8, background=None, return_num=False): - return _label(input, neighbors, background, return_num) +def label(input, neighbors=None, background=None, return_num=False, + connectivity=None): + return _label(input, neighbors, background, return_num, connectivity) label.__doc__ = _label.__doc__ diff --git a/skimage/measure/_regionprops.py b/skimage/measure/_regionprops.py index 070b49a4..66a8734f 100644 --- a/skimage/measure/_regionprops.py +++ b/skimage/measure/_regionprops.py @@ -473,11 +473,13 @@ def regionprops(label_image, intensity_image=None, cache=True): >>> from skimage import data, util >>> from skimage.morphology import label >>> img = util.img_as_ubyte(data.coins()) > 110 - >>> label_img = label(img) + >>> label_img = label(img, connectivity=img.ndim) >>> props = regionprops(label_img) - >>> props[0].centroid # centroid of first labeled object + >>> # centroid of first labeled object + >>> props[0].centroid (22.729879860483141, 81.912285234465827) - >>> props[0]['centroid'] # centroid of first labeled object + >>> # centroid of first labeled object + >>> props[0]['centroid'] (22.729879860483141, 81.912285234465827) """ diff --git a/skimage/measure/tests/__init__.py b/skimage/measure/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/measure/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/measure/tests/test_fit.py b/skimage/measure/tests/test_fit.py index 32d9ef22..c2a71f71 100644 --- a/skimage/measure/tests/test_fit.py +++ b/skimage/measure/tests/test_fit.py @@ -3,6 +3,7 @@ from numpy.testing import assert_equal, assert_raises, assert_almost_equal from skimage.measure import LineModel, CircleModel, EllipseModel, ransac from skimage.transform import AffineTransform from skimage.measure.fit import _dynamic_max_trials +from skimage._shared._warnings import expected_warnings def test_line_model_invalid_input(): @@ -180,7 +181,7 @@ def test_ransac_geometric(): model_est, inliers = ransac((src, dst), AffineTransform, 2, 20) # test whether estimated parameters equal original parameters - assert_almost_equal(model0._matrix, model_est._matrix) + assert_almost_equal(model0.params, model_est.params) assert np.all(np.nonzero(inliers == False)[0] == outliers) @@ -255,7 +256,8 @@ def test_deprecated_params_attribute(): model.params = (10, 1) x = np.arange(-10, 10) y = model.predict_y(x) - assert_equal(model.params, model._params) + with expected_warnings(['`_params`']): + assert_equal(model.params, model._params) if __name__ == "__main__": diff --git a/skimage/measure/tests/test_regionprops.py b/skimage/measure/tests/test_regionprops.py index 934e209e..5a14aba5 100644 --- a/skimage/measure/tests/test_regionprops.py +++ b/skimage/measure/tests/test_regionprops.py @@ -4,6 +4,7 @@ import numpy as np import math from skimage.measure._regionprops import regionprops, PROPS, perimeter +from skimage._shared._warnings import expected_warnings SAMPLE = np.array( @@ -125,12 +126,14 @@ def test_equiv_diameter(): def test_euler_number(): - en = regionprops(SAMPLE)[0].euler_number + with expected_warnings(['`background`']): + en = regionprops(SAMPLE)[0].euler_number assert en == 0 SAMPLE_mod = SAMPLE.copy() SAMPLE_mod[7, -3] = 0 - en = regionprops(SAMPLE_mod)[0].euler_number + with expected_warnings(['`background`']): + en = regionprops(SAMPLE_mod)[0].euler_number assert en == -1 @@ -369,8 +372,9 @@ def test_equals(): r2 = regions[0] r3 = regions[1] - assert_equal(r1 == r2, True, "Same regionprops are not equal") - assert_equal(r1 != r3, True, "Different regionprops are equal") + with expected_warnings(['`background`']): + assert_equal(r1 == r2, True, "Same regionprops are not equal") + assert_equal(r1 != r3, True, "Different regionprops are equal") if __name__ == "__main__": diff --git a/skimage/morphology/tests/__init__.py b/skimage/morphology/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/morphology/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/morphology/tests/test_binary.py b/skimage/morphology/tests/test_binary.py index 53ad504e..d52f92bb 100644 --- a/skimage/morphology/tests/test_binary.py +++ b/skimage/morphology/tests/test_binary.py @@ -4,6 +4,7 @@ from numpy import testing from skimage import data, color from skimage.util import img_as_bool from skimage.morphology import binary, grey, selem +from skimage._shared._warnings import expected_warnings from scipy import ndimage @@ -14,35 +15,40 @@ bw_img = img > 100 def test_non_square_image(): strel = selem.square(3) binary_res = binary.binary_erosion(bw_img[:100, :200], strel) - grey_res = img_as_bool(grey.erosion(bw_img[:100, :200], strel)) + with expected_warnings(['precision loss']): + grey_res = img_as_bool(grey.erosion(bw_img[:100, :200], strel)) testing.assert_array_equal(binary_res, grey_res) def test_binary_erosion(): strel = selem.square(3) binary_res = binary.binary_erosion(bw_img, strel) - grey_res = img_as_bool(grey.erosion(bw_img, strel)) + with expected_warnings(['precision loss']): + grey_res = img_as_bool(grey.erosion(bw_img, strel)) testing.assert_array_equal(binary_res, grey_res) def test_binary_dilation(): strel = selem.square(3) binary_res = binary.binary_dilation(bw_img, strel) - grey_res = img_as_bool(grey.dilation(bw_img, strel)) + with expected_warnings(['precision loss']): + grey_res = img_as_bool(grey.dilation(bw_img, strel)) testing.assert_array_equal(binary_res, grey_res) def test_binary_closing(): strel = selem.square(3) binary_res = binary.binary_closing(bw_img, strel) - grey_res = img_as_bool(grey.closing(bw_img, strel)) + with expected_warnings(['precision loss']): + grey_res = img_as_bool(grey.closing(bw_img, strel)) testing.assert_array_equal(binary_res, grey_res) def test_binary_opening(): strel = selem.square(3) binary_res = binary.binary_opening(bw_img, strel) - grey_res = img_as_bool(grey.opening(bw_img, strel)) + with expected_warnings(['precision loss']): + grey_res = img_as_bool(grey.opening(bw_img, strel)) testing.assert_array_equal(binary_res, grey_res) @@ -51,7 +57,8 @@ def test_selem_overflow(): img = np.zeros((20, 20)) img[2:19, 2:19] = 1 binary_res = binary.binary_erosion(img, strel) - grey_res = img_as_bool(grey.erosion(img, strel)) + with expected_warnings(['precision loss']): + grey_res = img_as_bool(grey.erosion(img, strel)) testing.assert_array_equal(binary_res, grey_res) diff --git a/skimage/morphology/tests/test_ccomp.py b/skimage/morphology/tests/test_ccomp.py index aebb443a..901a18b9 100644 --- a/skimage/morphology/tests/test_ccomp.py +++ b/skimage/morphology/tests/test_ccomp.py @@ -1,12 +1,10 @@ import numpy as np from numpy.testing import assert_array_equal, run_module_suite -from skimage.morphology import label +from skimage.measure import label import skimage.measure._ccomp as ccomp -from warnings import catch_warnings -from skimage._shared.utils import skimage_deprecation +from skimage._shared._warnings import expected_warnings -np.random.seed(0) # The background label value # is supposed to be changed to 0 soon @@ -26,7 +24,8 @@ class TestConnectedComponents: [6, 5, 5, 7, 8, 9]]) def test_basic(self): - assert_array_equal(label(self.x), self.labels) + with expected_warnings(['`background`']): + assert_array_equal(label(self.x), self.labels) # Make sure data wasn't modified assert self.x[0, 2] == 3 @@ -34,7 +33,7 @@ class TestConnectedComponents: def test_random(self): x = (np.random.rand(20, 30) * 5).astype(np.int) - with catch_warnings(): + with expected_warnings(['`background`']): labels = label(x) n = labels.max() @@ -46,13 +45,13 @@ class TestConnectedComponents: x = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]]) - with catch_warnings(): + with expected_warnings(['`background`']): assert_array_equal(label(x), x) def test_4_vs_8(self): x = np.array([[0, 1], [1, 0]], dtype=int) - with catch_warnings(): + with expected_warnings(['`background`']): assert_array_equal(label(x, 4), [[0, 1], [2, 3]]) @@ -65,7 +64,7 @@ class TestConnectedComponents: [1, 1, 5], [0, 0, 0]]) - with catch_warnings(): + with expected_warnings(['`background`']): assert_array_equal(label(x), [[0, 1, 1], [0, 0, 2], [3, 3, 3]]) @@ -101,7 +100,7 @@ class TestConnectedComponents: [0, 0, 6], [5, 5, 5]]) - with catch_warnings(): + with expected_warnings(['`background`']): assert_array_equal(label(x, return_num=True)[1], 4) assert_array_equal(label(x, background=0, return_num=True)[1], 3) @@ -143,7 +142,8 @@ class TestConnectedComponents3d: [10, 5, 7, 7, 7]]) def test_basic(self): - labels = label(self.x) + with expected_warnings(['`background`']): + labels = label(self.x) assert_array_equal(labels, self.labels) assert self.x[0, 0, 2] == 2, \ @@ -152,7 +152,7 @@ class TestConnectedComponents3d: def test_random(self): x = (np.random.rand(20, 30) * 5).astype(np.int) - with catch_warnings(): + with expected_warnings(['`background`']): labels = label(x) n = labels.max() @@ -165,7 +165,7 @@ class TestConnectedComponents3d: x[0, 2, 2] = 1 x[1, 1, 1] = 1 x[2, 0, 0] = 1 - with catch_warnings(): + with expected_warnings(['`background`']): assert_array_equal(label(x), x) def test_4_vs_8(self): @@ -174,7 +174,7 @@ class TestConnectedComponents3d: x[1, 0, 0] = 1 label4 = x.copy() label4[1, 0, 0] = 2 - with catch_warnings(): + with expected_warnings(['`background`']): assert_array_equal(label(x, 4), label4) assert_array_equal(label(x, 8), x) @@ -202,7 +202,7 @@ class TestConnectedComponents3d: [BG, 0, 1], [BG, BG, BG]]) - with catch_warnings(): + with expected_warnings(['`background`']): assert_array_equal(label(x), lnb) assert_array_equal(label(x, background=0), lb) @@ -240,7 +240,7 @@ class TestConnectedComponents3d: [0, 0, 6], [5, 5, 5]]) - with catch_warnings(): + with expected_warnings(['`background`']): assert_array_equal(label(x, return_num=True)[1], 4) assert_array_equal(label(x, background=0, return_num=True)[1], 3) @@ -254,7 +254,8 @@ class TestConnectedComponents3d: (1, xlen, 1), (xlen, 1, 1), (1, 1, xlen)) for reshape in reshapes: x2 = x.reshape(reshape) - labelled = label(x2) + with expected_warnings(['`background`']): + labelled = label(x2) assert_array_equal(y, labelled.flatten()) def test_nd(self): diff --git a/skimage/morphology/tests/test_grey.py b/skimage/morphology/tests/test_grey.py index 00f4ad37..911e0c71 100644 --- a/skimage/morphology/tests/test_grey.py +++ b/skimage/morphology/tests/test_grey.py @@ -7,6 +7,7 @@ from scipy import ndimage import skimage from skimage import data_dir from skimage.morphology import grey, selem +from skimage._shared._warnings import expected_warnings lena = np.load(os.path.join(data_dir, 'lena_GRAY_U8.npy')) @@ -170,9 +171,12 @@ def test_3d_fallback_white_tophat(): image[2, 2:4, 2:4] = 1 image[3, 2:5, 2:5] = 1 image[4, 3:5, 3:5] = 1 - new_image = grey.white_tophat(image) + + with expected_warnings(['operator.*deprecated|\A\Z']): + new_image = grey.white_tophat(image) footprint = ndimage.generate_binary_structure(3,1) - image_expected = ndimage.white_tophat(image,footprint=footprint) + with expected_warnings(['operator.*deprecated|\A\Z']): + image_expected = ndimage.white_tophat(image,footprint=footprint) testing.assert_array_equal(new_image, image_expected) def test_3d_fallback_black_tophat(): @@ -180,9 +184,12 @@ def test_3d_fallback_black_tophat(): image[2, 2:4, 2:4] = 0 image[3, 2:5, 2:5] = 0 image[4, 3:5, 3:5] = 0 - new_image = grey.black_tophat(image) + + with expected_warnings(['operator.*deprecated|\A\Z']): + new_image = grey.black_tophat(image) footprint = ndimage.generate_binary_structure(3,1) - image_expected = ndimage.black_tophat(image,footprint=footprint) + with expected_warnings(['operator.*deprecated|\A\Z']): + image_expected = ndimage.black_tophat(image,footprint=footprint) testing.assert_array_equal(new_image, image_expected) def test_2d_ndimage_equivalence(): @@ -216,10 +223,12 @@ class TestDTypes(): self.expected_closing = np.load(fname_closing)[arrname] def _test_image(self, image): - result_opening = grey.opening(image, self.disk) + with expected_warnings(['precision loss']): + result_opening = grey.opening(image, self.disk) testing.assert_equal(result_opening, self.expected_opening) - result_closing = grey.closing(image, self.disk) + with expected_warnings(['precision loss']): + result_closing = grey.closing(image, self.disk) testing.assert_equal(result_closing, self.expected_closing) def test_float(self): diff --git a/skimage/novice/tests/__init__.py b/skimage/novice/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/novice/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/novice/tests/test_novice.py b/skimage/novice/tests/test_novice.py index a1f750ab..e2aafef0 100644 --- a/skimage/novice/tests/test_novice.py +++ b/skimage/novice/tests/test_novice.py @@ -7,16 +7,12 @@ from skimage import novice from skimage.novice._novice import (array_to_xy_origin, xy_to_array_origin, rgb_transpose) from skimage import data_dir - +from skimage._shared.utils import all_warnings IMAGE_PATH = os.path.join(data_dir, "chelsea.png") SMALL_IMAGE_PATH = os.path.join(data_dir, "block.png") -def _array_2d_to_RGBA(array): - return np.tile(array[:, :, np.newaxis], (1, 1, 4)) - - def _array_2d_to_RGBA(array): return np.tile(array[:, :, np.newaxis], (1, 1, 4)) @@ -62,7 +58,8 @@ def test_modify(): assert p.blue <= 128 s = pic.size - pic.size = (pic.width / 2, pic.height / 2) + with all_warnings(): # precision loss + pic.size = (pic.width / 2, pic.height / 2) assert_equal(pic.size, (int(s[0] / 2), int(s[1] / 2))) assert pic.modified @@ -139,7 +136,8 @@ def test_modified_on_set_pixel(): def test_update_on_save(): pic = novice.Picture(array=np.zeros((3, 3, 3))) - pic.size = (6, 6) + with all_warnings(): # precision loss + pic.size = (6, 6) assert pic.modified assert pic.path is None diff --git a/skimage/restoration/tests/__init__.py b/skimage/restoration/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/restoration/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/restoration/tests/test_unwrap.py b/skimage/restoration/tests/test_unwrap.py index 39723894..e628f4fe 100644 --- a/skimage/restoration/tests/test_unwrap.py +++ b/skimage/restoration/tests/test_unwrap.py @@ -7,6 +7,7 @@ from numpy.testing import (run_module_suite, assert_array_almost_equal_nulp, import warnings from skimage.restoration import unwrap_phase +from skimage._shared._warnings import expected_warnings def assert_phase_almost_equal(a, b, *args, **kwargs): @@ -132,9 +133,12 @@ def test_mask(): assert_array_almost_equal_nulp(image_unwrapped[:, -1], image[i, -1]) # Same tests, but forcing use of the 3D unwrapper by reshaping - image_wrapped_3d = image_wrapped.reshape((1,) + image_wrapped.shape) - image_unwrapped_3d = unwrap_phase(image_wrapped_3d) - image_unwrapped_3d -= image_unwrapped_3d[0, 0, 0] # remove phase shift + with expected_warnings(['length 1 dimension']): + shape = (1,) + image_wrapped.shape + 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] assert_array_almost_equal_nulp(image_unwrapped_3d[:, :, -1], image[i, -1]) diff --git a/skimage/segmentation/tests/__init__.py b/skimage/segmentation/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/segmentation/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/segmentation/tests/test_random_walker.py b/skimage/segmentation/tests/test_random_walker.py index 9d30473b..f2207fde 100644 --- a/skimage/segmentation/tests/test_random_walker.py +++ b/skimage/segmentation/tests/test_random_walker.py @@ -1,6 +1,9 @@ import numpy as np from skimage.segmentation import random_walker from skimage.transform import resize +from skimage._shared._warnings import expected_warnings + +PYAMG_EXPECTED_WARNING = 'pyamg|\A\Z' def make_2d_syntheticdata(lx, ly=None): @@ -74,11 +77,13 @@ def test_2d_cg(): lx = 70 ly = 100 data, labels = make_2d_syntheticdata(lx, ly) - labels_cg = random_walker(data, labels, beta=90, mode='cg') + with expected_warnings(['"cg" mode']): + labels_cg = random_walker(data, labels, beta=90, mode='cg') assert (labels_cg[25:45, 40:60] == 2).all() assert data.shape == labels.shape - full_prob = random_walker(data, labels, beta=90, mode='cg', - return_full_prob=True) + with expected_warnings(['"cg" mode']): + full_prob = random_walker(data, labels, beta=90, mode='cg', + return_full_prob=True) assert (full_prob[1, 25:45, 40:60] >= full_prob[0, 25:45, 40:60]).all() assert data.shape == labels.shape @@ -89,10 +94,13 @@ def test_2d_cg_mg(): lx = 70 ly = 100 data, labels = make_2d_syntheticdata(lx, ly) - labels_cg_mg = random_walker(data, labels, beta=90, mode='cg_mg') + expected = 'scipy.sparse.sparsetools|%s' % PYAMG_EXPECTED_WARNING + with expected_warnings([expected]): + labels_cg_mg = random_walker(data, labels, beta=90, mode='cg_mg') assert (labels_cg_mg[25:45, 40:60] == 2).all() assert data.shape == labels.shape - full_prob = random_walker(data, labels, beta=90, mode='cg_mg', + with expected_warnings([expected]): + full_prob = random_walker(data, labels, beta=90, mode='cg_mg', return_full_prob=True) assert (full_prob[1, 25:45, 40:60] >= full_prob[0, 25:45, 40:60]).all() @@ -106,7 +114,8 @@ def test_types(): data, labels = make_2d_syntheticdata(lx, ly) data = 255 * (data - data.min()) // (data.max() - data.min()) data = data.astype(np.uint8) - labels_cg_mg = random_walker(data, labels, beta=90, mode='cg_mg') + with expected_warnings([PYAMG_EXPECTED_WARNING]): + labels_cg_mg = random_walker(data, labels, beta=90, mode='cg_mg') assert (labels_cg_mg[25:45, 40:60] == 2).all() assert data.shape == labels.shape return data, labels_cg_mg @@ -139,7 +148,8 @@ def test_3d(): n = 30 lx, ly, lz = n, n, n data, labels = make_3d_syntheticdata(lx, ly, lz) - labels = random_walker(data, labels, mode='cg') + with expected_warnings(['"cg" mode']): + labels = random_walker(data, labels, mode='cg') assert (labels.reshape(data.shape)[13:17, 13:17, 13:17] == 2).all() assert data.shape == labels.shape return data, labels @@ -152,7 +162,8 @@ def test_3d_inactive(): old_labels = np.copy(labels) labels[5:25, 26:29, 26:29] = -1 after_labels = np.copy(labels) - labels = random_walker(data, labels, mode='cg') + with expected_warnings(['"cg" mode']): + labels = random_walker(data, labels, mode='cg') assert (labels.reshape(data.shape)[13:17, 13:17, 13:17] == 2).all() assert data.shape == labels.shape return data, labels, old_labels, after_labels @@ -162,9 +173,12 @@ def test_multispectral_2d(): lx, ly = 70, 100 data, labels = make_2d_syntheticdata(lx, ly) data = data[..., np.newaxis].repeat(2, axis=-1) # Expect identical output - multi_labels = random_walker(data, labels, mode='cg', multichannel=True) + with expected_warnings(['"cg" mode']): + multi_labels = random_walker(data, labels, mode='cg', + multichannel=True) assert data[..., 0].shape == labels.shape - single_labels = random_walker(data[..., 0], labels, mode='cg') + with expected_warnings(['"cg" mode']): + single_labels = random_walker(data[..., 0], labels, mode='cg') assert (multi_labels.reshape(labels.shape)[25:45, 40:60] == 2).all() assert data[..., 0].shape == labels.shape return data, multi_labels, single_labels, labels @@ -175,9 +189,12 @@ def test_multispectral_3d(): lx, ly, lz = n, n, n data, labels = make_3d_syntheticdata(lx, ly, lz) data = data[..., np.newaxis].repeat(2, axis=-1) # Expect identical output - multi_labels = random_walker(data, labels, mode='cg', multichannel=True) + with expected_warnings(['"cg" mode']): + multi_labels = random_walker(data, labels, mode='cg', + multichannel=True) assert data[..., 0].shape == labels.shape - single_labels = random_walker(data[..., 0], labels, mode='cg') + with expected_warnings(['"cg" mode']): + single_labels = random_walker(data[..., 0], labels, mode='cg') assert (multi_labels.reshape(labels.shape)[13:17, 13:17, 13:17] == 2).all() assert (single_labels.reshape(labels.shape)[13:17, 13:17, 13:17] == 2).all() assert data[..., 0].shape == labels.shape @@ -203,7 +220,8 @@ def test_spacing_0(): lz // 4 - small_l // 8] = 2 # Test with `spacing` kwarg - labels_aniso = random_walker(data_aniso, labels_aniso, mode='cg', + with expected_warnings(['"cg" mode']): + labels_aniso = random_walker(data_aniso, labels_aniso, mode='cg', spacing=(1., 1., 0.5)) assert (labels_aniso[13:17, 13:17, 7:9] == 2).all() @@ -230,8 +248,9 @@ def test_spacing_1(): # Test with `spacing` kwarg # First, anisotropic along Y - labels_aniso = random_walker(data_aniso, labels_aniso, mode='cg', - spacing=(1., 2., 1.)) + with expected_warnings(['"cg" mode']): + labels_aniso = random_walker(data_aniso, labels_aniso, mode='cg', + spacing=(1., 2., 1.)) assert (labels_aniso[13:17, 26:34, 13:17] == 2).all() # Rescale `data` along X axis @@ -249,9 +268,10 @@ def test_spacing_1(): lz // 2 - small_l // 4] = 2 # Anisotropic along X - labels_aniso2 = random_walker(data_aniso, - labels_aniso2, - mode='cg', spacing=(2., 1., 1.)) + with expected_warnings(['"cg" mode']): + labels_aniso2 = random_walker(data_aniso, + labels_aniso2, + mode='cg', spacing=(2., 1., 1.)) assert (labels_aniso2[26:34, 13:17, 13:17] == 2).all() @@ -259,14 +279,17 @@ def test_trivial_cases(): # When all voxels are labeled img = np.ones((10, 10)) labels = np.ones((10, 10)) - pass_through = random_walker(img, labels) + + with expected_warnings(["Returning provided labels"]): + pass_through = random_walker(img, labels) np.testing.assert_array_equal(pass_through, labels) # When all voxels are labeled AND return_full_prob is True labels[:, :5] = 3 expected = np.concatenate(((labels == 1)[..., np.newaxis], (labels == 3)[..., np.newaxis]), axis=2) - test = random_walker(img, labels, return_full_prob=True) + with expected_warnings(["Returning provided labels"]): + test = random_walker(img, labels, return_full_prob=True) np.testing.assert_array_equal(test, expected) diff --git a/skimage/transform/tests/__init__.py b/skimage/transform/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/transform/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/transform/tests/test_geometric.py b/skimage/transform/tests/test_geometric.py index 2d81a23d..125faf6c 100644 --- a/skimage/transform/tests/test_geometric.py +++ b/skimage/transform/tests/test_geometric.py @@ -7,6 +7,7 @@ from skimage.transform import (estimate_transform, matrix_transform, SimilarityTransform, AffineTransform, ProjectiveTransform, PolynomialTransform, PiecewiseAffineTransform) +from skimage._shared._warnings import expected_warnings SRC = np.array([ @@ -49,7 +50,7 @@ def test_estimate_transform(): def test_matrix_transform(): tform = AffineTransform(scale=(0.1, 0.5), rotation=2) - assert_equal(tform(SRC), matrix_transform(SRC, tform._matrix)) + assert_equal(tform(SRC), matrix_transform(SRC, tform.params)) def test_similarity_estimation(): @@ -209,13 +210,13 @@ def test_union(): tform2 = SimilarityTransform(scale=0.1, rotation=0.9) tform3 = SimilarityTransform(scale=0.1 ** 2, rotation=0.3 + 0.9) tform = tform1 + tform2 - assert_array_almost_equal(tform._matrix, tform3._matrix) + assert_array_almost_equal(tform.params, tform3.params) tform1 = AffineTransform(scale=(0.1, 0.1), rotation=0.3) tform2 = SimilarityTransform(scale=0.1, rotation=0.9) tform3 = SimilarityTransform(scale=0.1 ** 2, rotation=0.3 + 0.9) tform = tform1 + tform2 - assert_array_almost_equal(tform._matrix, tform3._matrix) + assert_array_almost_equal(tform.params, tform3.params) assert tform.__class__ == ProjectiveTransform tform = AffineTransform(scale=(0.1, 0.1), rotation=0.3) @@ -251,10 +252,12 @@ def test_invalid_input(): def test_deprecated_params_attributes(): for t in ('projective', 'affine', 'similarity'): tform = estimate_transform(t, SRC, DST) - assert_equal(tform._matrix, tform.params) + with expected_warnings(['`_matrix`.*deprecated']): + assert_equal(tform._matrix, tform.params) tform = estimate_transform('polynomial', SRC, DST, order=3) - assert_equal(tform._params, tform.params) + with expected_warnings(['`_params`.*deprecated']): + assert_equal(tform._params, tform.params) if __name__ == "__main__": diff --git a/skimage/transform/tests/test_hough_transform.py b/skimage/transform/tests/test_hough_transform.py index fb19d8c1..884d7957 100644 --- a/skimage/transform/tests/test_hough_transform.py +++ b/skimage/transform/tests/test_hough_transform.py @@ -3,6 +3,7 @@ from numpy.testing import assert_almost_equal, assert_equal import skimage.transform as tf from skimage.draw import line, circle_perimeter, ellipse_perimeter +from skimage._shared._warnings import expected_warnings def append_desc(func, description): @@ -67,7 +68,8 @@ def test_hough_line_peaks(): out, angles, d = tf.hough_line(img) - out, theta, dist = tf.hough_line_peaks(out, angles, d) + with expected_warnings(['`background`']): + out, theta, dist = tf.hough_line_peaks(out, angles, d) assert_equal(len(dist), 1) assert_almost_equal(dist[0], 80.723, 1) @@ -79,13 +81,19 @@ def test_hough_line_peaks_dist(): img[:, 30] = True img[:, 40] = True hspace, angles, dists = tf.hough_line(img) - assert len(tf.hough_line_peaks(hspace, angles, dists, - min_distance=5)[0]) == 2 - assert len(tf.hough_line_peaks(hspace, angles, dists, - min_distance=15)[0]) == 1 + with expected_warnings(['`background`']): + assert len(tf.hough_line_peaks(hspace, angles, dists, + min_distance=5)[0]) == 2 + assert len(tf.hough_line_peaks(hspace, angles, dists, + min_distance=15)[0]) == 1 def test_hough_line_peaks_angle(): + with expected_warnings(['`background`']): + check_hough_line_peaks_angle() + + +def check_hough_line_peaks_angle(): img = np.zeros((100, 100), dtype=np.bool_) img[:, 0] = True img[0, :] = True @@ -116,8 +124,9 @@ def test_hough_line_peaks_num(): img[:, 30] = True img[:, 40] = True hspace, angles, dists = tf.hough_line(img) - assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=0, - min_angle=0, num_peaks=1)[0]) == 1 + with expected_warnings(['`background`']): + assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=0, + min_angle=0, num_peaks=1)[0]) == 1 def test_hough_circle(): diff --git a/skimage/transform/tests/test_warps.py b/skimage/transform/tests/test_warps.py index 09a93d69..115f0e6f 100644 --- a/skimage/transform/tests/test_warps.py +++ b/skimage/transform/tests/test_warps.py @@ -10,6 +10,7 @@ from skimage.transform import (warp, warp_coords, rotate, resize, rescale, downscale_local_mean) from skimage import transform as tf, data, img_as_float from skimage.color import rgb2gray +from skimage._shared._warnings import expected_warnings np.random.seed(0) @@ -196,8 +197,10 @@ def test_swirl(): image = img_as_float(data.checkerboard()) swirl_params = {'radius': 80, 'rotation': 0, 'order': 2, 'mode': 'reflect'} - swirled = tf.swirl(image, strength=10, **swirl_params) - unswirled = tf.swirl(swirled, strength=-10, **swirl_params) + + with expected_warnings(['Bi-quadratic.*bug']): + swirled = tf.swirl(image, strength=10, **swirl_params) + unswirled = tf.swirl(swirled, strength=-10, **swirl_params) assert np.mean(np.abs(image - unswirled)) < 0.01 diff --git a/skimage/util/tests/__init__.py b/skimage/util/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/util/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/util/tests/test_dtype.py b/skimage/util/tests/test_dtype.py index ae26cd27..612c43e6 100644 --- a/skimage/util/tests/test_dtype.py +++ b/skimage/util/tests/test_dtype.py @@ -3,6 +3,7 @@ from numpy.testing import assert_equal, assert_raises from skimage import img_as_int, img_as_float, \ img_as_uint, img_as_ubyte from skimage.util.dtype import convert +from skimage._shared._warnings import expected_warnings dtype_range = {np.uint8: (0, 255), @@ -28,7 +29,9 @@ def test_range(): (img_as_float, np.float64), (img_as_uint, np.uint16), (img_as_ubyte, np.ubyte)]: - y = f(x) + + with expected_warnings(['precision loss|sign loss|\A\Z']): + y = f(x) omin, omax = dtype_range[dt] @@ -59,7 +62,10 @@ def test_range_extra_dtypes(): for dtype_in, dt in dtype_pairs: imin, imax = dtype_range_extra[dtype_in] x = np.linspace(imin, imax, 10).astype(dtype_in) - y = convert(x, dt) + + with expected_warnings(['precision loss|sign loss|\A\Z']): + y = convert(x, dt) + omin, omax = dtype_range_extra[dt] yield (_verify_range, "From %s to %s" % (np.dtype(dtype_in), np.dtype(dt)), diff --git a/skimage/util/tests/test_shape.py b/skimage/util/tests/test_shape.py index ee897e7c..38127df8 100644 --- a/skimage/util/tests/test_shape.py +++ b/skimage/util/tests/test_shape.py @@ -3,7 +3,7 @@ from nose.tools import raises from numpy.testing import assert_equal, assert_warns from skimage.util.shape import view_as_blocks, view_as_windows -from skimage._shared.utils import all_warnings +from skimage._shared._warnings import expected_warnings @raises(TypeError) @@ -153,9 +153,8 @@ def test_views_non_contiguous(): A = np.arange(16).reshape((4, 4)) A = A[::2, :] - with all_warnings(): - assert_warns(RuntimeWarning, view_as_blocks, A, (2, 2)) - assert_warns(RuntimeWarning, view_as_windows, A, (2, 2)) + assert_warns(RuntimeWarning, view_as_blocks, A, (2, 2)) + assert_warns(RuntimeWarning, view_as_windows, A, (2, 2)) if __name__ == '__main__': diff --git a/skimage/viewer/canvastools/recttool.py b/skimage/viewer/canvastools/recttool.py index 8932e180..4acccf8a 100644 --- a/skimage/viewer/canvastools/recttool.py +++ b/skimage/viewer/canvastools/recttool.py @@ -41,15 +41,16 @@ class RectangleTool(CanvasToolBase, RectangleSelector): def __init__(self, viewer, on_move=None, on_release=None, on_enter=None, maxdist=10, rect_props=None): - CanvasToolBase.__init__(self, viewer, on_move=on_move, - on_enter=on_enter, on_release=on_release) - + self._rect = None props = dict(edgecolor=None, facecolor='r', alpha=0.15) props.update(rect_props if rect_props is not None else {}) if props['edgecolor'] is None: props['edgecolor'] = props['facecolor'] - RectangleSelector.__init__(self, self.ax, lambda *args: None, + RectangleSelector.__init__(self, viewer.ax, lambda *args: None, rectprops=props) + CanvasToolBase.__init__(self, viewer, on_move=on_move, + on_enter=on_enter, on_release=on_release) + # Events are handled by the viewer try: self.disconnect_events() @@ -87,6 +88,8 @@ class RectangleTool(CanvasToolBase, RectangleSelector): @property def _rect_bbox(self): + if not self._rect: + return 0, 0, 0, 0 x0 = self._rect.get_x() y0 = self._rect.get_y() width = self._rect.get_width() diff --git a/skimage/viewer/tests/__init__.py b/skimage/viewer/tests/__init__.py new file mode 100644 index 00000000..3df53221 --- /dev/null +++ b/skimage/viewer/tests/__init__.py @@ -0,0 +1,9 @@ +from skimage._shared.testing import setup_test, teardown_test + + +def setup(): + setup_test() + + +def teardown(): + teardown_test() diff --git a/skimage/viewer/tests/test_plugins.py b/skimage/viewer/tests/test_plugins.py index 6823635a..528df8f4 100644 --- a/skimage/viewer/tests/test_plugins.py +++ b/skimage/viewer/tests/test_plugins.py @@ -12,6 +12,7 @@ from skimage.viewer.plugins import ( PlotPlugin) from skimage.viewer.plugins.base import Plugin from skimage.viewer.widgets import Slider +from skimage._shared._warnings import expected_warnings def setup_line_profile(image, limits='image'): @@ -66,8 +67,9 @@ def test_line_profile_dynamic(): assert_almost_equal(np.std(line), 0.229, 3) assert_almost_equal(np.max(line) - np.min(line), 0.725, 1) - viewer.image = skimage.img_as_float(median(image, - selem=disk(radius=3))) + with expected_warnings(['precision loss']): + viewer.image = skimage.img_as_float(median(image, + selem=disk(radius=3))) line = lp.get_profiles()[-1][0] assert_almost_equal(np.std(viewer.image), 0.198, 3) @@ -159,7 +161,8 @@ def test_plugin(): viewer = ImageViewer(img) def median_filter(img, radius=3): - return median(img, selem=disk(radius=radius)) + with expected_warnings(['precision loss']): + return median(img, selem=disk(radius=radius)) plugin = Plugin(image_filter=median_filter) viewer += plugin diff --git a/skimage/viewer/tests/test_tools.py b/skimage/viewer/tests/test_tools.py index 0805364c..6b923063 100644 --- a/skimage/viewer/tests/test_tools.py +++ b/skimage/viewer/tests/test_tools.py @@ -8,8 +8,8 @@ from skimage.viewer import ImageViewer, viewer_available from skimage.viewer.canvastools import ( LineTool, ThickLineTool, RectangleTool, PaintTool) from skimage.viewer.canvastools.base import CanvasToolBase -from numpy.testing import assert_equal -from numpy.testing.decorators import skipif +from matplotlib.testing.decorators import cleanup + def get_end_points(image): @@ -74,6 +74,7 @@ def do_event(viewer, etype, button=1, xdata=0, ydata=0, key=None): func(event) +@cleanup @skipif(not viewer_available) def test_line_tool(): img = data.camera() @@ -99,6 +100,7 @@ def test_line_tool(): assert_equal(tool.geometry, np.array([[100, 100], [10, 10]])) +@cleanup @skipif(not viewer_available) def test_thick_line_tool(): img = data.camera() @@ -122,6 +124,7 @@ def test_thick_line_tool(): assert_equal(tool.linewidth, 1) +@cleanup @skipif(not viewer_available) def test_rect_tool(): img = data.camera() @@ -150,6 +153,7 @@ def test_rect_tool(): assert_equal(tool.geometry, [10, 100, 10, 100]) +@cleanup @skipif(not viewer_available) def test_paint_tool(): img = data.moon() @@ -183,6 +187,7 @@ def test_paint_tool(): assert_equal(tool.overlay.sum(), 0) +@cleanup @skipif(not viewer_available) def test_base_tool(): img = data.moon() diff --git a/skimage/viewer/tests/test_viewer.py b/skimage/viewer/tests/test_viewer.py index 99d8e364..1604ca6d 100644 --- a/skimage/viewer/tests/test_viewer.py +++ b/skimage/viewer/tests/test_viewer.py @@ -8,6 +8,7 @@ from skimage.filters import sobel from numpy.testing import assert_equal from numpy.testing.decorators import skipif from skimage._shared.version_requirements import is_installed +from skimage._shared._warnings import expected_warnings @skipif(not viewer_available) @@ -66,7 +67,9 @@ def test_viewer_with_overlay(): ov.color = 3 assert_equal(ov.color, 'yellow') - viewer.save_to_file(filename) + + with expected_warnings(['precision loss']): + viewer.save_to_file(filename) ov.display_filtered_image(img) assert_equal(ov.overlay, img) ov.overlay = None diff --git a/skimage/viewer/tests/test_widgets.py b/skimage/viewer/tests/test_widgets.py index ba76b7c5..170c186c 100644 --- a/skimage/viewer/tests/test_widgets.py +++ b/skimage/viewer/tests/test_widgets.py @@ -8,6 +8,7 @@ from skimage.viewer.plugins.base import Plugin from skimage.viewer.qt import QtGui, QtCore from numpy.testing import assert_almost_equal, assert_equal from numpy.testing.decorators import skipif +from skimage._shared._warnings import expected_warnings def get_image_viewer(): @@ -99,10 +100,13 @@ def test_save_buttons(): timer.singleShot(100, QtGui.QApplication.quit) sv.save_to_stack() - sv.save_to_file(filename) + with expected_warnings(['precision loss']): + sv.save_to_file(filename) img = data.imread(filename) - assert_almost_equal(img, img_as_uint(viewer.image)) + + with expected_warnings(['precision loss']): + assert_almost_equal(img, img_as_uint(viewer.image)) img = io.pop() assert_almost_equal(img, viewer.image) diff --git a/skimage/viewer/utils/core.py b/skimage/viewer/utils/core.py index 8aca4e24..242f2de4 100644 --- a/skimage/viewer/utils/core.py +++ b/skimage/viewer/utils/core.py @@ -203,6 +203,7 @@ def figimage(image, scale=1, dpi=None, **kwargs): ax.set_axis_off() ax.imshow(image, **kwargs) + ax.figure.canvas.draw() return fig, ax