Lesson 38: Introduction to image processing with scikit-image


[1]:
import numpy as np
import pandas as pd

# Our image processing tools
import skimage.filters
import skimage.io
import skimage.morphology

import iqplot

import holoviews as hv
hv.extension('bokeh')

import panel as pn
pn.extension()

import bokeh.io
bokeh.io.output_notebook()
Loading BokehJS ...

In this tutorial, we will learn some basic techniques for image processing using `scikit-image <http://scikit-image.org>`__ with Python.

Image processing tools for Python

There are many image processing tools available for Python. Some of them, such as ITK and OpenCV are mature image processing packages that have bindings for Python, allowing easy use of their functionality. Others were developed specifically for Python. Some of the many packages are

The first two packages are standard with Anaconda. They provide a set of basic image processing tools, with more sophisticated packages such as ITK and Fiji supplying many more bells and whistles. If in the future you have more demanding image processing requirements, the other packages can prove very useful.

These days, there are lots of machine learning based packages for image segmentation, but few of these are mature packages at the moment. In future editions of the bootcamp, as these techniques and packages mature, we may use them.

We will almost exclusively use scikit-image along with the standard tools from NumPy. The package scipy.ndimage is quite useful, but we will use scikit-image, since it has expanded functionality. A potential annoyance with skimage is that the main package has minimal functionality, and you must import subpackages as needed. For example, to load and view images, you will need to import skimage.io. Importantly, skimage is well-documented, and you can access the documentation at http://scikit-image.org/.

We will explore skimage’s capabilities and some basic image processing techniques through example. In this lesson, we will take a brightfield and a fluorescent image of bacteria and perform segmentation, that is the identification of each pixel in the image as being bacterial or background.

Loading and viewing images

We will now load and view the test images we will use for segmentation. We load the image using the skimage.io.imread(). The image is stored as a NumPy array. Each entry in the array is a pixel value. This is an important point: a digital image is data! It is a set of numbers with spatial positions.

Today, we’ll be looking at some images of Bacillus subtilis, a gram-positive bacterium famous for its ability to enter a form of “suspended animation” known as sporulation when environmental conditions get rough. In these images, all cells have been engineered to express Cyan Fluorescent Protein (CFP) once they enter a particular genetic state known as competence. These cells have been imaged under phase contrast (bsub_100x_phase.tif) and epifluorescence (bsub_100x_cfp.tif) microscopy. These images were acquired by Caltech graduate student (and 2016 bootcamp TA) Griffin Chure.

Let’s go ahead and load an image.

[2]:
# Load the phase contrast image.
im_phase = skimage.io.imread('data/bsub_100x_phase.tif')

# Take a look
im_phase
[2]:
array([[398, 403, 418, ..., 381, 377, 373],
       [410, 400, 398, ..., 385, 372, 395],
       [394, 407, 421, ..., 376, 377, 378],
       ...,
       [371, 382, 380, ..., 389, 380, 370],
       [362, 368, 356, ..., 397, 383, 382],
       [372, 364, 372, ..., 385, 371, 378]], dtype=uint16)

We indeed have a NumPy array of integer values. To properly display images, we also need to specify the interpixel distance, the physical distance corresponding to neighboring pixels in an image. Interpixel distances are calibrated for an optical setup by various means. For this particular setup, the interpixel distance was 62.6 nm.

[3]:
# Store the interpixel distance in units of microns
ip_distance = 0.0626

Now that we have the image loaded, and know the interpixel distance, we would like to view it. Really, I should say “plot it” because, an image is data.

Viewing images with HoloViews

The Image element of HoloViews enables easy viewing of images.

[4]:
hv.Image(
    data=im_phase
)
[4]: