ImageStack

lumicks.pylake.ImageStack

class ImageStack(*image_names, align=True)

Open a TIF file acquired with Bluelake. Bluelake can export stacks of images from various cameras and these can be opened and correlated to timeline data.

Parameters:
  • *image_names (str) – Filenames for the image stack. Typically a TIFF file recorded from a camera in Bluelake.

  • align (bool) – If enabled, multi-channel images will be reconstructed from the image alignment metadata from Bluelake. The default value is True.

Examples

from lumicks import pylake

# Loading a stack.
stack = pylake.ImageStack("example.tiff")

# Making a plot where force is correlated to images in the stack.
file = pylake.File("example.h5")
stack.plot_correlated(file.force1x)

# Determine the force trace averaged over frame 2...9.
file.force1x.downsampled_over(stack[2:10].frame_timestamp_ranges())

# Loading multiple TIFFs into a stack.
stack = pylake.ImageStack("example.tiff", "example2.tiff", "example3.tiff")
__getitem__(item)

Returns specific frame(s) and/or cropped stacks.

The first item refers to the camera frames; both indexing (by integer) and slicing are allowed, but using steps or slicing by a list is not. The last two items refer to the spatial dimensions in pixel rows and columns. Only full slices (without steps) are allowed. All values should be given in pixels.

Examples

import lumicks.pylake as lk

stack = lk.ImageStack("test.tiff")

stack[5]  # Gets the 6th frame of the scan (0 is the first).
stack[1:5]  # Get scan frames 1, 2, 3 and 4.
stack[:, 10:50, 20:50]  # Gets all frames cropped from row 11 to 50 and column 21 to 50.
stack[:, 10:50]  # Gets all frames and all columns, but crops from row 11 to 50.
stack[5, 10:20, 10:20]  # Obtains the 6th frame and crops it.

stack[[1, 3, 4]]  # Produces an error, lists are not allowed.
stack[1:5:2]  # Produces an error, steps are not allowed.
stack[1, 3, 5]   # Error, integer indices are not allowed for the spatial dimensions.
stack[1, 3:5:2]  # Produces an error, steps are not allowed when slicing.

stack["1s":"5s"]  # Slice the stack from 1 to 5 seconds
stack[:"-5s"]  # Slice the stack up to the last 5 seconds
close()

Closes ImageStack file handle.

Note

Attempting to access image data after closing the file handle will result in an IOError for both this ImageStack and any ImageStack derived from it through e.g. ImageStack.crop_by_pixels() or ImageStack.define_tether()

crop_and_rotate(frame=0, channel='rgb', show_title=True, **kwargs)

Open a widget to interactively edit the image stack.

Actions:
  • mouse wheel – Scroll through frames of the stack.

  • left-click – Define the location of the tether. First click defines the start of the tether and second click defines the end. Subsequent clicks will cycle back to re-defining the start, etc.

  • right-click and drag – Define the ROI to be cropped.

Parameters:
  • frame (int, optional) – Index of the frame to plot.

  • channel ('rgb', 'red', 'green', 'blue', None; optional) – Channel to plot for RGB images (None defaults to ‘rgb’) Not used for grayscale images

  • show_title (bool, optional) – Controls display of auto-generated plot title

  • **kwargs – Forwarded to matplotlib.pyplot.imshow().

Return type:

ImageEditorWidget

Examples

from lumicks import pylake
import matplotlib.pyplot as plt

# Loading a stack.
stack = pylake.ImageStack("example.tiff")
widget = stack.crop_and_rotate()
plt.show()

# Select cropping ROI by right-click drag
# Select tether ends by left-click

# Grab the updated image stack
new_stack = widget.image
crop_by_pixels(x_min, x_max, y_min, y_max)

Crop the image stack by pixel values.

Parameters:
  • x_min (int) – minimum x pixel (inclusive, optional)

  • x_max (int) – maximum x pixel (exclusive, optional)

  • y_min (int) – minimum y pixel (inclusive, optional)

  • y_max (int) – maximum y pixel (exclusive, optional)

define_tether(point1, point2)

Returns a copy of the stack rotated such that the tether defined by point_1 and point_2 is horizontal.

Note that the tether position is given in the image units (microns).

Parameters:
  • point_1 ((float, float)) – (x, y) coordinates of the tether start point

  • point_2 ((float, float)) – (x, y) coordinates of the tether end point

export_tiff(file_name)

Export a video of a particular scan plot

Parameters:

file_name (str) – The name of the TIFF file where the image will be saved.

export_video(channel, file_name, *, start_frame=None, stop_frame=None, fps=15, adjustment=<lumicks.pylake.adjustments.ColorAdjustment object>, scale_bar=None, channel_slice=None, vertical=True, **kwargs)

Export a video

Parameters:
  • channel (str) – Color channel(s) to use “red”, “green”, “blue” or “rgb”.

  • file_name (str) – File name to export to.

  • start_frame (int) – First frame in exported video.

  • stop_frame (int) – Last frame in exported video.

  • fps (int) – Frame rate.

  • adjustment (lk.ColorAdjustment) – Color adjustments to apply to the output image.

  • scale_bar (lk.ScaleBar) – Scale bar to add to the figure.

  • channel_slice (lk.Slice, optional) – When specified, we export a video correlated to channel data

  • vertical (bool, optional) – Render with the plots vertically aligned (default: True).

  • **kwargs – Forwarded to matplotlib.pyplot.imshow().

Examples

import lumicks.pylake as lk

# Note that the examples are shown for an ImageStack, but the API for Scan stacks is
# identical.
imgs = lk.ImageStack("stack.tiff")
imgs.plot_correlated(f.force1x, frame=5, vertical=False)

# Perform a basic export of the full stack
imgs.export_video("rgb", "test.gif")

# Export the first 10 frames
imgs[:10].export_video("rgb", "test.gif")

# Export a cropped video (cropping from pixel 10 to 50 along each axis)
imgs[:, 10:50, 10:50].export_video("rgb", "test.gif")

# Export with a color adjustment using percentile based adjustment.
imgs.export_video(
    "rgb", "test.gif", adjustment=lk.ColorAdjustment(2, 98, mode="percentile"
)

# Export a gif at 50 fps
imgs.export_video("rgb", "test.gif", fps=50)

# We can also export with correlated channel data
h5_file = lk.File("stack.h5")

# Export video with correlated force data. A marker will indicate the frame.
imgs.export_video("rgb", "test.gif", channel_slice=h5_file.force1x)

# If you want the subplots side by side, pass the extra argument `vertical=False`.
imgs.export_video("rgb", "test.gif", channel_slice=h5_file.force1x, vertical=False)

# Export to a mp4 file, note that this needs ffmpeg to be installed. See:
# https://lumicks-pylake.readthedocs.io/en/latest/install.html#optional-dependencies
# for more information.
imgs.export_video("rgb", "test.mp4")
frame_timestamp_ranges(*, include_dead_time=False)

Get start and stop timestamp of each frame in the stack.

Parameters:

include_dead_time (bool) – Include dead time between frames.

classmethod from_dataset(data, name=None, start_idx=0, stop_idx=None, step=1) ImageStack

Construct ImageStack from image stack object

Parameters:
  • data (TiffStack) – TiffStack object.

  • name (str) – Plot label of the image stack

  • start_idx (int) – Index at the first frame.

  • stop_idx (int) – Index beyond the last frame.

  • step (int) – Step value for slicing frames.

get_image(channel='rgb')

Get image data for the full stack as an np.ndarray.

Parameters:

channel ({'red', 'green', 'blue', 'rgb'}) – The color channel of the requested data. For single-color data, this argument is ignored.

plot(channel='rgb', *, frame=0, adjustment=<lumicks.pylake.adjustments.ColorAdjustment object>, axes=None, image_handle=None, show_title=True, show_axes=True, scale_bar=None, **kwargs)

Plot a frame from the image stack for the requested color channel(s)

Parameters:
  • channel ({"red", "green", "blue", "rgb"}, optional) – Color channel to plot.

  • frame (int, optional) – Index of the frame to plot.

  • adjustment (lk.ColorAdjustment) – Color adjustments to apply to the output image.

  • axes (matplotlib.axes.Axes, optional) – If supplied, the axes instance in which to plot.

  • image_handle (matplotlib.image.AxesImage or None) – Optional image handle which is used to update plots with new data rather than reconstruct them (better for performance).

  • show_title (bool, optional) – Controls display of auto-generated plot title

  • show_axes (bool, optional) – Setting show_axes to False hides the axes.

  • scale_bar (lk.ScaleBar, optional) – Scale bar to add to the figure.

  • **kwargs – Forwarded to matplotlib.pyplot.imshow(). These arguments are ignored if image_handle is provided.

Returns:

The image handle representing the plotted image.

Return type:

matplotlib.image.AxesImage

plot_correlated(channel_slice, frame=0, reduce=<function mean>, channel='rgb', figure_scale=0.75, adjustment=<lumicks.pylake.adjustments.ColorAdjustment object>, *, vertical=False, include_dead_time=False, return_frame_setter=False)

Downsample channel on a frame by frame basis and plot the results. The downsampling function (e.g. np.mean) is evaluated for the time between a start and end time of a frame.

Actions:

left-click in the left axes – Show the corresponding image frame in the right axes.

Parameters:
  • channel_slice (pylake.channel.Slice) – Data slice that we with to downsample.

  • frame (int) – Frame to show.

  • reduce (callable) – The function which is going to reduce multiple samples into one. The default is np.mean, but np.sum could also be appropriate for some cases e.g. photon counts.

  • channel ('rgb', 'red', 'green', 'blue', None; optional) – Channel to plot for RGB images (None defaults to ‘rgb’) Not used for grayscale images

  • figure_scale (float) – Scaling of the figure width and height. Values greater than one increase the size of the figure.

  • adjustment (lk.ColorAdjustment) – Color adjustments to apply to the output image.

  • vertical (bool, optional) – Align plots vertically, default: False.

  • include_dead_time (bool, optional) – Include dead time between frames, default: False.

  • return_frame_setter (bool, optional) – Whether to return a handle that allows updating the plotted frame, default: False.

Note

In environments which support interactive figures (e.g. jupyter notebook with ipywidgets or interactive python) this plot will be interactive.

Examples

from lumicks import pylake

file = pylake.File("example.h5")
stack = pylake.ImageStack("example.tiff")
stack.plot_correlated(file.force1x, frame=5)
plot_tether(axes=None, **kwargs)

Plot a line at the tether position.

Parameters:
to_kymo(half_window, reduce=<function sum>) Kymo

Convert this ImageStack to a Kymo by sampling along the tether.

Parameters:
  • half_window (int) – Number of pixels adjacent to the tether on either side to average over. The kymograph will be calculated from the pixel values reduced to a one pixel line using the downsampling function provided in reduce().

  • reduce (callable) – The numpy function which is going to reduce multiple samples into one. The default is np.sum.

Return type:

Kymo

Raises:
  • ValueError – If the frame rate or exposure time are not constant.

  • ValueError – If the image stack does not have a tether defined.

  • ValueError – If the number of adjacent lines are negative.

  • ValueError – If the number of adjacent lines exceed the image dimensions.

Notes

In order to convert a ImageStack to a Kymo, a tether needs to be defined first. See the example below for more information.

Examples

import lumicks.pylake as lk
import matplotlib.pyplot as plt

stack = lk.ImageStack("camera_recording.tiff")

# Plot the stack
plt.figure()
stack.plot()

# Define tether by a pair of X, Y coordinates.
stack = stack.define_tether((7.19, 4.07), (22.74, 4.15))

# Plot the tether to verify.
stack.plot_tether()
kymo = stack.to_kymo(half_window=3)

# Plot the kymograph just created
plt.figure()
kymo.plot()

# Or alternatively, use the interactive widget to define the tether graphically
%matplotlib widget  # Enable interactive widgets
stack = lk.ImageStack("camera_recording.tiff")

# Opens an interactive widget. See help(lk.ImageStack.crop_and_rotate) for more info.
widget = stack.crop_and_rotate()
kymo = widget.image.to_kymo(half_window=3)
kymo.plot()
property num_frames

Number of frames in the stack.

property pixelsize_um: Optional[list]

Returns a list of pixel sizes along each axis in um. Returns None if calibration is unavailable.

property size_um: Optional[list]

Returns a list of axis sizes in um. Returns None if calibration is unavailable.

property start

Starting time stamp of the stack.

property stop

Final time stamp of the stack.