mirror of
https://github.com/wassname/scikit-image.git
synced 2026-06-29 15:12:03 +08:00
Merge pull request #457 from tonysyu/logo_refactor
RF: Refactor code that generates scikit-image logo.
This commit is contained in:
+75
-135
@@ -1,17 +1,26 @@
|
||||
"""
|
||||
Script to draw skimage logo using Scipy logo as stencil. The easiest
|
||||
starting point is the `plot_colorized_logo`; the "if-main" demonstrates its use.
|
||||
starting point is the `plot_colorized_logo`.
|
||||
|
||||
Original snake image from pixabay [1]_
|
||||
|
||||
.. [1] http://pixabay.com/en/snake-green-toxic-close-yellow-3237/
|
||||
"""
|
||||
import numpy as np
|
||||
import sys
|
||||
if len(sys.argv) != 2 or sys.argv[1] != '--no-plot':
|
||||
print "Run with '--no-plot' flag to generate logo silently."
|
||||
else:
|
||||
import matplotlib as mpl
|
||||
mpl.use('Agg')
|
||||
import matplotlib.pyplot as plt
|
||||
import scipy.misc
|
||||
|
||||
import numpy as np
|
||||
|
||||
import skimage.io as sio
|
||||
import skimage.filter as imfilt
|
||||
from skimage import img_as_float
|
||||
from skimage.color import gray2rgb, rgb2gray
|
||||
from skimage.exposure import rescale_intensity
|
||||
from skimage.filter import sobel
|
||||
|
||||
import scipy_logo
|
||||
|
||||
@@ -19,42 +28,21 @@ import scipy_logo
|
||||
# Utility functions
|
||||
# =================
|
||||
|
||||
def get_edges(img):
|
||||
edge = np.empty(img.shape)
|
||||
if len(img.shape) == 3:
|
||||
for i in range(3):
|
||||
edge[:, :, i] = imfilt.sobel(img[:, :, i])
|
||||
else:
|
||||
edge = imfilt.sobel(img)
|
||||
edge = rescale_intensity(edge)
|
||||
return edge
|
||||
def colorize(image, color, whiten=False):
|
||||
"""Return colorized image from gray scale image.
|
||||
|
||||
def rescale_intensity(img):
|
||||
i_range = float(img.max() - img.min())
|
||||
img = (img - img.min()) / i_range * 255
|
||||
return np.uint8(img)
|
||||
|
||||
def colorize(img, color, whiten=False):
|
||||
"""Return colorized image from gray scale image
|
||||
|
||||
Parameters
|
||||
----------
|
||||
img : N x M array
|
||||
grayscale image
|
||||
color : length-3 sequence of floats
|
||||
RGB color spec. Float values should be between 0 and 1.
|
||||
whiten : bool
|
||||
If True, a color value less than 1 increases the image intensity.
|
||||
The colorized image has values from ranging between black at the lowest
|
||||
intensity to `color` at the highest. If `whiten=True`, then the color
|
||||
ranges from `color` to white.
|
||||
"""
|
||||
color = np.asarray(color)[np.newaxis, np.newaxis, :]
|
||||
img = img[:, :, np.newaxis]
|
||||
image = image[:, :, np.newaxis]
|
||||
if whiten:
|
||||
# truncate and stretch intensity range to enhance contrast
|
||||
img = np.clip(img, 80, 255)
|
||||
img = rescale_intensity(img)
|
||||
return np.uint8(color * (255 - img) + img)
|
||||
image = rescale_intensity(image, in_range=(0.3, 1))
|
||||
return color * (1 - image) + image
|
||||
else:
|
||||
return np.uint8(img * color)
|
||||
return image * color
|
||||
|
||||
|
||||
def prepare_axes(ax):
|
||||
@@ -65,16 +53,6 @@ def prepare_axes(ax):
|
||||
spine.set_visible(False)
|
||||
|
||||
|
||||
_rgb_stack = np.ones((1, 1, 3), dtype=bool)
|
||||
def gray2rgb(arr):
|
||||
"""Return RGB image from a grayscale image.
|
||||
|
||||
Expand h x w image to h x w x 3 image where color channels are simply copies
|
||||
of the grayscale image.
|
||||
"""
|
||||
return arr[:, :, np.newaxis] * _rgb_stack
|
||||
|
||||
|
||||
# Logo generating classes
|
||||
# =======================
|
||||
|
||||
@@ -82,21 +60,17 @@ class LogoBase(object):
|
||||
|
||||
def __init__(self):
|
||||
self.logo = scipy_logo.ScipyLogo(radius=self.radius)
|
||||
self.mask_1 = self.logo.get_mask(self.img.shape, 'upper left')
|
||||
self.mask_2 = self.logo.get_mask(self.img.shape, 'lower right')
|
||||
self.edges = get_edges(self.img)
|
||||
self.mask_1 = self.logo.get_mask(self.image.shape, 'upper left')
|
||||
self.mask_2 = self.logo.get_mask(self.image.shape, 'lower right')
|
||||
|
||||
edges = np.array([sobel(img) for img in self.image.T]).T
|
||||
# truncate and stretch intensity range to enhance contrast
|
||||
self.edges = np.clip(self.edges, 0, 100)
|
||||
self.edges = rescale_intensity(self.edges)
|
||||
self.edges = rescale_intensity(edges, in_range=(0, 0.4))
|
||||
|
||||
|
||||
def _crop_image(self, img):
|
||||
def _crop_image(self, image):
|
||||
w = 2 * self.radius
|
||||
x, y = self.origin
|
||||
return img[y:y+w, x:x+w]
|
||||
|
||||
def get_canvas(self):
|
||||
return 255 * np.ones(self.img.shape, dtype=np.uint8)
|
||||
return image[y:y + w, x:x + w]
|
||||
|
||||
def plot_curve(self, **kwargs):
|
||||
self.logo.plot_snake_curve(**kwargs)
|
||||
@@ -104,15 +78,13 @@ class LogoBase(object):
|
||||
|
||||
class SnakeLogo(LogoBase):
|
||||
|
||||
def __init__(self):
|
||||
self.radius = 250
|
||||
self.origin = (420, 0)
|
||||
img = sio.imread('data/snake_pixabay.jpg')
|
||||
img = self._crop_image(img)
|
||||
radius = 250
|
||||
origin = (420, 0)
|
||||
|
||||
img = img.astype(float) * 1.1
|
||||
img[img > 255] = 255
|
||||
self.img = img.astype(np.uint8)
|
||||
def __init__(self):
|
||||
image = sio.imread('data/snake_pixabay.jpg')
|
||||
image = self._crop_image(image)
|
||||
self.image = img_as_float(image)
|
||||
|
||||
LogoBase.__init__(self)
|
||||
|
||||
@@ -120,107 +92,75 @@ class SnakeLogo(LogoBase):
|
||||
snake_color = SnakeLogo()
|
||||
snake = SnakeLogo()
|
||||
# turn RGB image into gray image
|
||||
snake.img = np.mean(snake.img, axis=2)
|
||||
snake.edges = np.mean(snake.edges, axis=2)
|
||||
snake.image = rgb2gray(snake.image)
|
||||
snake.edges = rgb2gray(snake.edges)
|
||||
|
||||
|
||||
# Demo plotting functions
|
||||
# =======================
|
||||
|
||||
def plot_colorized_logo(logo, color, edges='light', switch=False, whiten=False):
|
||||
"""Convenience function to plot artificially colored logo.
|
||||
def plot_colorized_logo(logo, color, edges='light', whiten=False):
|
||||
"""Convenience function to plot artificially-colored logo.
|
||||
|
||||
The upper-left half of the logo is an edge filtered image, while the
|
||||
lower-right half is unfiltered.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
logo : subclass of LogoBase
|
||||
color : length-3 sequence of floats
|
||||
logo : LogoBase instance
|
||||
color : length-3 sequence of floats or 2 length-3 sequences
|
||||
RGB color spec. Float values should be between 0 and 1.
|
||||
edges : {'light'|'dark'}
|
||||
Specifies whether Sobel edges are drawn light or dark
|
||||
switch : bool
|
||||
If False, the image is drawn on the southeast half of the Scipy curve
|
||||
and the edge image is drawn on northwest half.
|
||||
whiten : bool
|
||||
whiten : bool or 2 bools
|
||||
If True, a color value less than 1 increases the image intensity.
|
||||
"""
|
||||
if not hasattr(color[0], '__iter__'):
|
||||
color = [color] * 2
|
||||
color = [color] * 2 # use same color for upper-left & lower-right
|
||||
if not hasattr(whiten, '__iter__'):
|
||||
whiten = [whiten] * 2
|
||||
img = gray2rgb(logo.get_canvas())
|
||||
whiten = [whiten] * 2 # use same setting for upper-left & lower-right
|
||||
|
||||
image = gray2rgb(np.ones_like(logo.image))
|
||||
mask_img = gray2rgb(logo.mask_2)
|
||||
mask_edge = gray2rgb(logo.mask_1)
|
||||
if switch:
|
||||
mask_img, mask_edge = mask_edge, mask_img
|
||||
|
||||
# Compose image with colorized image and edge-image.
|
||||
if edges == 'dark':
|
||||
lg_edge = colorize(255 - logo.edges, color[0], whiten=whiten[0])
|
||||
logo_edge = colorize(1 - logo.edges, color[0], whiten=whiten[0])
|
||||
else:
|
||||
lg_edge = colorize(logo.edges, color[0], whiten=whiten[0])
|
||||
lg_img = colorize(logo.img, color[1], whiten=whiten[1])
|
||||
img[mask_img] = lg_img[mask_img]
|
||||
img[mask_edge] = lg_edge[mask_edge]
|
||||
logo.plot_curve(lw=5, color='w')
|
||||
plt.imshow(img)
|
||||
logo_edge = colorize(logo.edges, color[0], whiten=whiten[0])
|
||||
logo_img = colorize(logo.image, color[1], whiten=whiten[1])
|
||||
image[mask_img] = logo_img[mask_img]
|
||||
image[mask_edge] = logo_edge[mask_edge]
|
||||
|
||||
|
||||
def red_light_edges(logo, **kwargs):
|
||||
plot_colorized_logo(logo, (1, 0, 0), edges='light', **kwargs)
|
||||
|
||||
|
||||
def red_dark_edges(logo, **kwargs):
|
||||
plot_colorized_logo(logo, (1, 0, 0), edges='dark', **kwargs)
|
||||
|
||||
def blue_light_edges(logo, **kwargs):
|
||||
plot_colorized_logo(logo, (0.35, 0.55, 0.85), edges='light', **kwargs)
|
||||
|
||||
|
||||
def blue_dark_edges(logo, **kwargs):
|
||||
plot_colorized_logo(logo, (0.35, 0.55, 0.85), edges='dark', **kwargs)
|
||||
|
||||
|
||||
def green_orange_light_edges(logo, **kwargs):
|
||||
colors = ((0.6, 0.8, 0.3), (1, 0.5, 0.1))
|
||||
plot_colorized_logo(logo, colors, edges='light', **kwargs)
|
||||
|
||||
def green_orange_dark_edges(logo, **kwargs):
|
||||
colors = ((0.6, 0.8, 0.3), (1, 0.5, 0.1))
|
||||
plot_colorized_logo(logo, colors, edges='dark', **kwargs)
|
||||
logo.plot_curve(lw=5, color='w') # plot snake curve on current axes
|
||||
plt.imshow(image)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
import sys
|
||||
plot = False
|
||||
if len(sys.argv) < 2 or sys.argv[1] != '--no-plot':
|
||||
plot = True
|
||||
|
||||
print "Run with '--no-plot' flag to generate logo silently."
|
||||
# Colors to use for the logo:
|
||||
red = (1, 0, 0)
|
||||
blue = (0.35, 0.55, 0.85)
|
||||
green_orange = ((0.6, 0.8, 0.3), (1, 0.5, 0.1))
|
||||
|
||||
def plot_all():
|
||||
plotters = (red_light_edges, red_dark_edges,
|
||||
blue_light_edges, blue_dark_edges,
|
||||
green_orange_light_edges, green_orange_dark_edges)
|
||||
|
||||
f, axes_array = plt.subplots(nrows=2, ncols=len(plotters))
|
||||
for plot, ax_col in zip(plotters, axes_array.T):
|
||||
prepare_axes(ax_col[0])
|
||||
plot(snake)
|
||||
prepare_axes(ax_col[1])
|
||||
plot(snake, whiten=True)
|
||||
color_list = [red, blue, green_orange]
|
||||
edge_list = ['light', 'dark']
|
||||
f, axes = plt.subplots(nrows=len(edge_list), ncols=len(color_list))
|
||||
for axes_row, edges in zip(axes, edge_list):
|
||||
for ax, color in zip(axes_row, color_list):
|
||||
prepare_axes(ax)
|
||||
plot_colorized_logo(snake, color, edges=edges)
|
||||
plt.tight_layout()
|
||||
|
||||
def plot_snake():
|
||||
|
||||
def plot_official_logo():
|
||||
f, ax = plt.subplots()
|
||||
prepare_axes(ax)
|
||||
green_orange_dark_edges(snake, whiten=(False, True))
|
||||
plot_colorized_logo(snake, green_orange, edges='dark',
|
||||
whiten=(False, True))
|
||||
plt.savefig('green_orange_snake.png', bbox_inches='tight')
|
||||
|
||||
if plot:
|
||||
plot_all()
|
||||
|
||||
plot_snake()
|
||||
|
||||
if plot:
|
||||
plt.show()
|
||||
plot_all()
|
||||
plot_official_logo()
|
||||
|
||||
plt.show()
|
||||
|
||||
+6
-10
@@ -3,10 +3,11 @@ Code used to trace Scipy logo.
|
||||
"""
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import skimage.io as imgio
|
||||
from scipy.misc import lena
|
||||
import matplotlib.nxutils as nx
|
||||
|
||||
from skimage import io
|
||||
from skimage import data
|
||||
|
||||
|
||||
class SymmetricAnchorPoint(object):
|
||||
"""Anchor point in a parametric curve with symmetric handles
|
||||
@@ -185,7 +186,7 @@ class ScipyLogo(object):
|
||||
|
||||
def plot_image(self, **kwargs):
|
||||
ax = kwargs.pop('ax', plt.gca())
|
||||
img = imgio.imread('data/scipy.png')
|
||||
img = io.imread('data/scipy.png')
|
||||
ax.imshow(img, **kwargs)
|
||||
|
||||
def get_mask(self, shape, region):
|
||||
@@ -236,9 +237,7 @@ def plot_snake_overlay():
|
||||
logo = ScipyLogo((670, 250), 250)
|
||||
logo.plot_snake_curve()
|
||||
logo.plot_circle()
|
||||
img = imgio.imread('data/snake_pixabay.jpg')
|
||||
#mask = logo.get_mask(img.shape, 'upper left')
|
||||
#img[mask] = 255
|
||||
img = io.imread('data/snake_pixabay.jpg')
|
||||
plt.imshow(img)
|
||||
|
||||
|
||||
@@ -247,9 +246,7 @@ def plot_lena_overlay():
|
||||
logo = ScipyLogo((300, 300), 180)
|
||||
logo.plot_snake_curve()
|
||||
logo.plot_circle()
|
||||
img = lena()
|
||||
#mask = logo.get_mask(img.shape, 'upper left')
|
||||
#img[mask] = 255
|
||||
img = data.lena()
|
||||
plt.imshow(img)
|
||||
|
||||
|
||||
@@ -259,4 +256,3 @@ if __name__ == '__main__':
|
||||
plot_lena_overlay()
|
||||
|
||||
plt.show()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user