Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add label2rgb #485

Merged
merged 7 commits into from Jun 23, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion doc/examples/applications/plot_coins_segmentation.py
Expand Up @@ -160,16 +160,19 @@

"""

from skimage.color import label2rgb

segmentation = ndimage.binary_fill_holes(segmentation - 1)
labeled_coins, _ = ndimage.label(segmentation)
image_label_overlay = label2rgb(labeled_coins, image=coins)

plt.figure(figsize=(6, 3))
plt.subplot(121)
plt.imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
plt.contour(segmentation, [0.5], linewidths=1.2, colors='y')
plt.axis('off')
plt.subplot(122)
plt.imshow(labeled_coins, cmap=plt.cm.spectral, interpolation='nearest')
plt.imshow(image_label_overlay, interpolation='nearest')
plt.axis('off')

plt.subplots_adjust(**margins)
Expand Down
23 changes: 10 additions & 13 deletions doc/examples/plot_join_segmentations.py
Expand Up @@ -13,11 +13,11 @@
import numpy as np
from scipy import ndimage as nd
import matplotlib.pyplot as plt
import matplotlib as mpl

from skimage.filter import sobel
from skimage.segmentation import slic, join_segmentations
from skimage.morphology import watershed
from skimage.color import label2rgb
from skimage import data


Expand All @@ -43,24 +43,21 @@
# combine the two
segj = join_segmentations(seg1, seg2)

### Display the result ###

# make a random colormap for a set number of values
def random_cmap(im):
np.random.seed(9)
cmap_array = np.concatenate(
(np.zeros((1, 3)), np.random.rand(np.ceil(im.max()), 3)))
return mpl.colors.ListedColormap(cmap_array)

# show the segmentations
fig, axes = plt.subplots(ncols=4, figsize=(9, 2.5))
axes[0].imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
axes[0].set_title('Image')
axes[1].imshow(seg1, cmap=random_cmap(seg1), interpolation='nearest')

color1 = label2rgb(seg1, image=coins, bg_label=0)
axes[1].imshow(color1, interpolation='nearest')
axes[1].set_title('Sobel+Watershed')
axes[2].imshow(seg2, cmap=random_cmap(seg2), interpolation='nearest')

color2 = label2rgb(seg2, image=coins, image_alpha=0.5)
axes[2].imshow(color2, interpolation='nearest')
axes[2].set_title('SLIC superpixels')
axes[3].imshow(segj, cmap=random_cmap(segj), interpolation='nearest')

color3 = label2rgb(segj, image=coins, image_alpha=0.5)
axes[3].imshow(color3, interpolation='nearest')
axes[3].set_title('Join')

for ax in axes:
Expand Down
4 changes: 3 additions & 1 deletion doc/examples/plot_label.py
Expand Up @@ -21,6 +21,7 @@
from skimage.segmentation import clear_border
from skimage.morphology import label, closing, square
from skimage.measure import regionprops
from skimage.color import label2rgb


image = data.coins()[50:-50, 50:-50]
Expand All @@ -37,9 +38,10 @@
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))
ax.imshow(label_image, cmap='jet')
ax.imshow(image_label_overlay)

for region in regionprops(label_image, ['Area', 'BoundingBox']):

Expand Down
13 changes: 12 additions & 1 deletion skimage/_shared/utils.py
Expand Up @@ -2,7 +2,18 @@
import functools


__all__ = ['deprecated']
__all__ = ['deprecated', 'is_str']


try:
isinstance("", basestring)
def is_str(s):
"""Return True if `s` is a string. Safe for Python 2 and 3."""
return isinstance(s, basestring)
except NameError:
def is_str(s):
"""Return True if `s` is a string. Safe for Python 2 and 3."""
return isinstance(s, str)


class deprecated(object):
Expand Down
7 changes: 6 additions & 1 deletion skimage/color/__init__.py
Expand Up @@ -41,6 +41,9 @@
is_rgb,
is_gray)

from .colorlabel import color_dict, label2rgb


__all__ = ['convert_colorspace',
'rgb2hsv',
'hsv2rgb',
Expand Down Expand Up @@ -82,4 +85,6 @@
'rgb_from_hpx',
'hpx_from_rgb',
'is_rgb',
'is_gray']
'is_gray',
'color_dict',
'label2rgb']
95 changes: 95 additions & 0 deletions skimage/color/colorlabel.py
@@ -0,0 +1,95 @@
import warnings
import itertools

import numpy as np

from skimage import img_as_float
from skimage._shared.utils import is_str
from .colorconv import rgb2gray, gray2rgb
from . import rgb_colors


__all__ = ['color_dict', 'label2rgb', 'DEFAULT_COLORS']


DEFAULT_COLORS = ('red', 'blue', 'yellow', 'magenta', 'green',
'indigo', 'darkorange', 'cyan', 'pink', 'yellowgreen')


color_dict = rgb_colors.__dict__


def _rgb_vector(color):
"""Return RGB color as (1, 3) array.

This RGB array gets multiplied by masked regions of an RGB image, which are
partially flattened by masking (i.e. dimensions 2D + RGB -> 1D + RGB).

Parameters
----------
color : str or array
Color name in `color_dict` or RGB float values between [0, 1].
"""
if is_str(color):
color = color_dict[color]
# slice to handle RGBA colors
return np.array(color[:3]).reshape(1, 3)


def label2rgb(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
Integer array of labels with the same shape as `image`.
image : array
Image used as underlay for labels. If the input is an RGB image, it's
converted to grayscale before coloring.
colors : list
List of colors. If the number of labels exceeds the number of colors,
then the colors are cycled.
alpha : float [0, 1]
Opacity of colorized labels. Ignored if image is `None`.
bg_label : int
Label that's treated as the background.
bg_color : str or array
Background color. Must be a name in `color_dict` or RGB float values
between [0, 1].
image_alpha : float [0, 1]
Opacity of the image.
"""
if colors is None:
colors = DEFAULT_COLORS
colors = [_rgb_vector(c) for c in colors]

if image is None:
colorized = np.zeros(label.shape + (3,), dtype=np.float64)
# Opacity doesn't make sense if no image exists.
alpha = 1
else:
if not image.shape[:2] == label.shape:
raise ValueError("`image` and `label` must be the same shape")

if image.min() < 0:
warnings.warn("Negative intensities in `image` are not supported")

image = img_as_float(rgb2gray(image))
colorized = gray2rgb(image) * image_alpha + (1 - image_alpha)

labels = list(set(label.flat))
color_cycle = itertools.cycle(colors)

if bg_label in labels:
labels.remove(bg_label)
if bg_color is not None:
labels.insert(0, bg_label)
bg_color = _rgb_vector(bg_color)
color_cycle = itertools.chain(bg_color, color_cycle)

for c, i in itertools.izip(color_cycle, labels):
mask = (label == i)
colorized[mask] = c * alpha + colorized[mask] * (1 - alpha)

return colorized
146 changes: 146 additions & 0 deletions skimage/color/rgb_colors.py
@@ -0,0 +1,146 @@
aliceblue = (0.941, 0.973, 1)
antiquewhite = (0.98, 0.922, 0.843)
aqua = (0, 1, 1)
aquamarine = (0.498, 1, 0.831)
azure = (0.941, 1, 1)
beige = (0.961, 0.961, 0.863)
bisque = (1, 0.894, 0.769)
black = (0, 0, 0)
blanchedalmond = (1, 0.922, 0.804)
blue = (0, 0, 1)
blueviolet = (0.541, 0.169, 0.886)
brown = (0.647, 0.165, 0.165)
burlywood = (0.871, 0.722, 0.529)
cadetblue = (0.373, 0.62, 0.627)
chartreuse = (0.498, 1, 0)
chocolate = (0.824, 0.412, 0.118)
coral = (1, 0.498, 0.314)
cornflowerblue = (0.392, 0.584, 0.929)
cornsilk = (1, 0.973, 0.863)
crimson = (0.863, 0.0784, 0.235)
cyan = (0, 1, 1)
darkblue = (0, 0, 0.545)
darkcyan = (0, 0.545, 0.545)
darkgoldenrod = (0.722, 0.525, 0.0431)
darkgray = (0.663, 0.663, 0.663)
darkgreen = (0, 0.392, 0)
darkgrey = (0.663, 0.663, 0.663)
darkkhaki = (0.741, 0.718, 0.42)
darkmagenta = (0.545, 0, 0.545)
darkolivegreen = (0.333, 0.42, 0.184)
darkorange = (1, 0.549, 0)
darkorchid = (0.6, 0.196, 0.8)
darkred = (0.545, 0, 0)
darksalmon = (0.914, 0.588, 0.478)
darkseagreen = (0.561, 0.737, 0.561)
darkslateblue = (0.282, 0.239, 0.545)
darkslategray = (0.184, 0.31, 0.31)
darkslategrey = (0.184, 0.31, 0.31)
darkturquoise = (0, 0.808, 0.82)
darkviolet = (0.58, 0, 0.827)
deeppink = (1, 0.0784, 0.576)
deepskyblue = (0, 0.749, 1)
dimgray = (0.412, 0.412, 0.412)
dimgrey = (0.412, 0.412, 0.412)
dodgerblue = (0.118, 0.565, 1)
firebrick = (0.698, 0.133, 0.133)
floralwhite = (1, 0.98, 0.941)
forestgreen = (0.133, 0.545, 0.133)
fuchsia = (1, 0, 1)
gainsboro = (0.863, 0.863, 0.863)
ghostwhite = (0.973, 0.973, 1)
gold = (1, 0.843, 0)
goldenrod = (0.855, 0.647, 0.125)
gray = (0.502, 0.502, 0.502)
green = (0, 0.502, 0)
greenyellow = (0.678, 1, 0.184)
grey = (0.502, 0.502, 0.502)
honeydew = (0.941, 1, 0.941)
hotpink = (1, 0.412, 0.706)
indianred = (0.804, 0.361, 0.361)
indigo = (0.294, 0, 0.51)
ivory = (1, 1, 0.941)
khaki = (0.941, 0.902, 0.549)
lavender = (0.902, 0.902, 0.98)
lavenderblush = (1, 0.941, 0.961)
lawngreen = (0.486, 0.988, 0)
lemonchiffon = (1, 0.98, 0.804)
lightblue = (0.678, 0.847, 0.902)
lightcoral = (0.941, 0.502, 0.502)
lightcyan = (0.878, 1, 1)
lightgoldenrodyellow = (0.98, 0.98, 0.824)
lightgray = (0.827, 0.827, 0.827)
lightgreen = (0.565, 0.933, 0.565)
lightgrey = (0.827, 0.827, 0.827)
lightpink = (1, 0.714, 0.757)
lightsalmon = (1, 0.627, 0.478)
lightseagreen = (0.125, 0.698, 0.667)
lightskyblue = (0.529, 0.808, 0.98)
lightslategray = (0.467, 0.533, 0.6)
lightslategrey = (0.467, 0.533, 0.6)
lightsteelblue = (0.69, 0.769, 0.871)
lightyellow = (1, 1, 0.878)
lime = (0, 1, 0)
limegreen = (0.196, 0.804, 0.196)
linen = (0.98, 0.941, 0.902)
magenta = (1, 0, 1)
maroon = (0.502, 0, 0)
mediumaquamarine = (0.4, 0.804, 0.667)
mediumblue = (0, 0, 0.804)
mediumorchid = (0.729, 0.333, 0.827)
mediumpurple = (0.576, 0.439, 0.859)
mediumseagreen = (0.235, 0.702, 0.443)
mediumslateblue = (0.482, 0.408, 0.933)
mediumspringgreen = (0, 0.98, 0.604)
mediumturquoise = (0.282, 0.82, 0.8)
mediumvioletred = (0.78, 0.0824, 0.522)
midnightblue = (0.098, 0.098, 0.439)
mintcream = (0.961, 1, 0.98)
mistyrose = (1, 0.894, 0.882)
moccasin = (1, 0.894, 0.71)
navajowhite = (1, 0.871, 0.678)
navy = (0, 0, 0.502)
oldlace = (0.992, 0.961, 0.902)
olive = (0.502, 0.502, 0)
olivedrab = (0.42, 0.557, 0.137)
orange = (1, 0.647, 0)
orangered = (1, 0.271, 0)
orchid = (0.855, 0.439, 0.839)
palegoldenrod = (0.933, 0.91, 0.667)
palegreen = (0.596, 0.984, 0.596)
palevioletred = (0.686, 0.933, 0.933)
papayawhip = (1, 0.937, 0.835)
peachpuff = (1, 0.855, 0.725)
peru = (0.804, 0.522, 0.247)
pink = (1, 0.753, 0.796)
plum = (0.867, 0.627, 0.867)
powderblue = (0.69, 0.878, 0.902)
purple = (0.502, 0, 0.502)
red = (1, 0, 0)
rosybrown = (0.737, 0.561, 0.561)
royalblue = (0.255, 0.412, 0.882)
saddlebrown = (0.545, 0.271, 0.0745)
salmon = (0.98, 0.502, 0.447)
sandybrown = (0.98, 0.643, 0.376)
seagreen = (0.18, 0.545, 0.341)
seashell = (1, 0.961, 0.933)
sienna = (0.627, 0.322, 0.176)
silver = (0.753, 0.753, 0.753)
skyblue = (0.529, 0.808, 0.922)
slateblue = (0.416, 0.353, 0.804)
slategray = (0.439, 0.502, 0.565)
slategrey = (0.439, 0.502, 0.565)
snow = (1, 0.98, 0.98)
springgreen = (0, 1, 0.498)
steelblue = (0.275, 0.51, 0.706)
tan = (0.824, 0.706, 0.549)
teal = (0, 0.502, 0.502)
thistle = (0.847, 0.749, 0.847)
tomato = (1, 0.388, 0.278)
turquoise = (0.251, 0.878, 0.816)
violet = (0.933, 0.51, 0.933)
wheat = (0.961, 0.871, 0.702)
white = (1, 1, 1)
whitesmoke = (0.961, 0.961, 0.961)
yellow = (1, 1, 0)
yellowgreen = (0.604, 0.804, 0.196)