mirror of
https://github.com/wassname/scikit-image.git
synced 2026-08-02 13:03:48 +08:00
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:
@@ -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.
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,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()
|
||||
|
||||
Reference in New Issue
Block a user