mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-13 17:45:20 +08:00
Merge pull request #1033 from jni/label_image
Add "average segment color" method for `label2rgb`
This commit is contained in:
@@ -64,28 +64,76 @@ def _match_label_with_color(label, colors, bg_label, bg_color):
|
||||
|
||||
|
||||
def label2rgb(label, image=None, colors=None, alpha=0.3,
|
||||
bg_label=-1, bg_color=None, image_alpha=1):
|
||||
bg_label=-1, bg_color=None, image_alpha=1, kind='overlay'):
|
||||
"""Return an RGB image where color-coded labels are painted over the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
label : array
|
||||
label : array, shape (M, N)
|
||||
Integer array of labels with the same shape as `image`.
|
||||
image : array
|
||||
image : array, shape (M, N, 3), optional
|
||||
Image used as underlay for labels. If the input is an RGB image, it's
|
||||
converted to grayscale before coloring.
|
||||
colors : list
|
||||
colors : list, optional
|
||||
List of colors. If the number of labels exceeds the number of colors,
|
||||
then the colors are cycled.
|
||||
alpha : float [0, 1]
|
||||
alpha : float [0, 1], optional
|
||||
Opacity of colorized labels. Ignored if image is `None`.
|
||||
bg_label : int
|
||||
bg_label : int, optional
|
||||
Label that's treated as the background.
|
||||
bg_color : str or array
|
||||
bg_color : str or array, optional
|
||||
Background color. Must be a name in `color_dict` or RGB float values
|
||||
between [0, 1].
|
||||
image_alpha : float [0, 1]
|
||||
image_alpha : float [0, 1], optional
|
||||
Opacity of the image.
|
||||
kind : string, one of {'overlay', 'avg'}
|
||||
The kind of color image desired. 'overlay' cycles over defined colors
|
||||
and overlays the colored labels over the original image. 'avg' replaces
|
||||
each labeled segment with its average color, for a stained-class or
|
||||
pastel painting appearance.
|
||||
|
||||
Returns
|
||||
-------
|
||||
result : array of float, shape (M, N, 3)
|
||||
The result of blending a cycling colormap (`colors`) for each distinct
|
||||
value in `label` with the image, at a certain alpha value.
|
||||
"""
|
||||
if kind == 'overlay':
|
||||
return _label2rgb_overlay(label, image, colors, alpha, bg_label,
|
||||
bg_color, image_alpha)
|
||||
else:
|
||||
return _label2rgb_avg(label, image, bg_label, bg_color)
|
||||
|
||||
|
||||
def _label2rgb_overlay(label, image=None, colors=None, alpha=0.3,
|
||||
bg_label=-1, bg_color=None, image_alpha=1):
|
||||
"""Return an RGB image where color-coded labels are painted over the image.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
label : array, shape (M, N)
|
||||
Integer array of labels with the same shape as `image`.
|
||||
image : array, shape (M, N, 3), optional
|
||||
Image used as underlay for labels. If the input is an RGB image, it's
|
||||
converted to grayscale before coloring.
|
||||
colors : list, optional
|
||||
List of colors. If the number of labels exceeds the number of colors,
|
||||
then the colors are cycled.
|
||||
alpha : float [0, 1], optional
|
||||
Opacity of colorized labels. Ignored if image is `None`.
|
||||
bg_label : int, optional
|
||||
Label that's treated as the background.
|
||||
bg_color : str or array, optional
|
||||
Background color. Must be a name in `color_dict` or RGB float values
|
||||
between [0, 1].
|
||||
image_alpha : float [0, 1], optional
|
||||
Opacity of the image.
|
||||
|
||||
Returns
|
||||
-------
|
||||
result : array of float, shape (M, N, 3)
|
||||
The result of blending a cycling colormap (`colors`) for each distinct
|
||||
value in `label` with the image, at a certain alpha value.
|
||||
"""
|
||||
if colors is None:
|
||||
colors = DEFAULT_COLORS
|
||||
@@ -134,3 +182,35 @@ def label2rgb(label, image=None, colors=None, alpha=0.3,
|
||||
result[label == bg_label] = image[label == bg_label]
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def _label2rgb_avg(label_field, image, bg_label=0, bg_color=(0, 0, 0)):
|
||||
"""Visualise each segment in `label_field` with its mean color in `image`.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
label_field : array of int
|
||||
A segmentation of an image.
|
||||
image : array, shape ``label_field.shape + (3,)``
|
||||
A color image of the same spatial shape as `label_field`.
|
||||
bg_label : int, optional
|
||||
A value in `label_field` to be treated as background.
|
||||
bg_color : 3-tuple of int, optional
|
||||
The color for the background label
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : array, same shape and type as `image`
|
||||
The output visualization.
|
||||
"""
|
||||
out = np.zeros_like(image)
|
||||
labels = np.unique(label_field)
|
||||
bg = (labels == bg_label)
|
||||
if bg.any():
|
||||
labels = labels[labels != bg_label]
|
||||
out[bg] = bg_color
|
||||
for label in labels:
|
||||
mask = (label_field == label).nonzero()
|
||||
color = image[mask].mean(axis=0)
|
||||
out[mask] = color
|
||||
return out
|
||||
|
||||
@@ -89,6 +89,39 @@ def test_leave_labels_alone():
|
||||
label2rgb(labels, bg_label=1)
|
||||
assert_array_equal(labels, labels_saved)
|
||||
|
||||
def test_avg():
|
||||
label_field = np.array([[1, 1, 1, 2],
|
||||
[1, 2, 2, 2],
|
||||
[3, 3, 3, 3]], dtype=np.uint8)
|
||||
r = np.array([[1., 1., 0., 0.],
|
||||
[0., 0., 1., 1.],
|
||||
[0., 0., 0., 0.]])
|
||||
g = np.array([[0., 0., 0., 1.],
|
||||
[1., 1., 1., 0.],
|
||||
[0., 0., 0., 0.]])
|
||||
b = np.array([[0., 0., 0., 1.],
|
||||
[0., 1., 1., 1.],
|
||||
[0., 0., 1., 1.]])
|
||||
image = np.dstack((r, g, b))
|
||||
out = label2rgb(label_field, image, kind='avg')
|
||||
rout = np.array([[0.5, 0.5, 0.5, 0.5],
|
||||
[0.5, 0.5, 0.5, 0.5],
|
||||
[0. , 0. , 0. , 0. ]])
|
||||
gout = np.array([[0.25, 0.25, 0.25, 0.75],
|
||||
[0.25, 0.75, 0.75, 0.75],
|
||||
[0. , 0. , 0. , 0. ]])
|
||||
bout = np.array([[0. , 0. , 0. , 1. ],
|
||||
[0. , 1. , 1. , 1. ],
|
||||
[0.5, 0.5, 0.5, 0.5]])
|
||||
expected_out = np.dstack((rout, gout, bout))
|
||||
assert_array_equal(out, expected_out)
|
||||
|
||||
out_bg = label2rgb(label_field, image, bg_label=2, bg_color=(0, 0, 0),
|
||||
kind='avg')
|
||||
expected_out_bg = expected_out.copy()
|
||||
expected_out_bg[label_field == 2] = 0
|
||||
assert_array_equal(out_bg, expected_out_bg)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
testing.run_module_suite()
|
||||
|
||||
Reference in New Issue
Block a user