如何在3d numpy数组中计算凸包图像/体积

时间:2017-09-19 22:28:59

标签: python numpy scipy computational-geometry convex-hull

我想知道是否有任何基于numpy的工具可以:

  1. 在3D中给出二进制输入numpy图像,找到它的凸包;
  2. 并返回此3D凸包内的体素(3D像素)的索引或类似列表。
  3. 一种可能性是使用skimage.morphology.convex_hull_image(),但这仅支持2D图像,因此我必须逐片(在z轴上)调用此函数,这很慢。

    我绝对更喜欢更有效的方式。例如,scipy.spatial.ConvexHull()可以获取N维空间中的点列表,并返回一个凸起的船体对象,该对象似乎不支持找到其凸包图像/体积。

    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
    

    任何想法如何?请注意效率对我的申请很重要。 谢谢!

1 个答案:

答案 0 :(得分:1)

你应该可以这样做:

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])

无法上传图片,但它似乎可以解决问题。