From 37560287a96760193475a3ca1ee7d0df76e3dcca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 29 Nov 2014 08:52:20 -0500 Subject: [PATCH 1/3] Fix rank filter kernels --- skimage/filters/rank/bilateral_cy.pyx | 2 +- skimage/filters/rank/generic_cy.pyx | 4 ++-- skimage/filters/rank/percentile_cy.pyx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/skimage/filters/rank/bilateral_cy.pyx b/skimage/filters/rank/bilateral_cy.pyx index 3acc26a4..a008e682 100644 --- a/skimage/filters/rank/bilateral_cy.pyx +++ b/skimage/filters/rank/bilateral_cy.pyx @@ -26,7 +26,7 @@ cdef inline void _kernel_mean(dtype_t_out* out, Py_ssize_t odepth, bilat_pop += histo[i] mean += histo[i] * i if bilat_pop: - out[0] = mean / bilat_pop + out[0] = (mean / bilat_pop) else: out[0] = 0 else: diff --git a/skimage/filters/rank/generic_cy.pyx b/skimage/filters/rank/generic_cy.pyx index a5c70bf4..3b28005a 100644 --- a/skimage/filters/rank/generic_cy.pyx +++ b/skimage/filters/rank/generic_cy.pyx @@ -29,7 +29,7 @@ cdef inline void _kernel_autolevel(dtype_t_out* out, Py_ssize_t odepth, break delta = imax - imin if delta > 0: - out[0] = (max_bin - 1) * (g - imin) / delta + out[0] = ((max_bin - 1) * (g - imin) / delta) else: out[0] = 0 else: @@ -49,7 +49,7 @@ cdef inline void _kernel_bottomhat(dtype_t_out* out, Py_ssize_t odepth, for i in range(max_bin): if histo[i]: break - out[0] = g - i + out[0] = (g - i) else: out[0] = 0 diff --git a/skimage/filters/rank/percentile_cy.pyx b/skimage/filters/rank/percentile_cy.pyx index 3be4b52a..4d90555f 100644 --- a/skimage/filters/rank/percentile_cy.pyx +++ b/skimage/filters/rank/percentile_cy.pyx @@ -116,7 +116,7 @@ cdef inline void _kernel_sum(dtype_t_out* out, Py_ssize_t odepth, sum_g += histo[i] * i if n > 0: - out[0] = (sum_g) + out[0] = sum_g else: out[0] = 0 else: From bbd98282340caa384cbe78801fa9e6d64415ac71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 6 Dec 2014 10:19:23 -0500 Subject: [PATCH 2/3] Wrap code at 80 --- skimage/filters/rank/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skimage/filters/rank/__init__.py b/skimage/filters/rank/__init__.py index 22b0e881..37b5f9cd 100644 --- a/skimage/filters/rank/__init__.py +++ b/skimage/filters/rank/__init__.py @@ -1,6 +1,7 @@ from .generic import (autolevel, bottomhat, equalize, gradient, maximum, mean, subtract_mean, median, minimum, modal, enhance_contrast, - pop, threshold, tophat, noise_filter, entropy, otsu, sum, windowed_histogram) + pop, threshold, tophat, noise_filter, entropy, otsu, + sum, windowed_histogram) from ._percentile import (autolevel_percentile, gradient_percentile, mean_percentile, subtract_mean_percentile, enhance_contrast_percentile, percentile, From cf499bf84454d3263189e40a47e4c4f28ba7a6c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20Sch=C3=B6nberger?= Date: Sat, 13 Dec 2014 11:25:59 +0100 Subject: [PATCH 3/3] Add tests for all rank filters and reformat code --- skimage/data/rank_filter_tests.npz | Bin 0 -> 33945 bytes skimage/filters/rank/tests/test_rank.py | 241 ++++++++++++++++-------- 2 files changed, 159 insertions(+), 82 deletions(-) create mode 100644 skimage/data/rank_filter_tests.npz diff --git a/skimage/data/rank_filter_tests.npz b/skimage/data/rank_filter_tests.npz new file mode 100644 index 0000000000000000000000000000000000000000..3142fcc15f05b7a5e38ac7dcbcbba15eb0a0ec94 GIT binary patch literal 33945 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 literal 0 HcmV?d00001 diff --git a/skimage/filters/rank/tests/test_rank.py b/skimage/filters/rank/tests/test_rank.py index 7359fe87..23745ebf 100644 --- a/skimage/filters/rank/tests/test_rank.py +++ b/skimage/filters/rank/tests/test_rank.py @@ -1,14 +1,85 @@ +import os import numpy as np -from numpy.testing import run_module_suite, assert_array_equal, assert_raises +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 data, util +from skimage import data, util, morphology from skimage.morphology import cmorph, disk from skimage.filters import rank np.random.seed(0) +def test_all(): + image = np.random.rand(25, 25) + selem = morphology.disk(1) + refs = np.load(os.path.join(skimage.data_dir, "rank_filter_tests.npz")) + + assert_equal(refs["autolevel"], + rank.autolevel(image, selem)) + assert_equal(refs["autolevel_percentile"], + rank.autolevel_percentile(image, selem)) + assert_equal(refs["bottomhat"], + rank.bottomhat(image, selem)) + assert_equal(refs["equalize"], + rank.equalize(image, selem)) + assert_equal(refs["gradient"], + rank.gradient(image, selem)) + assert_equal(refs["gradient_percentile"], + rank.gradient_percentile(image, selem)) + assert_equal(refs["maximum"], + rank.maximum(image, selem)) + assert_equal(refs["mean"], + rank.mean(image, selem)) + assert_equal(refs["mean_percentile"], + rank.mean_percentile(image, selem)) + assert_equal(refs["mean_bilateral"], + rank.mean_bilateral(image, selem)) + assert_equal(refs["subtract_mean"], + rank.subtract_mean(image, selem)) + assert_equal(refs["subtract_mean_percentile"], + rank.subtract_mean_percentile(image, selem)) + assert_equal(refs["median"], + rank.median(image, selem)) + assert_equal(refs["minimum"], + rank.minimum(image, selem)) + assert_equal(refs["modal"], + rank.modal(image, selem)) + assert_equal(refs["enhance_contrast"], + rank.enhance_contrast(image, selem)) + assert_equal(refs["enhance_contrast_percentile"], + rank.enhance_contrast_percentile(image, selem)) + assert_equal(refs["pop"], + rank.pop(image, selem)) + assert_equal(refs["pop_percentile"], + rank.pop_percentile(image, selem)) + assert_equal(refs["pop_bilateral"], + rank.pop_bilateral(image, selem)) + assert_equal(refs["sum"], + rank.sum(image, selem)) + assert_equal(refs["sum_bilateral"], + rank.sum_bilateral(image, selem)) + assert_equal(refs["sum_percentile"], + rank.sum_percentile(image, selem)) + assert_equal(refs["threshold"], + rank.threshold(image, selem)) + assert_equal(refs["threshold_percentile"], + rank.threshold_percentile(image, selem)) + assert_equal(refs["tophat"], + rank.tophat(image, selem)) + assert_equal(refs["noise_filter"], + rank.noise_filter(image, selem)) + assert_equal(refs["entropy"], + rank.entropy(image, selem)) + assert_equal(refs["otsu"], + rank.otsu(image, selem)) + assert_equal(refs["percentile"], + rank.percentile(image, selem)) + assert_equal(refs["windowed_histogram"], + rank.windowed_histogram(image, selem)) + + def test_random_sizes(): # make sure the size is not a problem @@ -21,26 +92,26 @@ def test_random_sizes(): out8 = np.empty_like(image8) rank.mean(image=image8, selem=elem, mask=mask, out=out8, shift_x=0, shift_y=0) - assert_array_equal(image8.shape, out8.shape) + assert_equal(image8.shape, out8.shape) rank.mean(image=image8, selem=elem, mask=mask, out=out8, shift_x=+1, shift_y=+1) - assert_array_equal(image8.shape, out8.shape) + assert_equal(image8.shape, out8.shape) image16 = np.ones((m, n), dtype=np.uint16) out16 = np.empty_like(image8, dtype=np.uint16) rank.mean(image=image16, selem=elem, mask=mask, out=out16, shift_x=0, shift_y=0) - assert_array_equal(image16.shape, out16.shape) + assert_equal(image16.shape, out16.shape) rank.mean(image=image16, selem=elem, mask=mask, out=out16, shift_x=+1, shift_y=+1) - assert_array_equal(image16.shape, out16.shape) + assert_equal(image16.shape, out16.shape) rank.mean_percentile(image=image16, mask=mask, out=out16, selem=elem, shift_x=0, shift_y=0, p0=.1, p1=.9) - assert_array_equal(image16.shape, out16.shape) + assert_equal(image16.shape, out16.shape) rank.mean_percentile(image=image16, mask=mask, out=out16, selem=elem, shift_x=+1, shift_y=+1, p0=.1, p1=.9) - assert_array_equal(image16.shape, out16.shape) + assert_equal(image16.shape, out16.shape) def test_compare_with_cmorph_dilate(): @@ -54,7 +125,7 @@ def test_compare_with_cmorph_dilate(): elem = np.ones((r, r), dtype=np.uint8) rank.maximum(image=image, selem=elem, out=out, mask=mask) cm = cmorph._dilate(image=image, selem=elem) - assert_array_equal(out, cm) + assert_equal(out, cm) def test_compare_with_cmorph_erode(): @@ -68,7 +139,7 @@ def test_compare_with_cmorph_erode(): elem = np.ones((r, r), dtype=np.uint8) rank.minimum(image=image, selem=elem, out=out, mask=mask) cm = cmorph._erode(image=image, selem=elem) - assert_array_equal(out, cm) + assert_equal(out, cm) def test_bitdepth(): @@ -98,7 +169,7 @@ def test_population(): [6, 9, 9, 9, 6], [6, 9, 9, 9, 6], [4, 6, 6, 6, 4]]) - assert_array_equal(r, out) + assert_equal(r, out) def test_structuring_element8(): @@ -120,7 +191,7 @@ def test_structuring_element8(): rank.maximum(image=image, selem=elem, out=out, mask=mask, shift_x=1, shift_y=1) - assert_array_equal(r, out) + assert_equal(r, out) # 16-bit image = np.zeros((6, 6), dtype=np.uint16) @@ -129,7 +200,7 @@ def test_structuring_element8(): rank.maximum(image=image, selem=elem, out=out, mask=mask, shift_x=1, shift_y=1) - assert_array_equal(r, out) + assert_equal(r, out) def test_pass_on_bitdepth(): @@ -161,7 +232,7 @@ def test_compare_autolevels(): loc_perc_autolevel = rank.autolevel_percentile(image, selem=selem, p0=.0, p1=1.) - assert_array_equal(loc_autolevel, loc_perc_autolevel) + assert_equal(loc_autolevel, loc_perc_autolevel) def test_compare_autolevels_16bit(): @@ -175,7 +246,7 @@ def test_compare_autolevels_16bit(): loc_perc_autolevel = rank.autolevel_percentile(image, selem=selem, p0=.0, p1=1.) - assert_array_equal(loc_autolevel, loc_perc_autolevel) + assert_equal(loc_autolevel, loc_perc_autolevel) def test_compare_ubyte_vs_float(): @@ -191,7 +262,7 @@ def test_compare_ubyte_vs_float(): func = getattr(rank, method) out_u = func(image_uint, disk(3)) out_f = func(image_float, disk(3)) - assert_array_equal(out_u, out_f) + assert_equal(out_u, out_f) def test_compare_8bit_unsigned_vs_signed(): @@ -204,7 +275,7 @@ def test_compare_8bit_unsigned_vs_signed(): image_s = image.astype(np.int8) image_u = img_as_ubyte(image_s) - assert_array_equal(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', @@ -214,7 +285,7 @@ def test_compare_8bit_unsigned_vs_signed(): func = getattr(rank, method) out_u = func(image_u, disk(3)) out_s = func(image_s, disk(3)) - assert_array_equal(out_u, out_s) + assert_equal(out_u, out_s) def test_compare_8bit_vs_16bit(): @@ -223,7 +294,7 @@ def test_compare_8bit_vs_16bit(): image8 = util.img_as_ubyte(data.camera()) image16 = image8.astype(np.uint16) - assert_array_equal(image8, image16) + assert_equal(image8, image16) methods = ['autolevel', 'bottomhat', 'equalize', 'gradient', 'maximum', 'mean', 'subtract_mean', 'median', 'minimum', 'modal', @@ -233,7 +304,7 @@ def test_compare_8bit_vs_16bit(): func = getattr(rank, method) f8 = func(image8, disk(3)) f16 = func(image16, disk(3)) - assert_array_equal(f8, f16) + assert_equal(f8, f16) def test_trivial_selem8(): @@ -250,13 +321,13 @@ def test_trivial_selem8(): elem = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]], dtype=np.uint8) rank.mean(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.minimum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.maximum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) def test_trivial_selem16(): @@ -273,13 +344,13 @@ def test_trivial_selem16(): elem = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]], dtype=np.uint8) rank.mean(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.minimum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.maximum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) def test_smallest_selem8(): @@ -296,13 +367,13 @@ def test_smallest_selem8(): elem = np.array([[1]], dtype=np.uint8) rank.mean(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.minimum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.maximum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) def test_smallest_selem16(): @@ -319,13 +390,13 @@ def test_smallest_selem16(): elem = np.array([[1]], dtype=np.uint8) rank.mean(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.minimum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.maximum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) def test_empty_selem(): @@ -344,13 +415,13 @@ def test_empty_selem(): rank.mean(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(res, out) + assert_equal(res, out) rank.minimum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(res, out) + assert_equal(res, out) rank.maximum(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(res, out) + assert_equal(res, out) def test_otsu(): @@ -364,7 +435,7 @@ def test_otsu(): res = np.tile([1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1], (16, 1)) selem = np.ones((6, 6), dtype=np.uint8) th = 1 * (test >= rank.otsu(test, selem)) - assert_array_equal(th, res) + assert_equal(th, res) def test_entropy(): @@ -424,10 +495,10 @@ def test_selem_dtypes(): elem = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]], dtype=dtype) rank.mean(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) rank.mean_percentile(image=image, selem=elem, out=out, mask=mask, shift_x=0, shift_y=0) - assert_array_equal(image, out) + assert_equal(image, out) def test_16bit(): @@ -464,11 +535,11 @@ def test_percentile_min(): # check for 8bit img_p0 = rank.percentile(img, selem=selem, p0=0) img_min = rank.minimum(img, selem=selem) - assert_array_equal(img_p0, img_min) + assert_equal(img_p0, img_min) # check for 16bit img_p0 = rank.percentile(img16, selem=selem, p0=0) img_min = rank.minimum(img16, selem=selem) - assert_array_equal(img_p0, img_min) + assert_equal(img_p0, img_min) def test_percentile_max(): @@ -479,11 +550,11 @@ def test_percentile_max(): # check for 8bit img_p0 = rank.percentile(img, selem=selem, p0=1.) img_max = rank.maximum(img, selem=selem) - assert_array_equal(img_p0, img_max) + assert_equal(img_p0, img_max) # check for 16bit img_p0 = rank.percentile(img16, selem=selem, p0=1.) img_max = rank.maximum(img16, selem=selem) - assert_array_equal(img_p0, img_max) + assert_equal(img_p0, img_max) def test_percentile_median(): @@ -494,11 +565,12 @@ def test_percentile_median(): # check for 8bit img_p0 = rank.percentile(img, selem=selem, p0=.5) img_max = rank.median(img, selem=selem) - assert_array_equal(img_p0, img_max) + assert_equal(img_p0, img_max) # check for 16bit img_p0 = rank.percentile(img16, selem=selem, p0=.5) img_max = rank.median(img16, selem=selem) - assert_array_equal(img_p0, img_max) + assert_equal(img_p0, img_max) + def test_sum(): # check the number of valid pixels in the neighborhood @@ -508,39 +580,44 @@ def test_sum(): [0, 1, 1, 1, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]], dtype=np.uint8) - image16 = 400*np.array([[0, 0, 0, 0, 0], - [0, 1, 1, 1, 0], - [0, 1, 1, 1, 0], - [0, 1, 1, 1, 0], - [0, 0, 0, 0, 0]], dtype=np.uint16) + image16 = 400 * np.array([[0, 0, 0, 0, 0], + [0, 1, 1, 1, 0], + [0, 1, 1, 1, 0], + [0, 1, 1, 1, 0], + [0, 0, 0, 0, 0]], dtype=np.uint16) elem = np.ones((3, 3), dtype=np.uint8) out8 = np.empty_like(image8) out16 = np.empty_like(image16) mask = np.ones(image8.shape, dtype=np.uint8) - r = np.array([[1, 2, 3, 2, 1], - [2, 4, 6, 4, 2], - [3, 6, 9, 6, 3], - [2, 4, 6, 4, 2], - [1, 2, 3, 2, 1]], dtype=np.uint8) + r = np.array([[1, 2, 3, 2, 1], + [2, 4, 6, 4, 2], + [3, 6, 9, 6, 3], + [2, 4, 6, 4, 2], + [1, 2, 3, 2, 1]], dtype=np.uint8) rank.sum(image=image8, selem=elem, out=out8, mask=mask) - assert_array_equal(r, out8) - rank.sum_percentile(image=image8, selem=elem, out=out8, mask=mask,p0=.0,p1=1.) - assert_array_equal(r, out8) - rank.sum_bilateral(image=image8, selem=elem, out=out8, mask=mask,s0=255,s1=255) - assert_array_equal(r, out8) + assert_equal(r, out8) + rank.sum_percentile( + image=image8, selem=elem, out=out8, mask=mask, p0=.0, p1=1.) + assert_equal(r, out8) + rank.sum_bilateral( + image=image8, selem=elem, out=out8, mask=mask, s0=255, s1=255) + assert_equal(r, out8) - r = 400* np.array([[1, 2, 3, 2, 1], - [2, 4, 6, 4, 2], - [3, 6, 9, 6, 3], - [2, 4, 6, 4, 2], - [1, 2, 3, 2, 1]], dtype=np.uint16) + r = 400 * np.array([[1, 2, 3, 2, 1], + [2, 4, 6, 4, 2], + [3, 6, 9, 6, 3], + [2, 4, 6, 4, 2], + [1, 2, 3, 2, 1]], dtype=np.uint16) rank.sum(image=image16, selem=elem, out=out16, mask=mask) - assert_array_equal(r, out16) - rank.sum_percentile(image=image16, selem=elem, out=out16, mask=mask,p0=.0,p1=1.) - assert_array_equal(r, out16) - rank.sum_bilateral(image=image16, selem=elem, out=out16, mask=mask,s0=1000,s1=1000) - assert_array_equal(r, out16) + assert_equal(r, out16) + rank.sum_percentile( + image=image16, selem=elem, out=out16, mask=mask, p0=.0, p1=1.) + assert_equal(r, out16) + rank.sum_bilateral( + image=image16, selem=elem, out=out16, mask=mask, s0=1000, s1=1000) + assert_equal(r, out16) + def test_windowed_histogram(): # check the number of valid pixels in the neighborhood @@ -551,7 +628,7 @@ def test_windowed_histogram(): [0, 1, 1, 1, 0], [0, 0, 0, 0, 0]], dtype=np.uint8) elem = np.ones((3, 3), dtype=np.uint8) - outf = np.empty(image8.shape+(2,), dtype=float) + outf = np.empty(image8.shape + (2,), dtype=float) mask = np.ones(image8.shape, dtype=np.uint8) # Population so we can normalize the expected output while maintaining @@ -562,19 +639,19 @@ def test_windowed_histogram(): [6, 9, 9, 9, 6], [4, 6, 6, 6, 4]], dtype=float) - r0 = np.array([[3, 4, 3, 4, 3], - [4, 5, 3, 5, 4], - [3, 3, 0, 3, 3], - [4, 5, 3, 5, 4], - [3, 4, 3, 4, 3]], dtype=float) / pop - r1 = np.array([[1, 2, 3, 2, 1], - [2, 4, 6, 4, 2], - [3, 6, 9, 6, 3], - [2, 4, 6, 4, 2], - [1, 2, 3, 2, 1]], dtype=float) / pop + r0 = np.array([[3, 4, 3, 4, 3], + [4, 5, 3, 5, 4], + [3, 3, 0, 3, 3], + [4, 5, 3, 5, 4], + [3, 4, 3, 4, 3]], dtype=float) / pop + r1 = np.array([[1, 2, 3, 2, 1], + [2, 4, 6, 4, 2], + [3, 6, 9, 6, 3], + [2, 4, 6, 4, 2], + [1, 2, 3, 2, 1]], dtype=float) / pop rank.windowed_histogram(image=image8, selem=elem, out=outf, mask=mask) - assert_array_equal(r0, outf[:,:,0]) - assert_array_equal(r1, outf[:,:,1]) + assert_equal(r0, outf[:, :, 0]) + assert_equal(r1, outf[:, :, 1]) # Test n_bins parameter larger_output = rank.windowed_histogram(image=image8, selem=elem,