Ask a question about this section
Ask a question about this section

scikit-image: image processing in Python

View article
PeerJ
https://developers.google.com/open-source/soc (accessed 30 March 2014).
https://www.ohloh.net/p/scikit-image
http://pypi.python.org
https://store.continuum.io/cshop/anaconda
https://www.enthought.com/products/canopy
https://code.google.com/p/pythonxy
http://packages.ubuntu.com
http://pypi.python.org/pypi/scikit-image (accessed 30 March 2014).
http://pillow.readthedocs.org/en/latest/ (accessed 30 May 2015).
http://freeimage.sourceforge.net/ (accessed 15 May 2015).
http://scikit-image.org/docs/dev/api/api.html
https://github.com/scikit-image
https://groups.google.com/group/scikit-image
https://help.github.com/articles/using-pull-requests (accessed 15 May 2014).
https://travis-ci.org, https://coveralls.io (accessed 30 March 2014).
http://scikit-image.org/docs/dev (accessed 30 March 2014).
http://www.aicbt.com/disguise-detection (accessed 30 March 2014).
http://www.mathworks.com.au/products/distriben/description3.html (accessed 9 May 2014).
https://www.ohloh.net/p/scikit-image (accessed 15 May 2014).

Main article text

 

Introduction

  1. To provide high quality, well-documented and easy-to-use implementations of common image processing algorithms.

    Such algorithms are essential building blocks in many areas of scientific research, algorithmic comparisons and data exploration. In the context of reproducible science, it is important to be able to inspect any source code used for algorithmic flaws or mistakes. Additionally, scientific research often requires custom modification of standard algorithms, further emphasizing the importance of open source.

  2. To facilitate education in image processing.

    The library allows students in image processing to learn algorithms in a hands-on fashion by adjusting parameters and modifying code. In addition, a novice module is provided, not only for teaching programming in the “turtle graphics” paradigm, but also to familiarize users with image concepts such as color and dimensionality. Furthermore, the project takes part in the yearly Google Summer of Code program1, where students learn about image processing and software engineering through contributing to the project.

  3. To address industry challenges.

    High quality reference implementations of trusted algorithms provide industry with a reliable way of attacking problems without having to expend significant energy in re-implementing algorithms already available in commercial packages. Companies may use the library entirely free of charge, and have the option of contributing changes back, should they so wish.

Getting started

from skimage import data, io, filter

image = data.coins()  # or any NumPy array!
edges = filter.sobel(image)
io.imshow(edges)
import numpy as np
import matplotlib.pyplot as plt

# Load a small section of the image.
image = data.coins()[0:95, 70:370]

fig, axes = plt.subplots(ncols=2, nrows=3,
                         figsize=(8, 4))
ax0, ax1, ax2, ax3, ax4, ax5  = axes.flat
ax0.imshow(image, cmap=plt.cm.gray)
ax0.set_title('Original', fontsize=24)
ax0.axis('off')
# Histogram.
values, bins = np.histogram(image,
                            bins=np.arange(256))

ax1.plot(bins[:-1], values, lw=2, c='k')
ax1.set_xlim(xmax=256)
ax1.set_yticks([0, 400])
ax1.set_aspect(.2)
ax1.set_title('Histogram', fontsize=24)
# Apply threshold.
from skimage.filter import threshold_adaptive

bw = threshold_adaptive(image, 95, offset=-15)

ax2.imshow(bw, cmap=plt.cm.gray)
ax2.set_title('Adaptive threshold', fontsize=24)
ax2.axis('off')
# Find maxima.
from skimage.feature import peak_local_max

coordinates = peak_local_max(image, min_distance=20)

ax3.imshow(image, cmap=plt.cm.gray)
ax3.autoscale(False)
ax3.plot(coordinates[:, 1],
         coordinates[:, 0], c='r.')
ax3.set_title('Peak local maxima', fontsize=24)
ax3.axis('off')
# Detect edges.
from skimage import filter

edges = filter.canny(image, sigma=3,
                     low_threshold=10,
                     high_threshold=80)

ax4.imshow(edges, cmap=plt.cm.gray)
ax4.set_title('Edges', fontsize=24)
ax4.axis('off')
# Label image regions.
from skimage.measure import regionprops
import matplotlib.patches as mpatches
from skimage.morphology import label

label_image = label(edges)

ax5.imshow(image, cmap=plt.cm.gray)
ax5.set_title('Labeled items', fontsize=24)
ax5.axis('off')

for region in regionprops(label_image):
    # Draw rectangle around segmented coins.
    minr, minc, maxr, maxc = region.bbox
    rect = mpatches.Rectangle((minc, minr),
                              maxc - minc,
                              maxr - minr,
                              fill=False,
                              edgecolor='red',
                              linewidth=2)
    ax5.add_patch(rect)

plt.tight_layout()
plt.show()

Library overview

  • color: Color space conversion.

  • data: Test images and example data.

  • draw: Drawing primitives (lines, text, etc.) that operate on NumPy arrays.

  • exposure: Image intensity adjustment, e.g., histogram equalization, etc.

  • feature: Feature detection and extraction, e.g., texture analysis, corners, etc.

  • filter: Sharpening, edge finding, rank filters, thresholding, etc.

  • graph: Graph-theoretic operations, e.g., shortest paths.

  • io: Wraps various libraries for reading, saving, and displaying images and video, such as Pillow9 and FreeImage.10

  • measure: Measurement of image properties, e.g., similarity and contours.

  • morphology: Morphological operations, e.g., opening or skeletonization.

  • novice: Simplified interface for teaching purposes.

  • restoration: Restoration algorithms, e.g., deconvolution algorithms, denoising, etc.

  • segmentation: Partitioning an image into multiple regions.

  • transform: Geometric and other transforms, e.g., rotation or the Radon transform.

  • viewer: A simple graphical user interface for visualizing results and exploring parameters.

Data format and pipelining

Development practices

Usage examples

Research

Education

Industry

Example: image registration and stitching

This section gives a step-by-step outline of how to perform panorama stitching using the primitives found in scikit-image. The full source code is at https://github.com/scikit-image/scikit-image-demos.

Data loading

from skimage import io
ic = io.ImageCollection('data/*')
from skimage.color import rgb2gray
from skimage import transform

image0 = rgb2gray(ic[0][:, 500:500+1987, :])
image1 = rgb2gray(ic[1][:, 500:500+1987, :])

image0 = transform.rescale(image0, 0.25)
image1 = transform.rescale(image1, 0.25)

Feature detection and matching

from skimage.feature import ORB, match_descriptors

orb = ORB(n_keypoints=1000, fast_threshold=0.05)

orb.detect_and_extract(image0)
keypoints1 = orb.keypoints
descriptors1 = orb.descriptors

orb.detect_and_extract(image1)
keypoints2 = orb.keypoints
descriptors2 = orb.descriptors

matches12 = match_descriptors(descriptors1,
                              descriptors2,
                              cross_check=True)

Transform estimation

from skimage.measure import ransac

# Select keypoints from the source (image to be
# registered) and target (reference image).

src = keypoints2[matches12[:, 1]][:, ::-1]
dst = keypoints1[matches12[:, 0]][:, ::-1]

model_robust, inliers = \
    ransac((src, dst), ProjectiveTransform,
           min_samples=4, residual_threshold=2)

Warping

r, c = image1.shape[:2]

# Note that transformations take coordinates in
# (x, y) format, not (row, column), in order to be
# consistent with most literature.
corners = np.array([[0, 0],
                    [0, r],
                    [c, 0],
                    [c, r]])

# Warp the image corners to their new positions.
warped_corners = model_robust(corners)

# Find the extents of both the reference image and
# the warped target image.
all_corners = np.vstack((warped_corners, corners))

corner_min = np.min(all_corners, axis=0)
corner_max = np.max(all_corners, axis=0)

output_shape = (corner_max - corner_min)
output_shape = np.ceil(output_shape[::-1])
from skimage.color import gray2rgb
from skimage.exposure import rescale_intensity
from skimage.transform import warp
from skimage.transform import SimilarityTransform

offset = SimilarityTransform(translation=-corner_min)

image0_ = warp(image0, offset.inverse,
               output_shape=output_shape, cval=-1)

image1_ = warp(image1, (model_robust + offset).inverse,
               output_shape=output_shape, cval=-1)
def add_alpha(image, background=-1):
    """Add an alpha layer to the image.

    The alpha layer is set to 1 for foreground
    and 0 for background.
    """
    rgb = gray2rgb(image)
    alpha = (image != background)
    return np.dstack((rgb, alpha))

image0_alpha = add_alpha(image0_)
image1_alpha = add_alpha(image1_)

merged = (image0_alpha + image1_alpha)
alpha = merged[..., 3]

# The summed alpha layers give us an indication of
# how many images were combined to make up each
# pixel.  Divide by the number of images to get
# an average.
merged /= np.maximum(alpha, 1)[..., np.newaxis]

Blending

Discussion

Related work

Roadmap

  • Obtain full test coverage.

  • Overhaul the functions for image reading/writing.

  • Improve the project infrastructure, e.g., create an interactive gallery of examples.

  • Add support for graph-based operations.

  • Significantly extend higher dimensional (multi-layer) support.

Conclusion

Additional Information and Declarations

Competing Interests

Neil Yager is an employee of AICBT Ltd; Tony Yu is an employee of Enthought, Inc.

Author Contributions

Stéfan van der Walt, Johannes L. Schönberger, Juan Nunez-Iglesias, François Boulogne and Neil Yager conceived and designed the experiments, performed the experiments, wrote the paper, prepared figures and/or tables, reviewed drafts of the paper, wrote software.

Joshua D. Warner, Emmanuelle Gouillart and Tony Yu conceived and designed the experiments, performed the experiments, wrote the paper, reviewed drafts of the paper, wrote software.

Funding

Portions of the research reported in this publication were supported by the National Institute of Diabetes and Digestive and Kidney Diseases of the National Institutes of Health under award number F30DK098832. Portions of the research reported in this paper were supported by the Victorian Life Sciences Computation Initiative. The funders had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript.

 
Ask a question
4594 Citations 155,500 Views 34,025 Downloads

Your institution may have Open Access funds available for qualifying authors. See if you qualify

Publish for free

Comment on Articles or Preprints and we'll waive your author fee
Learn more

Five new journals in Chemistry

Free to publish • Peer-reviewed • From PeerJ
Find out more