使用napari进行交互式裁剪#
在裁剪三维数据时,交互式操作可能更有意义,例如使用napari。为了方便脚本编写,我们使用一个名为napari-crop的napari插件。
另请参阅
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
我们首先加载一个数据集并在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)
接下来,我们在查看器中的新形状层中放置一个圆形。
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)
接下来,我们附加一个用于裁剪区域的图形用户界面(GUI)。
# 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)
附加GUI后,我们还可以点击Run按钮,像这样裁剪出一个区域:
crop_gui()
nbscreenshot(viewer)
我们还可以重新定位圆形并再次裁剪。
# 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)
最后,我们移除图像和形状层,并并排查看裁剪结果。
# 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)