mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-19 11:27:45 +08:00
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:
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
@@ -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__
|
||||
@@ -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
|
||||
|
||||
@@ -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,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',
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user