Merge pull request #1007 from stefanv/label_refactor

Move `morphology.label` to `measure.label` and prepare for 0-label transition
This commit is contained in:
Johannes L. Schönberger
2014-05-25 21:56:42 -04:00
15 changed files with 76 additions and 35 deletions
+9
View File
@@ -1,3 +1,12 @@
Remember to list any API changes below in `doc/source/api_changes.txt`.
Version 0.12
------------
- Change `label` to mark background as 0, not -1, which is consistent with
SciPy's labelling.
- Remove `skimage.morphology.label` from `skimage.morphology.__init__`--it now
lives in `skimage.measure.label`.
Version 0.11
------------
* Remove deprecated `reverse_map` parameter of `skimage.transform.warp`
+2 -2
View File
@@ -64,9 +64,9 @@ Library:
Extension: skimage.filter._ctmf
Sources:
skimage/filter/_ctmf.pyx
Extension: skimage.morphology.ccomp
Extension: skimage.measure._ccomp
Sources:
skimage/morphology/ccomp.pyx
skimage/measure/_ccomp.pyx
Extension: skimage.morphology._watershed
Sources:
skimage/morphology/_watershed.pyx
-1
View File
@@ -24,4 +24,3 @@ Version 0.3
- Remove ``as_grey``, ``dtype`` keyword from ImageCollection
- Remove ``dtype`` from imread
- Generalise ImageCollection to accept a load_func
+3 -1
View File
@@ -8,6 +8,7 @@ from ._moments import moments, moments_central, moments_normalized, moments_hu
from .profile import profile_line
from .fit import LineModel, CircleModel, EllipseModel, ransac
from .block import block_reduce
from ._label import label
__all__ = ['find_contours',
@@ -28,4 +29,5 @@ __all__ = ['find_contours',
'marching_cubes',
'mesh_surface_area',
'correct_mesh_orientation',
'profile_line']
'profile_line',
'label']
@@ -4,6 +4,7 @@
#cython: wraparound=False
import numpy as np
import warnings
cimport numpy as cnp
@@ -82,7 +83,7 @@ cdef inline void link_bg(DTYPE_t *forest, DTYPE_t n, DTYPE_t *background_node):
# Connected components search as described in Fiorio et al.
def label(input, DTYPE_t neighbors=8, DTYPE_t background=-1, return_num=False):
def label(input, DTYPE_t neighbors=8, background=None, return_num=False):
"""Label connected regions of an integer array.
Two pixels are connected when they are neighbors and have the same value.
@@ -100,11 +101,14 @@ def label(input, DTYPE_t neighbors=8, DTYPE_t background=-1, return_num=False):
----------
input : ndarray of dtype int
Image to label.
neighbors : {4, 8}, int
neighbors : {4, 8}, int, optional
Whether to use 4- or 8-connectivity.
background : int
background : int, optional
Consider all pixels with this value as background pixels, and label
them as -1.
them as -1. (Note: background pixels will be labeled as 0 starting with
version 0.12).
return_num : bool, optional
Whether to return the number of assigned labels.
Returns
-------
@@ -157,17 +161,27 @@ def label(input, DTYPE_t neighbors=8, DTYPE_t background=-1, return_num=False):
cdef DTYPE_t i, j
cdef DTYPE_t background_val
if background is None:
background_val = -1
warnings.warn(DeprecationWarning(
'The default value for `background` will change to 0 in v0.12'
))
else:
background_val = background
cdef DTYPE_t background_node = -999
if neighbors != 4 and neighbors != 8:
raise ValueError('Neighbors must be either 4 or 8.')
# Initialize the first row
if data[0, 0] == background:
if data[0, 0] == background_val:
link_bg(forest_p, 0, &background_node)
for j in range(1, cols):
if data[0, j] == background:
if data[0, j] == background_val:
link_bg(forest_p, j, &background_node)
if data[0, j] == data[0, j-1]:
@@ -175,7 +189,7 @@ def label(input, DTYPE_t neighbors=8, DTYPE_t background=-1, return_num=False):
for i in range(1, rows):
# Handle the first column
if data[i, 0] == background:
if data[i, 0] == background_val:
link_bg(forest_p, i * cols, &background_node)
if data[i, 0] == data[i-1, 0]:
@@ -186,7 +200,7 @@ def label(input, DTYPE_t neighbors=8, DTYPE_t background=-1, return_num=False):
join_trees(forest_p, i*cols, (i-1)*cols + 1)
for j in range(1, cols):
if data[i, j] == background:
if data[i, j] == background_val:
link_bg(forest_p, i * cols + j, &background_node)
if neighbors == 8:
+6
View File
@@ -0,0 +1,6 @@
from ._ccomp import label as _label
def label(input, neighbors=8, background=None, return_num=False):
return _label(input, neighbors, background, return_num)
label.__doc__ = _label.__doc__
+3 -2
View File
@@ -4,8 +4,8 @@ from math import sqrt, atan2, pi as PI
import numpy as np
from scipy import ndimage
from skimage.morphology import convex_hull_image, label
from skimage.measure import _moments
from ._label import label
from . import _moments
__all__ = ['regionprops', 'perimeter']
@@ -135,6 +135,7 @@ class _RegionProperties(object):
@_cached_property
def convex_image(self):
from ..morphology.convex_hull import convex_hull_image
return convex_hull_image(self.image)
@_cached_property
+3
View File
@@ -12,10 +12,13 @@ def configuration(parent_package='', top_path=None):
config = Configuration('measure', parent_package, top_path)
config.add_data_dir('tests')
cython(['_ccomp.pyx'], working_path=base_path)
cython(['_find_contours_cy.pyx'], working_path=base_path)
cython(['_moments.pyx'], working_path=base_path)
cython(['_marching_cubes_cy.pyx'], working_path=base_path)
config.add_extension('_ccomp', sources=['_ccomp.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('_find_contours_cy', sources=['_find_contours_cy.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('_moments', sources=['_moments.c'],
+4 -1
View File
@@ -4,13 +4,16 @@ from .grey import (erosion, dilation, opening, closing, white_tophat,
black_tophat)
from .selem import (square, rectangle, diamond, disk, cube, octahedron, ball,
octagon, star)
from .ccomp import label
from .watershed import watershed
from ._skeletonize import skeletonize, medial_axis
from .convex_hull import convex_hull_image, convex_hull_object
from .greyreconstruct import reconstruction
from .misc import remove_small_objects
from ..measure._label import label
from skimage._shared.utils import deprecated as _deprecated
label = _deprecated('skimage.measure.label')(label)
__all__ = ['binary_erosion',
'binary_dilation',
+1 -1
View File
@@ -3,7 +3,7 @@ __all__ = ['convex_hull_image', 'convex_hull_object']
import numpy as np
from ._pnpoly import grid_points_inside_poly
from ._convex_hull import possible_hull
from skimage.morphology import label
from ..measure._label import label
from skimage.util import unique_rows
-3
View File
@@ -12,7 +12,6 @@ def configuration(parent_package='', top_path=None):
config = Configuration('morphology', parent_package, top_path)
config.add_data_dir('tests')
cython(['ccomp.pyx'], working_path=base_path)
cython(['cmorph.pyx'], working_path=base_path)
cython(['_watershed.pyx'], working_path=base_path)
cython(['_skeletonize_cy.pyx'], working_path=base_path)
@@ -20,8 +19,6 @@ def configuration(parent_package='', top_path=None):
cython(['_convex_hull.pyx'], working_path=base_path)
cython(['_greyreconstruct.pyx'], working_path=base_path)
config.add_extension('ccomp', sources=['ccomp.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('cmorph', sources=['cmorph.c'],
include_dirs=[get_numpy_include_dirs()])
config.add_extension('_watershed', sources=['_watershed.c'],
+21 -14
View File
@@ -2,7 +2,8 @@ import numpy as np
from numpy.testing import assert_array_equal, run_module_suite
from skimage.morphology import label
from warnings import catch_warnings
from skimage._shared.utils import skimage_deprecation
class TestConnectedComponents:
def setup(self):
@@ -25,7 +26,9 @@ class TestConnectedComponents:
def test_random(self):
x = (np.random.random((20, 30)) * 5).astype(np.int)
labels = label(x)
with catch_warnings():
labels = label(x)
n = labels.max()
for i in range(n):
values = x[labels == i]
@@ -35,27 +38,29 @@ class TestConnectedComponents:
x = np.array([[0, 0, 1],
[0, 1, 0],
[1, 0, 0]])
assert_array_equal(label(x),
x)
with catch_warnings():
assert_array_equal(label(x), x)
def test_4_vs_8(self):
x = np.array([[0, 1],
[1, 0]], dtype=int)
assert_array_equal(label(x, 4),
[[0, 1],
[2, 3]])
assert_array_equal(label(x, 8),
[[0, 1],
[1, 0]])
with catch_warnings():
assert_array_equal(label(x, 4),
[[0, 1],
[2, 3]])
assert_array_equal(label(x, 8),
[[0, 1],
[1, 0]])
def test_background(self):
x = np.array([[1, 0, 0],
[1, 1, 5],
[0, 0, 0]])
assert_array_equal(label(x), [[0, 1, 1],
[0, 0, 2],
[3, 3, 3]])
with catch_warnings():
assert_array_equal(label(x), [[0, 1, 1],
[0, 0, 2],
[3, 3, 3]])
assert_array_equal(label(x, background=0),
[[0, -1, -1],
@@ -87,7 +92,9 @@ class TestConnectedComponents:
[0, 0, 6],
[5, 5, 5]])
assert_array_equal(label(x, return_num=True)[1], 4)
with catch_warnings():
assert_array_equal(label(x, return_num=True)[1], 4)
assert_array_equal(label(x, background=0, return_num=True)[1], 3)
+1 -1
View File
@@ -7,7 +7,7 @@ import scipy
cimport cython
cimport numpy as cnp
from skimage.morphology.ccomp cimport find_root, join_trees
from skimage.measure._ccomp cimport find_root, join_trees
from ..util import img_as_float
+1 -1
View File
@@ -71,7 +71,7 @@ def hough_line_peaks(hspace, angles, dists, min_distance=9, min_angle=10,
hspace *= mask
hspace_t = hspace > threshold
label_hspace = morphology.label(hspace_t)
label_hspace = measure.label(hspace_t)
props = measure.regionprops(label_hspace)
coords = np.array([np.round(p.centroid) for p in props], dtype=int)