Proposed enhancement
napari-crop can crop in nD based on 2D shapes. It would be a good new feature to cut in irregular 3D shapes with the user providing points/shapes representing polygons at different z-slices.
Example of the current behavior
The code below is an attempt to reproduce it in the current state.
import napari
from napari_crop._function import crop_region
from skimage.data import cells3d
import numpy as np
from magicgui import magicgui
viewer = napari.Viewer()
image = cells3d()
image = image[:,1]
polygon1 = np.array([[ 24., 141., 100.],
[ 24., 135., 115.],
[ 24., 142., 130.],
[ 24., 155., 134.],
[ 24., 167., 129.],
[ 24., 173., 117.],
[ 24., 163., 103.],
[ 24., 156., 95.]])
polygon2 = np.array([[ 33. , 136., 102.],
[ 33., 132., 115.7],
[ 33., 152., 135.],
[ 33., 165., 134.],
[ 33., 176., 122.],
[ 33., 180., 112.],
[ 33., 160., 89.],
[ 33., 140., 95.]])
polygon3 = np.array([[ 45., 146., 94.],
[ 45., 143., 109.],
[ 45., 156., 122.],
[ 45., 170., 126.],
[ 45., 179., 120.],
[ 45., 182., 108.],
[ 45., 177., 99.],
[ 45., 154., 89.]])
# This is how the shapes layer data would be if the user draw polygons along a z-stack
polygon_list = [polygon1, polygon2, polygon3]
# Transforms a list of polygons into a single 3D array of vertices
shapes = [polygon[np.newaxis,:] for polygon in polygon_list]
shape_3D = np.concatenate(shapes, axis=0)
viewer.add_image(image)
viewer.add_shapes(np.array(shape_3D), shape_type='polygon')
widget = magicgui(crop_region)
viewer.window.add_dock_widget(widget)
Two errors happen:
- If the number of vertices per slice is not the same, there is a
ValueError
because the polygons cannot be concatenated into a 3D array with the same shape.
- Even if the number of vertices match, it gives an interpolation error:
ValueError: 'linear' is not a valid Interpolation
From this, it seems the shapes layer may not be the best choice for that. Turning it into a surface and cropping it seems more appropriate. Suggestions and feedback welcome :)
enhancement