From 70e37f305559536b5d2bc8b5fc775a074d6dec58 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Wed, 6 Mar 2013 23:03:01 -0600 Subject: [PATCH 1/2] Refactor code that generates scikit-image logo. Simplify code and use skimage functions that didn't exist when this code was originally written. --- doc/logo/scikit_image_logo.py | 210 ++++++++++++---------------------- doc/logo/scipy_logo.py | 16 +-- 2 files changed, 81 insertions(+), 145 deletions(-) diff --git a/doc/logo/scikit_image_logo.py b/doc/logo/scikit_image_logo.py index de460344..dab3f6bb 100644 --- a/doc/logo/scikit_image_logo.py +++ b/doc/logo/scikit_image_logo.py @@ -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 and lower-right if not hasattr(whiten, '__iter__'): - whiten = [whiten] * 2 - img = gray2rgb(logo.get_canvas()) + whiten = [whiten] * 2 # use same setting for upper-left and 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() diff --git a/doc/logo/scipy_logo.py b/doc/logo/scipy_logo.py index c9de053a..c57cd95b 100644 --- a/doc/logo/scipy_logo.py +++ b/doc/logo/scipy_logo.py @@ -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() - From ad0927f4592878e3317b9a6ec1ae03004d97c89f Mon Sep 17 00:00:00 2001 From: Stefan van der Walt Date: Thu, 7 Mar 2013 08:29:01 +0200 Subject: [PATCH 2/2] STY: PEP8 for logo. --- doc/logo/scikit_image_logo.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/logo/scikit_image_logo.py b/doc/logo/scikit_image_logo.py index dab3f6bb..fc8ec006 100644 --- a/doc/logo/scikit_image_logo.py +++ b/doc/logo/scikit_image_logo.py @@ -70,7 +70,7 @@ class LogoBase(object): def _crop_image(self, image): w = 2 * self.radius x, y = self.origin - return image[y:y+w, x:x+w] + return image[y:y + w, x:x + w] def plot_curve(self, **kwargs): self.logo.plot_snake_curve(**kwargs) @@ -116,9 +116,9 @@ def plot_colorized_logo(logo, color, edges='light', whiten=False): If True, a color value less than 1 increases the image intensity. """ if not hasattr(color[0], '__iter__'): - color = [color] * 2 # use same color for upper-left and lower-right + color = [color] * 2 # use same color for upper-left & lower-right if not hasattr(whiten, '__iter__'): - whiten = [whiten] * 2 # use same setting for upper-left and lower-right + whiten = [whiten] * 2 # use same setting for upper-left & lower-right image = gray2rgb(np.ones_like(logo.image)) mask_img = gray2rgb(logo.mask_2) @@ -133,7 +133,7 @@ def plot_colorized_logo(logo, color, edges='light', whiten=False): image[mask_img] = logo_img[mask_img] image[mask_edge] = logo_edge[mask_edge] - logo.plot_curve(lw=5, color='w') # plot snake curve on current axes + logo.plot_curve(lw=5, color='w') # plot snake curve on current axes plt.imshow(image)