Modified label function so that background pixels are labeled with 0, and

background=0 by default.

Modified label function so that background pixels are labeled with 0, and
background=0 by default. All tests of _ccomp.pyx pass

Modified a couple of files to be consistent with the new behavior of
measure.label

Modified doctring of label to pass doctest

Modified TODO.txt as well as release notes to mention the new behavior of
label.

Typo in docstring

Typo in docstring

Changed default value of kw argument background in measure.label

Removed unnecessary and outdated comment
This commit is contained in:
emmanuelle
2016-02-22 21:19:23 +01:00
parent 44150989ee
commit a5a771a8e4
8 changed files with 80 additions and 85 deletions
-4
View File
@@ -37,7 +37,3 @@ Version 0.13
_shared/interpolation.pyx, transform/_geometric.py, and transform/_warps.py
Version 0.12
------------
* Change `label` to mark background as 0, not -1, which is consistent with
SciPy's labelling.
-2
View File
@@ -37,8 +37,6 @@ clear_border(cleared)
# label image regions
label_image = label(cleared)
borders = np.logical_xor(bw, cleared)
label_image[borders] = -1
image_label_overlay = label2rgb(label_image, image=image)
fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 6))
+3
View File
@@ -29,6 +29,9 @@ include:
- Synthetic 2-D and 3-D binary data with rounded blobs (#1485)
- Plugin for ``imageio`` library (#1575)
- Inpainting algorithm (#1804)
- New handling of background pixels for ``measure.label``: 0-valued
pixels are considered as background by default, and the label of
background pixels is 0.
- Partial support of 3-D images for ``skimage.measure.regionprops``
(#1505)
- Multi-block local binary patterns (MB-LBP) for texture classification (#1536)
+22 -16
View File
@@ -358,7 +358,7 @@ def undo_reshape_array(arr, swaps):
# Connected components search as described in Fiorio et al.
def label(input, neighbors=None, background=None, return_num=False,
def label(input, neighbors=None, background=0, return_num=False,
connectivity=None):
r"""Label connected regions of an integer array.
@@ -386,13 +386,15 @@ def label(input, neighbors=None, background=None, return_num=False,
**Deprecated, use ``connectivity`` instead.**
background : int, optional
Consider all pixels with this value as background pixels, and label
them as 0.
them as 0. By default, 0-valued pixels are considered as background
pixels.
return_num : bool, optional
Whether to return the number of assigned labels.
connectivity : int, optional
Maximum number of orthogonal hops to consider a pixel/voxel
as a neighbor.
Accepted values are ranging from 1 to input.ndim.
Accepted values are ranging from 1 to input.ndim. If ``None``, a full
connectivity of ``input.ndim`` is used.
Returns
-------
@@ -413,24 +415,28 @@ def label(input, neighbors=None, background=None, return_num=False,
[0 0 1]]
>>> from skimage.measure import label
>>> print(label(x, connectivity=1))
[[0 1 1]
[2 3 1]
[2 2 4]]
[[1 0 0]
[0 2 0]
[0 0 3]]
>>> print(label(x, connectivity=2))
[[0 1 1]
[1 0 1]
[1 1 0]]
[[1 0 0]
[0 1 0]
[0 0 1]]
>>> print(label(x, background=-1))
[[1 2 2]
[2 1 2]
[2 2 1]]
>>> x = np.array([[1, 0, 0],
... [1, 1, 5],
... [0, 0, 0]])
>>> print(label(x, background=1))
[[ 0 1 1]
[ 0 0 2]
[ 3 3 3]]
>>> print(label(x))
[[1 0 0]
[1 1 2]
[0 0 0]]
"""
# We have to ensure that the shape of the input can be handled by the
# algorithm the input if it is the case
@@ -511,7 +517,7 @@ cdef DTYPE_t resolve_labels(DTYPE_t *data_p, DTYPE_t *forest_p,
our knowledge of prov. labels relationship.
We also track how many distinct final labels we have.
"""
cdef DTYPE_t counter = 0, i
cdef DTYPE_t counter = 1, i
for i in range(shapeinfo.numels):
if i == bg.background_node:
@@ -523,7 +529,7 @@ cdef DTYPE_t resolve_labels(DTYPE_t *data_p, DTYPE_t *forest_p,
counter += 1
else:
data_p[i] = data_p[forest_p[i]]
return counter
return counter - 1
cdef void scanBG(DTYPE_t *data_p, DTYPE_t *forest_p, shape_info *shapeinfo,
+1 -1
View File
@@ -117,7 +117,7 @@ def convex_hull_object(image, neighbors=8):
convex_obj = np.zeros(image.shape, dtype=bool)
convex_img = np.zeros(image.shape, dtype=bool)
for i in range(0, labeled_im.max() + 1):
for i in range(1, labeled_im.max() + 1):
convex_obj = convex_hull_image(labeled_im == i)
convex_img = np.logical_or(convex_img, convex_obj)
+44 -46
View File
@@ -5,10 +5,8 @@ from skimage.measure import label
import skimage.measure._ccomp as ccomp
from skimage._shared._warnings import expected_warnings
# The background label value
# is supposed to be changed to 0 soon
BG = -1
# Background value
BG = 0
class TestConnectedComponents:
@@ -21,7 +19,7 @@ class TestConnectedComponents:
self.labels = np.array([[0, 0, 1, 2, 3, 4],
[0, 5, 5, 4, 2, 4],
[0, 0, 5, 4, 4, 4],
[6, 5, 5, 7, 8, 9]])
[6, 5, 5, 7, 8, 0]])
def test_basic(self):
assert_array_equal(label(self.x), self.labels)
@@ -49,7 +47,7 @@ class TestConnectedComponents:
[1, 0]], dtype=int)
assert_array_equal(label(x, 4),
[[0, 1],
[2, 3]])
[2, 0]])
assert_array_equal(label(x, 8),
[[0, 1],
[1, 0]])
@@ -59,14 +57,14 @@ class TestConnectedComponents:
[1, 1, 5],
[0, 0, 0]])
assert_array_equal(label(x), [[0, 1, 1],
[0, 0, 2],
[3, 3, 3]])
assert_array_equal(label(x), [[1, 0, 0],
[1, 1, 2],
[0, 0, 0]])
assert_array_equal(label(x, background=0),
[[0, -1, -1],
[0, 0, 1],
[-1, -1, -1]])
[[1, 0, 0],
[1, 1, 2],
[0, 0, 0]])
def test_background_two_regions(self):
x = np.array([[0, 0, 6],
@@ -75,9 +73,9 @@ class TestConnectedComponents:
res = label(x, background=0)
assert_array_equal(res,
[[-1, -1, 0],
[-1, -1, 0],
[+1, 1, 1]])
[[0, 0, 1],
[0, 0, 1],
[2, 2, 2]])
def test_background_one_region_center(self):
x = np.array([[0, 0, 0],
@@ -85,18 +83,18 @@ class TestConnectedComponents:
[0, 0, 0]])
assert_array_equal(label(x, neighbors=4, background=0),
[[-1, -1, -1],
[-1, 0, -1],
[-1, -1, -1]])
[[0, 0, 0],
[0, 1, 0],
[0, 0, 0]])
def test_return_num(self):
x = np.array([[1, 0, 6],
[0, 0, 6],
[5, 5, 5]])
assert_array_equal(label(x, return_num=True)[1], 4)
assert_array_equal(label(x, return_num=True)[1], 3)
assert_array_equal(label(x, background=0, return_num=True)[1], 3)
assert_array_equal(label(x, background=-1, return_num=True)[1], 4)
class TestConnectedComponents3d:
@@ -122,17 +120,17 @@ class TestConnectedComponents3d:
self.labels[0] = np.array([[0, 1, 2, 3, 4],
[0, 5, 4, 2, 4],
[0, 5, 4, 4, 4],
[1, 5, 6, 1, 7]])
[1, 5, 6, 1, 0]])
self.labels[1] = np.array([[1, 1, 2, 3, 4],
[0, 1, 4, 2, 3],
[0, 1, 1, 3, 3],
[1, 5, 1, 1, 7]])
[1, 5, 1, 1, 0]])
self.labels[2] = np.array([[1, 1, 8, 8, 9],
[10, 1, 4, 8, 8],
[10, 1, 7, 8, 7],
[10, 5, 7, 7, 7]])
self.labels[2] = np.array([[1, 1, 7, 7, 0],
[8, 1, 4, 7, 7],
[8, 1, 0, 7, 0],
[8, 5, 0, 0, 0]])
def test_basic(self):
labels = label(self.x)
@@ -176,22 +174,22 @@ class TestConnectedComponents3d:
[0, 0, 0]])
lnb = x.copy()
lnb[0] = np.array([[0, 1, 1],
[0, 1, 1],
[1, 1, 1]])
lnb[1] = np.array([[1, 1, 1],
[1, 0, 2],
[1, 1, 1]])
lnb[0] = np.array([[1, 2, 2],
[1, 2, 2],
[2, 2, 2]])
lnb[1] = np.array([[2, 2, 2],
[2, 1, 3],
[2, 2, 2]])
lb = x.copy()
lb[0] = np.array([[0, BG, BG],
[0, BG, BG],
lb[0] = np.array([[1, BG, BG],
[1, BG, BG],
[BG, BG, BG]])
lb[1] = np.array([[BG, BG, BG],
[BG, 0, 1],
[BG, 1, 2],
[BG, BG, BG]])
assert_array_equal(label(x), lnb)
assert_array_equal(label(x, background=0), lb)
assert_array_equal(label(x), lb)
assert_array_equal(label(x, background=-1), lnb)
def test_background_two_regions(self):
x = np.zeros((2, 3, 3), int)
@@ -202,11 +200,11 @@ class TestConnectedComponents3d:
[5, 0, 0],
[0, 0, 0]])
lb = x.copy()
lb[0] = np.array([[BG, BG, 0],
[BG, BG, 0],
[1, 1, 1]])
lb[1] = np.array([[0, 0, BG],
[1, BG, BG],
lb[0] = np.array([[BG, BG, 1],
[BG, BG, 1],
[2, 2, 2]])
lb[1] = np.array([[1, 1, BG],
[2, BG, BG],
[BG, BG, BG]])
res = label(x, background=0)
@@ -217,7 +215,7 @@ class TestConnectedComponents3d:
x[1, 1, 1] = 1
lb = np.ones_like(x) * BG
lb[1, 1, 1] = 0
lb[1, 1, 1] = 1
assert_array_equal(label(x, neighbors=4, background=0), lb)
@@ -226,13 +224,13 @@ class TestConnectedComponents3d:
[0, 0, 6],
[5, 5, 5]])
assert_array_equal(label(x, return_num=True)[1], 4)
assert_array_equal(label(x, background=0, return_num=True)[1], 3)
assert_array_equal(label(x, return_num=True)[1], 3)
assert_array_equal(label(x, background=-1, return_num=True)[1], 4)
def test_1D(self):
x = np.array((0, 1, 2, 2, 1, 1, 0, 0))
xlen = len(x)
y = np.array((0, 1, 2, 2, 3, 3, 4, 4))
y = np.array((0, 1, 2, 2, 3, 3, 0, 0))
reshapes = ((xlen,),
(1, xlen), (xlen, 1),
(1, xlen, 1), (xlen, 1, 1), (1, 1, xlen))
+1 -2
View File
@@ -1,5 +1,4 @@
import numpy as np
#from scipy.ndimage import label
from ..measure import label
@@ -60,7 +59,7 @@ def clear_border(labels, buffer_size=0, bgval=0, in_place=False):
# Re-label, in case we are dealing with a binary image
# and to get consistent labeling
labels = label(image, background=0) + 1
labels = label(image, background=0)
number = np.max(labels) + 1
# determine all objects that are connected to borders
@@ -82,8 +82,7 @@ def test_hough_line_peaks():
out, angles, d = tf.hough_line(img)
with expected_warnings(['`background`']):
out, theta, dist = tf.hough_line_peaks(out, angles, d)
out, theta, dist = tf.hough_line_peaks(out, angles, d)
assert_equal(len(dist), 1)
assert_almost_equal(dist[0], 80.723, 1)
@@ -101,9 +100,8 @@ def test_hough_line_peaks_ordered():
hough_space, angles, dists = tf.hough_line(testim)
with expected_warnings(['`background`']):
hspace, _, _ = tf.hough_line_peaks(hough_space, angles, dists)
assert hspace[0] > hspace[1]
hspace, _, _ = tf.hough_line_peaks(hough_space, angles, dists)
assert hspace[0] > hspace[1]
def test_hough_line_peaks_dist():
@@ -111,16 +109,14 @@ def test_hough_line_peaks_dist():
img[:, 30] = True
img[:, 40] = True
hspace, angles, dists = tf.hough_line(img)
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,
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()
check_hough_line_peaks_angle()
def check_hough_line_peaks_angle():
@@ -154,9 +150,8 @@ def test_hough_line_peaks_num():
img[:, 30] = True
img[:, 40] = True
hspace, angles, dists = tf.hough_line(img)
with expected_warnings(['`background`']):
assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=0,
min_angle=0, num_peaks=1)[0]) == 1
assert len(tf.hough_line_peaks(hspace, angles, dists, min_distance=0,
min_angle=0, num_peaks=1)[0]) == 1
@test_parallel()