Exercise: image processing#

Duration ~35 min  ·  Session Day 1, Python notebooks

Correction of uneven illumination (vignetting) and cell segmentation with watershed.

Data: data/misc/cells_shaded.tif, and data/bbbc020/ fields 1h_1 and 15min_3.

import numpy as np
import tifffile
import matplotlib.pyplot as plt
import os; os.environ["DISPLAY"] = ":1"

from skimage.filters import threshold_otsu, gaussian
from skimage.measure import label
from skimage.color import label2rgb


from course import DATA, show

Task 1: Correcting for uneven illumination / vignetting#

Load data/misc/cells_shaded.tif and display it.

You should be able to see that the middle is brighter than the edges: this is vignetting, and it is a property of the optics, not the sample.

shaded = tifffile.imread(DATA / "misc" / "cells_shaded.tif").astype(float)
h, w = shaded.shape

show(shaded, title="cells_shaded.tif - bright in the middle")
plt.show()

Flatten the illumination#

In the walkthrough notebook, we removed a background by subtracting it. Let’s assume in this case that the vignetting is a multiplicative effect, and we want to flatten the illumination by dividing by an estimated illumination profile.

# --- your turn ---
illumination_profile = ...   # TODO: heavily blurred copy = the illumination field
flattened = ...    # TODO: divide, then rescale by background.mean()

fig, axes = plt.subplots(1, 3, figsize=(15, 4))
show(shaded, ax=axes[0])
show(illumination_profile, title="estimated illumination field", ax=axes[1])
show(flattened, ax=axes[2])
plt.show()

Segmenting the corrected image#

Segment the corrected image.

# --- your turn ---
labels = ...

Task 2: Separate remaining touching objects#

Use watershed segmentation to separate the remaining touching objects.

Hint: Use the function seeds_from_peaks from the walkthrough notebook as a starting point.

# --- your turn ---
binary_image = ...
connected_component_labels = ...
watershed_labels = ...