如何在 3d numpy 数组中计算凸包 image/volume
how to compute convex hull image/volume in 3d numpy arrays
我想知道是否有任何基于 numpy 的工具可以:
- 给定一个二进制输入的 3D numpy 图像,找到它的凸包;
- 和 return 此 3D 凸包内的体素(3D 像素)的索引或类似列表。
一种可能是使用skimage.morphology.convex_hull_image()
,但是这只支持2D图像,所以我必须逐个切片(在z轴上)调用这个函数,这很慢. [编辑:见下面的注释。]
我绝对更喜欢更高效的方式。例如,scipy.spatial.ConvexHull() 可以采用 N 维点列表 space,并且 return 一个似乎不支持找到其凸包 image/volume 的凸包对象。
points = np.transpose(np.where(image))
hull = scipy.spatial.ConvexHull(points)
# but now wonder an efficient way of finding the list of 3D voxels that are inside this convex hull
有什么想法吗?请注意效率对我的申请很重要。
谢谢!
更新:同时,convex_hull_image()
已经extended to support ND images, but it is quite slow for moderately sized data. The 快多了。
你应该可以做到这一点:
def flood_fill_hull(image):
points = np.transpose(np.where(image))
hull = scipy.spatial.ConvexHull(points)
deln = scipy.spatial.Delaunay(points[hull.vertices])
idx = np.stack(np.indices(image.shape), axis = -1)
out_idx = np.nonzero(deln.find_simplex(idx) + 1)
out_img = np.zeros(image.shape)
out_img[out_idx] = 1
return out_img, hull
它可能不是最快的,但缺少一个现成的功能它应该可以工作。
测试:
points = tuple(np.rint(10 * np.random.randn(3,100)).astype(int) + 50)
image = np.zeros((100,)*3)
image[points] = 1
%timeit flood_fill_hull(image)
10 loops, best of 3: 96.8 ms per loop
out, h = flood_fill_hull(image)
plot.imshow(out[50])
无法上传图片,但似乎可以解决问题。
我想知道是否有任何基于 numpy 的工具可以:
- 给定一个二进制输入的 3D numpy 图像,找到它的凸包;
- 和 return 此 3D 凸包内的体素(3D 像素)的索引或类似列表。
一种可能是使用skimage.morphology.convex_hull_image()
,但是这只支持2D图像,所以我必须逐个切片(在z轴上)调用这个函数,这很慢. [编辑:见下面的注释。]
我绝对更喜欢更高效的方式。例如,scipy.spatial.ConvexHull() 可以采用 N 维点列表 space,并且 return 一个似乎不支持找到其凸包 image/volume 的凸包对象。
points = np.transpose(np.where(image))
hull = scipy.spatial.ConvexHull(points)
# but now wonder an efficient way of finding the list of 3D voxels that are inside this convex hull
有什么想法吗?请注意效率对我的申请很重要。 谢谢!
更新:同时,convex_hull_image()
已经extended to support ND images, but it is quite slow for moderately sized data. The
你应该可以做到这一点:
def flood_fill_hull(image):
points = np.transpose(np.where(image))
hull = scipy.spatial.ConvexHull(points)
deln = scipy.spatial.Delaunay(points[hull.vertices])
idx = np.stack(np.indices(image.shape), axis = -1)
out_idx = np.nonzero(deln.find_simplex(idx) + 1)
out_img = np.zeros(image.shape)
out_img[out_idx] = 1
return out_img, hull
它可能不是最快的,但缺少一个现成的功能它应该可以工作。
测试:
points = tuple(np.rint(10 * np.random.randn(3,100)).astype(int) + 50)
image = np.zeros((100,)*3)
image[points] = 1
%timeit flood_fill_hull(image)
10 loops, best of 3: 96.8 ms per loop
out, h = flood_fill_hull(image)
plot.imshow(out[50])
无法上传图片,但似乎可以解决问题。