Interactive cropping with napari#
When cropping three-dimensional data it might make sense to do this interactively, e.g. using napari. For scripting convenience, we use a napari plugin, called napari-crop.
See also
import napari
from napari.utils import nbscreenshot
from skimage.io import imread
from magicgui import magicgui
# The following is a private function. The interface
# may be changed in the future. If you copy that code
# it breaks at some point, please come back to this
# notebook and check how to update your code.
from napari_crop._function import crop_region
We start by loading a dataset and showing it in napari.
# Start a napari viewer
viewer = napari.Viewer()
# open an image and store it in a layer
image_layer = viewer.open("../../data/Haase_MRT_tfl3d1.tif")
# select a center plane for viewing
viewer.dims.current_step = [100, 0, 0]
# show napari window as screenshot in the notebook
nbscreenshot(viewer)
C:\Users\rober\Anaconda3\envs\bio_39\lib\site-packages\napari\plugins\_plugin_manager.py:494: UserWarning: Plugin 'napari-accelerated-pixel-and-object-classification' provided a non-callable type to `napari_experimental_provide_function`: <class 'magicgui._magicgui.MagicFactory'>. Function widget ignored.
warn(message=warn_message)
Next, we put a circle shape in a new shapes layer into the viewer.
def make_circle(circle_center_x, circle_center_y, circle_radius):
"""Helper function to create circles"""
current_z_slice = viewer.dims.current_step[0]
return [[current_z_slice, circle_center_y - circle_radius, circle_center_x - circle_radius],
[current_z_slice, circle_center_y - circle_radius, circle_center_x + circle_radius],
[current_z_slice, circle_center_y + circle_radius, circle_center_x - circle_radius],
[current_z_slice, circle_center_y + circle_radius, circle_center_x + circle_radius]]
elipses = make_circle(80, 100, 50)
# add shapes to viewer
shapes_layer = viewer.add_shapes(elipses, shape_type='ellipse', edge_width=2)
nbscreenshot(viewer)
Next, we attach a graphical user-interface (GUI) for cropping a region.
# make a graphical user interface
crop_gui = magicgui(crop_region)
# attach it to the viewer window
viewer.window.add_dock_widget(crop_gui)
nbscreenshot(viewer)
After attaching the GUI, we can also click the Run
button and crop out a region like this:
crop_gui()
nbscreenshot(viewer)
We can also reposition the circle and crop again.
# reposition the selected circle
elipses = make_circle(120, 150, 50)
shapes_layer.data = elipses
# duplicate last cropped layer, because cropping again would overwrite it
viewer.add_image(viewer.layers[2].data)
# crop again
crop_gui()
# crop one more circle
shapes_layer.data = make_circle(170, 150, 50)
viewer.add_image(viewer.layers[2].data)
crop_gui()
nbscreenshot(viewer)
By the end, we remove the image and shapes layers and take a look at the crops side by side.
# Remove the first two layers
viewer.layers.remove(viewer.layers[0])
viewer.layers.remove(viewer.layers[0])
# toggle grid view
viewer.grid.enabled = True
viewer.grid.stride = 1
nbscreenshot(viewer)