tracking-3d¶
Feature finding in 3D confocal images¶
Confocal microscopy is a techique that is able to make image slices of your sample. New developments (spinning disk scanning, resonant mirrors) have made this technique sufficiently fast for 3D tracking. Commonly, the sample is mounted on a piezo stage that is able to quickly scan the sample in Z direction. In this way, sequences of Z pictures can be made. By repeating this, the sample can be followed real-time in 3D.
Because of the different techniques used for XY and Z resolution, pixel sizes in these directions are mostly not equal. It is easy to extend the method of Crocker & Grier to 3 dimensions with different feature sizes. Trackpy can do this from version v0.3; the only thing you need to do is load your images as 3 dimensional numpy arrays and supply a tuple value for diameter, describing feature size in each dimension.
First, we initalize IPython and load the required packages. PIMS and Trackpy v0.3 are required.
Setup IPython, pims, trackpy¶
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('figure', figsize=(10, 6))
import numpy as np
import pandas as pd
from pandas import DataFrame, Series # for convenience
import pims
import trackpy as tp
import warnings
warnings.filterwarnings("ignore", module="matplotlib")
Import 3D images¶
We make use of ImageSequenceND
. This reader class searches for files matching a certain search string. The filename should contain indentifiers for each axis (dimension). For example "demo_t001_z001.png"
contains identifiers t
and z
. We set the returned image axes to zyx
and the iterating axis to t
. In this way we get 3D images indexed by t
.
For this tutorial, the images are inside a zipfile. You can extract the images from the specified archive to check them out.
frames = pims.ImageSequenceND(r'../sample_data/pmma_colloids.zip', axes_identifiers = ['z', 't'])
frames.bundle_axes = ['z', 'y', 'x']
frames.iter_axes = 't'
frames
<ImageSequenceND> Source: /Users/charles/codes/trackpy-examples/sample_data/pmma_colloids.zip Axes: 4 Axis 'z' size: 25 Axis 't' size: 33 Axis 'y' size: 128 Axis 'x' size: 128 Pixel Datatype: uint8
The time-index of the first frame is always 0, regardless of the index in the filename. We can use pims
3d scrollable stack feature to display a 3D image. Use the scroll wheel to scroll through the focal planes.
This feature will not work online, download the example and run it yourself to checkout the scrollable stack feature.
frames[0]
Feature finding¶
Now we can use trackpy.locate
to generate a table (a pandas DataFrame
) of the feature coordinates. locate
only requires a feature diameter. This needs to be an odd integer and can be specified for each dimension seperately. The order of dimensions is the same as the order of the image array, typically (z, y, x).
features = tp.locate(frames[0], diameter=(5, 9, 9))
features.head() # displays first 5 rows
x | y | z | mass | size_x | size_y | size_z | ecc | signal | raw_mass | ep_x | ep_y | ep_z | frame | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 92.767466 | 9.071401 | 2.012498 | 7546.110185 | 2.860761 | 2.665710 | 1.405736 | NaN | 119.948425 | 11471.0 | 0.011464 | 0.011464 | 0.005139 | 0 |
1 | 54.699074 | 12.227642 | 1.913505 | 4283.319561 | 2.822252 | 2.610693 | 1.350248 | NaN | 77.386081 | 7476.0 | 0.017994 | 0.017994 | 0.008067 | 0 |
2 | 67.940818 | 36.920317 | 2.033795 | 6039.499928 | 2.930073 | 2.924657 | 1.355519 | NaN | 83.190037 | 9711.0 | 0.013646 | 0.013646 | 0.006117 | 0 |
3 | 4.873056 | 37.946693 | 1.959903 | 5162.618902 | 2.897005 | 2.790764 | 1.331927 | NaN | 81.739048 | 8632.0 | 0.015448 | 0.015448 | 0.006925 | 0 |
4 | 58.815615 | 80.025063 | 2.059816 | 5191.155019 | 2.814045 | 2.593217 | 1.386939 | NaN | 98.183590 | 7986.0 | 0.016774 | 0.016774 | 0.007520 | 0 |
Because we specified different diameters for each dimension, trackpy we return size
and ep
(static error) for each dimension seperately. We can plot the feature locations on top of the original picture. You can see that there are no features found at the edges. This is because these particles partly fall out of the measurement box.
tp.annotate3d(features, frames[0])