📚 The CoCalc Library - books, templates and other resources
License: OTHER
Images are numpy arrays
Images are represented in scikit-image
using standard numpy
arrays. This allows maximum inter-operability with other libraries in the scientific Python ecosystem, such as matplotlib
and scipy
.
Let's see how to build a grayscale image as a 2D array:
The same holds for "real-world" images:
A color image is a 3D array, where the last dimension has size 3 and represents the red, green, and blue channels:
These are just numpy arrays. Making a red square is easy using just array slicing and manipulation:
Images can also include transparent regions by adding a 4th dimension, called an alpha layer.
Data types and image values
In literature, one finds different conventions for representing image values:
scikit-image
supports both conventions--the choice is determined by the data-type of the array.
E.g., here, I generate two valid images:
The library is designed in such a way that any data-type is allowed as input, as long as the range is correct (0-1 for floating point images, 0-255 for unsigned bytes, 0-65535 for unsigned 16-bit integers).
This is achieved through the use of a few utility functions, such as img_as_float
and img_as_ubyte
:
Your code would then typically look like this:
We recommend using the floating point representation, given that scikit-image
mostly uses that format internally.
Displaying images using matplotlib
Before we get started, a quick note about plotting images---specifically, plotting gray-scale images with Matplotlib. First, let's grab an example image from scikit-image
.
Also, we'll want to make sure we have numpy and matplotlib imported.
If we plot a gray-scale image using the old default colormap "jet" (it's been replaced by Viridis in Matplotlib >= 1.5), and a gray-scale colormap, "gray", you can easily see the difference:
We can get a better idea of the ill effects by zooming into the man's face.
Notice how the face looks distorted and splotchy with the "jet" colormap. Also, this colormap distorts the concepts of light and dark, and there are artificial boundaries created by the different color hues. Is that a beauty mark on the man's upper lip? No, it's just an artifact of this ridiculous colormap.
Here's another example:
Woah! See all those non-existing contours?
You can set both the method of interpolation and colormap used explicitly in the imshow
command:
Otherwise, you can add the following setting at the top of any script to change the default colormap:
Don't worry: color images are unaffected by this change.
In addition, we'll set the interpolation to 'nearest neighborhood' so that it's easier to distinguish individual pixels in your image (the default is 'bicubic'--see the exploration below).
For reference, let's look at the images above using Matplotlib's new 'viridis' and 'magma' colormaps (requires matplotlib >= 1.5).
Interactive demo: interpolation and color maps
If you are viewing this tutorial from inside a Jupyter notebook, the following code will display an interactive widget for exploring different colormaps and types of interpolation.
Image I/O
Mostly, we won't be using input images from the scikit-image example data sets. Those images are typically stored in JPEG or PNG format. Since scikit-image operates on NumPy arrays, any image reader library that provides arrays will do. Options include matplotlib, pillow, imageio, imread, etc.
scikit-image conveniently wraps many of these in the io
submodule, and will use whatever option is available:
We also have the ability to load multiple images, or multi-layer TIFF images:
Exercises
Draw the letter H
Define a function that takes as input an RGB image and a pair of coordinates (row, column), and returns the image (optionally a copy) with green letter H overlaid at those coordinates. The coordinates should point to the top-left corner of the H.
The arms and strut of the H should have a width of 3 pixels, and the H itself should have a height of 24 pixels and width of 20 pixels.
Start with the following template:
Test your function like so:
RGB intensity plot
Plot the intensity of each channel of the image along a given row. Start with the following template:
Test your function using: