Add relabel_sequential, deprecate relabel_from_one

This commit is contained in:
Juan Nunez-Iglesias
2013-10-03 16:08:29 +10:00
parent 547c0bb7d8
commit 1843829917
+26 -5
View File
@@ -1,4 +1,5 @@
import numpy as np
from skimage._shared.utils import deprecated
def join_segmentations(s1, s2):
@@ -42,9 +43,18 @@ def join_segmentations(s1, s2):
return j
@deprecated('relabel_sequential')
def relabel_from_one(label_field):
"""Convert labels in an arbitrary label field to {1, ... number_of_labels}.
This function is deprecated, see ``relabel_sequential`` for more.
"""
return relabel_sequential(label_field, offset=1)
def relabel_sequential(label_field, offset=1):
"""Relabel arbitrary labels to {`offset`, ... `offset` + number_of_labels}.
This function also returns the forward map (mapping the original labels to
the reduced labels) and the inverse map (mapping the reduced labels back
to the original ones).
@@ -52,6 +62,10 @@ def relabel_from_one(label_field):
Parameters
----------
label_field : numpy array of int, arbitrary shape
An array of labels.
offset : int, optional
The return labels will start at `offset`, which should be
strictly positive.
Returns
-------
@@ -62,13 +76,15 @@ def relabel_from_one(label_field):
The map from the original label space to the returned label
space. Can be used to re-apply the same mapping. See examples
for usage.
inverse_map : numpy array of int, shape ``(len(np.unique(label_field)),)``
inverse_map : 1D numpy array of int, of length offset + number of labels
The map from the new label space to the original space. This
can be used to reconstruct the original label field from the
relabeled one.
Notes
-----
The label 0 is assumed to denote the background and is never remapped.
The forward map can be extremely big for some inputs, since its
length is given by the maximum of the label field. However, in most
situations, ``label_field.max()`` is much smaller than
@@ -79,7 +95,7 @@ def relabel_from_one(label_field):
--------
>>> from skimage.segmentation import relabel_from_one
>>> label_field = array([1, 1, 5, 5, 8, 99, 42])
>>> relab, fw, inv = relabel_from_one(label_field)
>>> relab, fw, inv = relabel_sequential(label_field)
>>> relab
array([1, 1, 2, 2, 3, 5, 4])
>>> fw
@@ -94,6 +110,9 @@ def relabel_from_one(label_field):
True
>>> (inv[relab] == label_field).all()
True
>>> relab, fw, inv = relabel_sequential(label_field, offset=5)
>>> relab
array([5, 5, 6, 6, 7, 9, 8])
"""
labels = np.unique(label_field)
labels0 = labels[labels != 0]
@@ -101,9 +120,11 @@ def relabel_from_one(label_field):
if m == len(labels0): # nothing to do, already 1...n labels
return label_field, labels, labels
forward_map = np.zeros(m+1, int)
forward_map[labels0] = np.arange(1, len(labels0) + 1)
forward_map[labels0] = np.arange(offset, offset + len(labels0) + 1)
if not (labels == 0).any():
labels = np.concatenate(([0], labels))
inverse_map = labels
return forward_map[label_field], forward_map, inverse_map
inverse_map = np.zeros(offset - 1 + len(labels), dtype=np.intp)
inverse_map[(offset - 1):] = labels
relabeled = forward_map[label_field]
return relabeled, forward_map, inverse_map