def test_both_algs_same_result_donut():
    # Performing this test on data that does not have ambiguities
    n = 48
    a, b = 2.5/n, -1.25

    vol = np.empty((n, n, n), 'float32')
    for iz in range(vol.shape[0]):
        for iy in range(vol.shape[1]):
            for ix in range(vol.shape[2]):
                # Double-torii formula by Thomas Lewiner
                z, y, x = float(iz)*a+b, float(iy)*a+b, float(ix)*a+b
                vol[iz,iy,ix] = ( ( 
                    (8*x)**2 + (8*y-2)**2 + (8*z)**2 + 16 - 1.85*1.85 ) * ( (8*x)**2 +
                    (8*y-2)**2 + (8*z)**2 + 16 - 1.85*1.85 ) - 64 * ( (8*x)**2 + (8*y-2)**2 )
                    ) * ( ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 )
                    * ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 ) -
                    64 * ( ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 
                    ) ) + 1025
    
    vertices1, faces1 = marching_cubes_classic(vol, 0)[:2]
    vertices2, faces2 = marching_cubes_lewiner(vol, 0)[:2]
    vertices3, faces3 = marching_cubes_lewiner(vol, 0, use_classic=True)[:2]
    
    # Old and new alg are different
    assert not _same_mesh(vertices1, faces1, vertices2, faces2)
    # New classic and new Lewiner are different
    assert not _same_mesh(vertices2, faces2, vertices3, faces3)
def main(select=3, **kwargs):
    """Script main function.

    select: int
        1: Medical data
        2: Blocky data, different every time
        3: Two donuts
        4: Ellipsoid

    """
    import visvis as vv  # noqa: delay import visvis and GUI libraries

    # Create test volume
    if select == 1:
        vol = vv.volread('stent')
        isovalue = kwargs.pop('level', 800)
    elif select == 2:
        vol = vv.aVolume(20, 128)
        isovalue = kwargs.pop('level', 0.2)
    elif select == 3:
        with timer('computing donuts'):
            vol = donuts()
        isovalue = kwargs.pop('level', 0.0)
        # Uncommenting the line below will yield different results for
        # classic MC
        # vol *= -1
    elif select == 4:
        vol = ellipsoid(4, 3, 2, levelset=True)
        isovalue = kwargs.pop('level', 0.0)
    else:
        raise ValueError('invalid selection')

    # Get surface meshes
    with timer('finding surface lewiner'):
        vertices1, faces1 = marching_cubes_lewiner(vol, isovalue, **kwargs)[:2]

    with timer('finding surface classic'):
        vertices2, faces2 = marching_cubes_classic(vol, isovalue, **kwargs)

    # Show
    vv.figure(1)
    vv.clf()
    a1 = vv.subplot(121)
    vv.title('Lewiner')
    m1 = vv.mesh(np.fliplr(vertices1), faces1)
    a2 = vv.subplot(122)
    vv.title('Classic')
    m2 = vv.mesh(np.fliplr(vertices2), faces2)
    a1.camera = a2.camera

    # visvis uses right-hand rule, gradient_direction param uses left-hand rule
    m1.cullFaces = m2.cullFaces = 'front'  # None, front or back

    vv.use().Run()
def test_both_algs_same_result_ellipse():
    # Performing this test on data that does not have ambiguities
    
    sphere_small = ellipsoid(1, 1, 1, levelset=True)
    
    vertices1, faces1 = marching_cubes_classic(sphere_small, 0)[:2]
    vertices2, faces2 = marching_cubes_lewiner(sphere_small, 0, allow_degenerate=False)[:2]
    vertices3, faces3 = marching_cubes_lewiner(sphere_small, 0, allow_degenerate=False, use_classic=True)[:2]
    
    # Order is different, best we can do is test equal shape and same vertices present
    assert _same_mesh(vertices1, faces1, vertices2, faces2)
    assert _same_mesh(vertices1, faces1, vertices3, faces3)
def test_marching_cubes_isotropic():
    ellipsoid_isotropic = ellipsoid(6, 10, 16, levelset=True)
    _, surf = ellipsoid_stats(6, 10, 16)
    
    # Classic
    verts, faces = marching_cubes_classic(ellipsoid_isotropic, 0.)
    surf_calc = mesh_surface_area(verts, faces)
    # Test within 1% tolerance for isotropic. Will always underestimate.
    assert surf > surf_calc and surf_calc > surf * 0.99
    
    # Lewiner
    verts, faces = marching_cubes_lewiner(ellipsoid_isotropic, 0.)[:2]
    surf_calc = mesh_surface_area(verts, faces)
    # Test within 1% tolerance for isotropic. Will always underestimate.
    assert surf > surf_calc and surf_calc > surf * 0.99
Exemple #5
0
def visualize_voxel_spectral(points, vis_size=128):
  """Function to visualize voxel (spectral)."""
  points = np.rint(points)
  points = np.swapaxes(points, 0, 2)
  fig = p.figure(figsize=(1, 1), dpi=vis_size)
  verts, faces = measure.marching_cubes_classic(points, 0, spacing=(0.1, 0.1, 0.1))
  ax = fig.add_subplot(111, projection='3d')
  ax.plot_trisurf(
      verts[:, 0], verts[:, 1], faces, verts[:, 2], cmap='Spectral_r', lw=0.1)
  ax.set_axis_off()
  fig.tight_layout(pad=0)
  fig.canvas.draw()
  data = np.fromstring(
      fig.canvas.tostring_rgb(), dtype=np.uint8, sep='').reshape(
          vis_size, vis_size, 3)
  p.close('all')
  return data
def test_marching_cubes_anisotropic():
    spacing = (1., 10 / 6., 16 / 6.)
    ellipsoid_anisotropic = ellipsoid(6, 10, 16, spacing=spacing,
                                      levelset=True)
    _, surf = ellipsoid_stats(6, 10, 16)
    
    # Classic
    verts, faces = marching_cubes_classic(ellipsoid_anisotropic, 0.,
                                          spacing=spacing)
    surf_calc = mesh_surface_area(verts, faces)
    # Test within 1.5% tolerance for anisotropic. Will always underestimate.
    assert surf > surf_calc and surf_calc > surf * 0.985
    
    # Lewiner
    verts, faces = marching_cubes_lewiner(ellipsoid_anisotropic, 0., spacing=spacing)[:2]
    surf_calc = mesh_surface_area(verts, faces)
    # Test within 1.5% tolerance for anisotropic. Will always underestimate.
    assert surf > surf_calc and surf_calc > surf * 0.985
def test_invalid_input():
    # Classic
    with testing.raises(ValueError):
        marching_cubes_classic(np.zeros((2, 2, 1)), 0)
    with testing.raises(ValueError):
        marching_cubes_classic(np.zeros((2, 2, 1)), 1)
    with testing.raises(ValueError):
        marching_cubes_classic(np.ones((3, 3, 3)), 1, spacing=(1, 2))
    with testing.raises(ValueError):
        marching_cubes_classic(np.zeros((20, 20)), 0)
    
    # Lewiner
    with testing.raises(ValueError):
        marching_cubes_lewiner(np.zeros((2, 2, 1)), 0)
    with testing.raises(ValueError):
        marching_cubes_lewiner(np.zeros((2, 2, 1)), 1)
    with testing.raises(ValueError):
        marching_cubes_lewiner(np.ones((3, 3, 3)), 1,
                               spacing=(1, 2))
    with testing.raises(ValueError):
        marching_cubes_lewiner(np.zeros((20, 20)), 0)
def plot_3d_lung(lung_array, title=''):
    print(title, lung_array.shape)

    start = time.time()
    imgs = lung_array.transpose(2, 1, 0)  # z,y,x -> x,y,z
    verts, faces = measure.marching_cubes_classic(imgs, 130)

    fig = plt.figure(figsize=(20, 20))
    ax = fig.add_subplot(111, projection='3d')
    mesh = Poly3DCollection(verts[faces], alpha=0.3)
    mesh.set_facecolor([1, 1, 1])

    ax.add_collection3d(mesh)
    ax.set_xlim(0, lung_array.shape[0])
    ax.set_ylim(0, lung_array.shape[1])
    ax.set_zlim(0, lung_array.shape[2])

    #ax.view_init(10,270) #旋转角度
    plt.rcParams['axes.facecolor'] = 'black'  #背景颜色
    plt.axis('off')

    plt.show()
    print('time cost:', time.time() - start)
def plot_3d(image, threshold=-300, id="1"):
    # Position the scan upright,
    # so the head of the patient would be at the top facing the camera
    p = image.transpose(2, 1, 0)
    #p = p[:,::-1,:]
    verts, faces = measure.marching_cubes_classic(p, threshold)

    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')

    # Fancy indexing: `verts[faces]` to generate a collection of triangles
    mesh = Poly3DCollection(verts[faces], alpha=0.70)
    face_color = [0.45, 0.45, 0.75]
    mesh.set_facecolor(face_color)
    ax.add_collection3d(mesh)

    ax.set_xlim(0, p.shape[0])
    ax.set_ylim(0, p.shape[1])
    ax.set_zlim(0, p.shape[2])

    fig = plt.gcf()
    plt.show()
    fig.savefig('./output/%s.png' % (id), dpi=100)
Exemple #10
0
    def f(X, c, q):
        vert_list = []

        for j in range(N):
            print 'step {%d}' % j
            X = f_(X, c, q)

            R = np.sqrt(np.square(X[:,:,:,0]) + \
                        np.square(X[:,:,:,1]) + \
                        np.square(X[:,:,:,2]))

            B = 1.0 * (R < 2.0)

            verts, faces = measure.marching_cubes_classic(B, 0)

            for k in range(3):
                verts[:, k] = (bounds[k][1] - bounds[k][0]) * (
                    1.0 * verts[:, k]) / K + bounds[k][0]

            faces = measure.correct_mesh_orientation(B, verts, faces)

            vert_list.append(verts)

        return vert_list
def test_marching_cubes_anisotropic():
    spacing = (1., 10 / 6., 16 / 6.)
    ellipsoid_anisotropic = ellipsoid(6,
                                      10,
                                      16,
                                      spacing=spacing,
                                      levelset=True)
    _, surf = ellipsoid_stats(6, 10, 16)

    # Classic
    verts, faces = marching_cubes_classic(ellipsoid_anisotropic,
                                          0.,
                                          spacing=spacing)
    surf_calc = mesh_surface_area(verts, faces)
    # Test within 1.5% tolerance for anisotropic. Will always underestimate.
    assert surf > surf_calc and surf_calc > surf * 0.985

    # Lewiner
    verts, faces = marching_cubes_lewiner(ellipsoid_anisotropic,
                                          0.,
                                          spacing=spacing)[:2]
    surf_calc = mesh_surface_area(verts, faces)
    # Test within 1.5% tolerance for anisotropic. Will always underestimate.
    assert surf > surf_calc and surf_calc > surf * 0.985
def test_marching_cubes_anisotropic():
    # test spacing as numpy array (and not just tuple)
    spacing = np.array([1., 10 / 6., 16 / 6.])
    ellipsoid_anisotropic = ellipsoid(6, 10, 16, spacing=spacing,
                                      levelset=True)
    _, surf = ellipsoid_stats(6, 10, 16)
    
    # Classic
    verts, faces = marching_cubes_classic(ellipsoid_anisotropic, 0.,
                                          spacing=spacing)
    surf_calc = mesh_surface_area(verts, faces)
    # Test within 1.5% tolerance for anisotropic. Will always underestimate.
    assert surf > surf_calc and surf_calc > surf * 0.985
    
    # Lewiner
    verts, faces = marching_cubes_lewiner(
        ellipsoid_anisotropic, 0., spacing=spacing)[:2]
    surf_calc = mesh_surface_area(verts, faces)
    # Test within 1.5% tolerance for anisotropic. Will always underestimate.
    assert surf > surf_calc and surf_calc > surf * 0.985

    # Test spacing together with allow_degenerate=False
    marching_cubes_lewiner(ellipsoid_anisotropic, 0, spacing=spacing,
                           allow_degenerate=False)
def test_both_algs_same_result_donut():
    # Performing this test on data that does not have ambiguities

    n = 48
    a, b = 2.5 / n, -1.25
    isovalue = 0.0

    vol = np.empty((n, n, n), 'float32')
    for iz in range(vol.shape[0]):
        for iy in range(vol.shape[1]):
            for ix in range(vol.shape[2]):
                # Double-torii formula by Thomas Lewiner
                z, y, x = float(iz) * a + b, float(iy) * a + b, float(
                    ix) * a + b
                vol[iz, iy, ix] = (((8 * x)**2 + (8 * y - 2)**2 +
                                    (8 * z)**2 + 16 - 1.85 * 1.85) *
                                   ((8 * x)**2 + (8 * y - 2)**2 +
                                    (8 * z)**2 + 16 - 1.85 * 1.85) - 64 *
                                   ((8 * x)**2 + (8 * y - 2)**2)) * (
                                       ((8 * x)**2 + ((8 * y - 2) + 4) *
                                        ((8 * y - 2) + 4) +
                                        (8 * z)**2 + 16 - 1.85 * 1.85) *
                                       ((8 * x)**2 + ((8 * y - 2) + 4) *
                                        ((8 * y - 2) + 4) +
                                        (8 * z)**2 + 16 - 1.85 * 1.85) - 64 *
                                       (((8 * y - 2) + 4) * ((8 * y - 2) + 4) +
                                        (8 * z)**2)) + 1025

    vertices1, faces1 = marching_cubes_classic(vol, 0)[:2]
    vertices2, faces2 = marching_cubes_lewiner(vol, 0)[:2]
    vertices3, faces3 = marching_cubes_lewiner(vol, 0, use_classic=True)[:2]

    # Old and new alg are different
    assert not _same_mesh(vertices1, faces1, vertices2, faces2)
    # New classic and new Lewiner are different
    assert not _same_mesh(vertices2, faces2, vertices3, faces3)
Exemple #14
0
def build_surface(grain):
    verts, faces = measure.marching_cubes_classic(grain, 0, spacing=(1, 1, 1))
    return verts, faces
def getVFByMarchingCubes(voxels, threshold=0.5):
    """Voxel 로 부터 Vertices, faces 리턴 하는 함수"""
    v, f = sk.marching_cubes_classic(voxels, level=threshold)
    return v, f
Exemple #16
0
def getVFByMarchingCubes(voxels, threshold=0.5):
    # v, f =  sk.marching_cubes(voxels, level=threshold)
    # v, f,_,_ =  sk.marching_cubes_lewiner(voxels,threshold)
    v, f = sk.marching_cubes_classic(voxels, threshold)
    return v, f
Exemple #17
0
 def measure(self, p, threshold, q1, q2):
     verts, faces = measure.marching_cubes_classic(p, threshold)
     q1.put(verts)
     q2.put(faces)
Exemple #18
0
                    ) * ( ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 )
                    * ( (8*x)**2 + ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2 + 16 - 1.85*1.85 ) -
                    64 * ( ((8*y-2)+4)*((8*y-2)+4) + (8*z)**2
                    ) ) + 1025
    # Uncommenting the line below will yield different results for classic MC
    #vol = -vol

elif SELECT == 4:
    vol = ellipsoid(4, 3, 2, levelset=True)
    isovalue = 0

# Get surface meshes
t0 = time.time()
vertices1, faces1, _ = marching_cubes_lewiner(vol, isovalue, gradient_direction=gradient_dir, use_classic=False)
print('finding surface lewiner took %1.0f ms' % (1000*(time.time()-t0)) )

t0 = time.time()
vertices2, faces2, _ = marching_cubes_classic(vol, isovalue, gradient_direction=gradient_dir)
print('finding surface classic took %1.0f ms' % (1000*(time.time()-t0)) )

# Show
vv.figure(1); vv.clf()
a1 = vv.subplot(121); m1 = vv.mesh(np.fliplr(vertices1), faces1)
a2 = vv.subplot(122); m2 = vv.mesh(np.fliplr(vertices2), faces2)
a1.camera = a2.camera

# visvis uses right-hand rule, gradient_direction param uses left-hand rule
m1.cullFaces = m2.cullFaces = 'front'  # None, front or back

vv.use().Run()
Exemple #19
0
def mandelbulb(K=200, p=8.0, N=10, extreme=1.5, optimize=False):
    M = T.ftensor4()
    C = T.ftensor4()
    n = T.fscalar()

    def step(X):
        r = T.sqrt(
            T.square(X[:, :, :, 0]) + T.square(X[:, :, :, 1]) +
            T.square(X[:, :, :, 2]))
        phi = T.arctan2(X[:, :, :, 1], X[:, :, :, 0])
        theta = T.arctan2(
            T.sqrt(T.square(X[:, :, :, 0]) + T.square(X[:, :, :, 1])),
            X[:, :, :, 2])

        X_ = T.stack((T.pow(r, n) * T.sin(n * theta) * T.cos(n * phi),
                      T.pow(r, n) * T.sin(n * theta) * T.sin(n * theta),
                      T.pow(r, n) * T.cos(n * theta)),
                     axis=-1)

        return X_ + C

    if optimize:
        result, _ = theano.scan(fn=step, outputs_info=M, n_steps=N)

        f = theano.function([M, C, n], result, allow_input_downcast=True)
    else:
        f_ = theano.function([M, C, n], step(M), allow_input_downcast=True)

        def f(X, c, q):
            for j in range(N):
                print 'step {%d}' % j
                X = f_(X, c, q)
            return np.array(X)

    x, y, z = np.meshgrid(np.linspace(-extreme, extreme, K),
                          np.linspace(-extreme, extreme, K),
                          np.linspace(-extreme, extreme, K))

    X = np.stack((x, y, z), axis=-1)

    if optimize:
        x_n = f(np.zeros((K, K, K, 3)), X, p)[-1]
    else:
        x_n = f(np.zeros((K, K, K, 3)), X, p)

    r_n = np.sqrt(np.square(x_n[:,:,:,0]) + \
                  np.square(x_n[:,:,:,1]) + \
                  np.square(x_n[:,:,:,2]))

    b_ = 1.0 * (r_n < 2.0)

    import open3d
    from scipy.misc import imresize
    from skimage import measure

    verts, faces = measure.marching_cubes_classic(b_, 0)
    faces = measure.correct_mesh_orientation(b_, verts, faces)
    verts = 2.0 * extreme * (np.array(verts, dtype=np.float32) / K) - extreme

    pcd = open3d.PointCloud()
    pcd.points = open3d.Vector3dVector(verts)
    open3d.estimate_normals(pcd,
                            search_param=open3d.KDTreeSearchParamHybrid(
                                radius=0.1, max_nn=30))

    global i, images
    i = 0
    images = []

    def custom_draw_geometry_with_rotation(pcd):
        def rotate_view(vis):
            ctr = vis.get_view_control()
            ctr.rotate(10.0, 0.0)

            global i, images
            i += 1
            print i % 210, i // 210

            image = np.asarray(vis.capture_screen_float_buffer())
            image = np.array(255 * image, dtype=np.uint8)
            image = imresize(image, 0.25)

            if (i // 210 == 0):
                images.append(image)

            return False

        open3d.draw_geometries_with_animation_callback([pcd], rotate_view)

    custom_draw_geometry_with_rotation(pcd)

    gif_name = 'Mandelbulb_%d_%d.gif' % (int(p), int(N))
    output_file = os.path.join(__file__.split('.')[0], gif_name)
    imageio.mimsave(output_file, images, duration=0.05)
Exemple #20
0









 
   
    
#   plotting in plotly if set true      
if to_plotly:
    verts, simplices = measure.marching_cubes_classic(vspace, np.amax(vspace)*q_threshold)
    x,y,z = zip(*verts)
    #colormap=['rgb(255,105,180)','rgb(255,255,51)','rgb(0,191,255)']
    fig = plotly.figure_factory.create_trisurf(x=x, y=y, z=z, plot_edges=False,
                        #colormap=colormap,
                        simplices=simplices,
                        title="Vortex field")
    py.iplot(fig)
#   plotting in matplotlib if set true 
if to_matplot:
    stop1 = time.clock()        
    verts, faces = measure.marching_cubes_classic(vspace, np.amax(vspace)*q_threshold)
    stop2 = time.clock()   
    print ('\n',int((stop2-stop1)*10000)/10000.,'sec  marching cubes')

    fig = plt.figure()
Exemple #21
0
def plot_3d(image=None,
            body=None,
            roi=None,
            gt=None,
            pred=None,
            threshold_i=1500,
            threshold_b=0,
            threshold_r=0):
    # Position the scan upright,
    # so the head of the patient would be at the top facing the camera
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')
    g, y = [], []
    if image is not None:
        g = np.zeros(image.shape, dtype=np.uint8)
        y = np.zeros(image.shape, dtype=np.uint8)
        p = image
        p = p[:, :, ::-1]
        verts_p, faces_p = measure.marching_cubes_classic(p, threshold_i)
        # Fancy indexing: `verts[faces]` to generate a collection of triangles
        mesh_p = Poly3DCollection(verts_p[faces_p], alpha=0.1)
        mesh_p.set_facecolor([0.0, 0.0, 0.0])
        ax.add_collection3d(mesh_p)

        ax.set_xlim(0, p.shape[0])
        ax.set_ylim(0, p.shape[1])
        ax.set_zlim(0, p.shape[2])

    if body is not None:
        g = np.zeros(body.shape, dtype=np.uint8)
        y = np.zeros(body.shape, dtype=np.uint8)
        b = body
        b = b[:, :, ::-1]
        verts_b, faces_b = measure.marching_cubes_classic(b, threshold_b)
        # Fancy indexing: `verts[faces]` to generate a collection of triangles
        mesh_b = Poly3DCollection(verts_b[faces_b], alpha=0.1)
        mesh_b.set_facecolor([0.5, 0.5, 1])
        ax.add_collection3d(mesh_b)

        ax.set_xlim(0, b.shape[0])
        ax.set_ylim(0, b.shape[1])
        ax.set_zlim(0, b.shape[2])

    if roi is not None:
        g = np.zeros(roi.shape, dtype=np.uint8)
        y = np.zeros(roi.shape, dtype=np.uint8)
        r = roi
        r = r[:, :, ::-1]
        verts_r, faces_r = measure.marching_cubes_classic(r, threshold_r)
        # Fancy indexing: `verts[faces]` to generate a collection of triangles
        mesh_r = Poly3DCollection(verts_r[faces_r], alpha=0.1)
        mesh_r.set_facecolor([0.5, 0.5, 0])
        ax.add_collection3d(mesh_r)

        ax.set_xlim(0, r.shape[0])
        ax.set_ylim(0, r.shape[1])
        ax.set_zlim(0, r.shape[2])

    if gt is not None:
        gt = np.round(gt).astype(np.int16)
        gt[2] = g.shape[2] - gt[2]
        g[gt[0], gt[1], gt[2]] = 1
        verts_g, faces_g = measure.marching_cubes_classic(g, 0)
        # Fancy indexing: `verts[faces]` to generate a collection of triangles
        mesh_g = Poly3DCollection(verts_g[faces_g], alpha=0.1)
        mesh_g.set_facecolor([0, 1, 0])
        ax.add_collection3d(mesh_g)

        ax.set_xlim(0, g.shape[0])
        ax.set_ylim(0, g.shape[1])
        ax.set_zlim(0, g.shape[2])

    if pred is not None:
        pred = np.round(pred).astype(np.int16)
        pred[2] = y.shape[2] - pred[2]
        y[pred[0], pred[1], pred[2]] = 1
        verts_y, faces_y = measure.marching_cubes_classic(y, 0)
        # Fancy indexing: `verts[faces]` to generate a collection of triangles
        mesh_y = Poly3DCollection(verts_y[faces_y], alpha=0.1)
        mesh_y.set_facecolor([1, 0, 0])
        ax.add_collection3d(mesh_y)

        ax.set_xlim(0, y.shape[0])
        ax.set_ylim(0, y.shape[1])
        ax.set_zlim(0, y.shape[2])

    plt.show()
Exemple #22
0
def get_surface(mask, spacing):
    vertices, faces = marching_cubes_classic(mask, level=0, spacing=spacing)
    faces = correct_mesh_orientation(mask, vertices, faces, spacing)
    return vertices, faces
Exemple #23
0
    def plot(self):
        """
        Plot the contours.
        """

        import bpy
        import numpy as np
        from skimage import measure
        from blendaviz import colors

        # Check if there is any time array.
        if not self.time is None:
            if not isinstance(self.time, np.ndarray):
                print("Error: time is not a valid array.")
                return -1
            elif self.time.ndim != 1:
                print("Error: time array must be 1d.")
                return -1
            # Determine the time index.
            self.time_index = np.argmin(
                abs(bpy.context.scene.frame_float - self.time))
        else:
            self.time = np.array([0])
            self.time_index = 0

        # Check the validity of the input arrays.
        if not isinstance(self.x, np.ndarray) or not isinstance(self.y, np.ndarray) \
           or not isinstance(self.z, np.ndarray):
            print("Error: x OR y OR z array invalid.")
            return -1
        if not ((self.x.shape[0], self.y.shape[0], self.z.shape[0])
                == self.phi.shape[:3]):
            print("Error: input array shapes invalid.")
            return -1
        if not self.psi is None:
            if not isinstance(self.psi, np.ndarray):
                print("Error: psi is not a numpy array.")
                return -1
            if not self.psi.shape[:3] == self.phi.shape[:3]:
                print("Error: psi and phi must of of the same shape.")

        # Point the local variables to the correct arrays.
        if self.x.ndim == 2:
            self._x = self.x[:, self.time_index]
        else:
            self._x = self.x
        if self.y.ndim == 2:
            self._y = self.y[:, self.time_index]
        else:
            self._y = self.y
        if self.z.ndim == 2:
            self._z = self.z[:, self.time_index]
        else:
            self._z = self.z
        if self.phi.ndim == 4:
            self._phi = self.phi[:, :, :, self.time_index]
        else:
            self._phi = self.phi
        if not self.psi is None:
            if self.psi.ndim == 4:
                self._psi = self.psi[:, :, :, self.time_index]
            else:
                self._psi = self.psi
        else:
            self._psi = None

        # Prepare the isosurface levels.
        if isinstance(self.contours, int):
            level_list = np.linspace(self._phi.min(), self._phi.max(),
                                     self.contours + 2)[1:-1]
        elif isinstance(self.contours, list):
            level_list = np.array(self.contours)
        elif isinstance(self.contours, np.ndarray):
            level_list = self.contours.ravel()
        else:
            print("Error: countours invalid. \
                  Must be either integer or 1d array/list.")
            return -1

        # Prepare the material colors.
        color_rgba = colors.make_rgba_array(self.color, level_list.shape[0],
                                            self.color_map, self.vmin,
                                            self.vmax)

        # Determine the grid spacing.
        dx = np.partition(np.array(list(set(list(self._x.ravel())))), 1)[1] - \
             self._x.min()
        dy = np.partition(np.array(list(set(list(self._y.ravel())))), 1)[1] - \
             self._y.min()
        dz = np.partition(np.array(list(set(list(self._z.ravel())))), 1)[1] - \
             self._z.min()

        # Delete existing meshes.
        if not self.mesh_object is None:
            bpy.ops.object.select_all(action='DESELECT')
            for mesh_object in self.mesh_object:
                mesh_object.select_set(state=True)
                bpy.ops.object.delete()
            self.mesh_object = None

        # Delete existing materials.
        if not self.mesh_material is None:
            for mesh_material in self.mesh_material:
                bpy.data.materials.remove(mesh_material)

        # Prepare the lists of mashes and materials.
        self.mesh_data = []
        self.mesh_object = []
        self.mesh_material = []

        for idx, level in enumerate(level_list):
            # Find the vertices and faces of the isosurfaces.
            vertices, faces = measure.marching_cubes_classic(self._phi,
                                                             level,
                                                             spacing=(dx, dy,
                                                                      dz))
            vertices[:, 0] += self._x.min()
            vertices[:, 1] += self._y.min()
            vertices[:, 2] += self._z.min()

            # Create mesh and object.
            self.mesh_data.append(bpy.data.meshes.new("DataMesh"))
            self.mesh_object.append(
                bpy.data.objects.new("ObjMesh", self.mesh_data[-1]))

            # Create mesh from the given data.
            self.mesh_data[-1].from_pydata(list(vertices), [], list(faces))
            self.mesh_data[-1].update(calc_edges=True)

            # Set the material/color.
            if self._psi is None:
                self.__set_material(idx, color_rgba, len(level_list))
            else:
                self.__color_vertices(idx, vertices)
            self.mesh_data[-1].materials.append(self.mesh_material[-1])

            # Link the mesh object with the scene.
            bpy.context.scene.collection.objects.link(self.mesh_object[-1])

        # Group the meshes together.
        for mesh in self.mesh_object[::-1]:
            mesh.select_set(state=True)
            bpy.context.view_layer.objects.active = mesh
        bpy.ops.object.join()
        self.mesh_object = bpy.context.object
        self.mesh_object.select_set(state=False)

        # Make the grouped meshes the deletable object.
        self.deletable_object = self.mesh_object

        return 0
Exemple #24
0
    # Uncommenting the line below will yield different results for classic MC
    #vol = -vol

elif SELECT == 4:
    vol = ellipsoid(4, 3, 2, levelset=True)
    isovalue = 0

# Get surface meshes
t0 = time.time()
vertices1, faces1, _, _ = marching_cubes_lewiner(
    vol, isovalue, gradient_direction=gradient_dir, use_classic=False)
print('finding surface lewiner took %1.0f ms' % (1000 * (time.time() - t0)))

t0 = time.time()
vertices2, faces2 = marching_cubes_classic(vol,
                                           isovalue,
                                           gradient_direction=gradient_dir)
print('finding surface classic took %1.0f ms' % (1000 * (time.time() - t0)))

# Show
vv.figure(1)
vv.clf()
a1 = vv.subplot(121)
m1 = vv.mesh(np.fliplr(vertices1), faces1)
a2 = vv.subplot(122)
m2 = vv.mesh(np.fliplr(vertices2), faces2)
a1.camera = a2.camera

# visvis uses right-hand rule, gradient_direction param uses left-hand rule
m1.cullFaces = m2.cullFaces = 'front'  # None, front or back
Exemple #25
0
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
from skimage import measure

n = 10
x = np.linspace(0, n, n + 1)

X, Y, Z = np.meshgrid(x, x, x, indexing='ij')


def f(x, y, z):
    return (x**2 + y**2 + z**2)**0.5 - 3


verts, faces = measure.marching_cubes_classic(f(X, Y, Z), 5)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

mesh = Poly3DCollection(verts[faces])
ax.add_collection3d(mesh)

m = 00

ax.set_xlim(-m, n + 5)
ax.set_ylim(-m, n + 5)
ax.set_zlim(-m, n + 5)

plt.show()
Exemple #26
0
def draw_3d_labels(
        in_bone_labels,  # type: np.ndarray
        start_idx=1,  # type: int
        rescale_func=None,
        vox_size=None,
        verbose=False,
        level=0,
        figsize=(10, 12),
        force_shape=True,
        flip=True):
    # type: (...) -> Tuple[Axes3D, matplotlib.figure.Figure]
    # somehow add type to rescale_fun Optional[Function(np.ndarray, np.ndarray)]
    """

    :param in_bone_labels:
    :param start_idx:
    :param rescale_func: a function to downscale the images (if needed)
    :return:
    >>> test_labels = np.stack([np.eye(3),2*np.eye(3)]).astype(int); tvx = np.array([0.1, 3.0, 0.33])
    >>> ax, fig = draw_3d_labels(test_labels, verbose = True)
    Adding meshes 1, sized 3.0
    Adding meshes 2, sized 3.0
    >>> type(ax)
    <class 'matplotlib.axes._subplots.Axes3DSubplot'>
    >>> type(fig)
    <class 'matplotlib.figure.Figure'>
    """
    # todo I don't think the Function typing is correct

    # plt.rcParams['savefig.bbox'] = 'tight'
    fig = plt.figure(figsize=figsize)
    ax = fig.add_subplot(111, projection='3d')
    # Fancy indexing: `verts[faces]` to generate a collection of triangles
    cmap = plt.cm.get_cmap('nipy_spectral_r')
    max_comp = in_bone_labels.max()

    rescale_func = rescale_func if rescale_func is not None else lambda x: x
    if flip:
        ax_flip = lambda x: rescale_func(x)[::-1].swapaxes(0, 2).swapaxes(0, 1)
    else:
        ax_flip = lambda x: rescale_func(x)

    for i in range(start_idx, min(max_comp, MAX_COMP_LIMIT) + 1):

        if i == 0:
            v_img = ax_flip((in_bone_labels > 0).astype(np.float32))
        else:
            v_img = ax_flip((in_bone_labels == i).astype(np.float32))

        if verbose:
            print('Adding meshes {}, sized {}'.format(i, np.sum(v_img)))
        mc_args = {'level': level}

        if vox_size is not None:
            mc_args['spacing'] = vox_size

        verts, faces = marching_cubes_classic(v_img, **mc_args)

        mesh = Poly3DCollection(verts[faces])

        if i > 0:
            mesh.set_facecolor(cmap(i / max_comp)[:3])
            mesh.set_alpha(0.75)
        else:
            mesh.set_facecolor([1, 1, 1])
            mesh.set_edgecolor([0, 0, 0])
            mesh.set_alpha(0.1)
        # mesh.set_edgecolor(cmap(i/max_comp)[:3])

        ax.add_collection3d(mesh)
    n_shape = ax_flip(in_bone_labels).shape
    if force_shape:
        ax.set_xlim(0, n_shape[0])
        ax.set_ylim(0, n_shape[1])
        ax.set_zlim(0, n_shape[2])
    else:
        pass  # ax.set_aspect('equal')
    ax.view_init(45, 45)
    ax.axis('off')
    return ax, fig
Exemple #27
0
def getVFByMarchingCubes(voxels, threshold=0.5):
    v, f = sk.marching_cubes_classic(voxels, level=threshold)
    return v, f
r2 = np.exp(-Z * r / n / amu)
r3 = (2 * Z * r / n / amu)**l
r4 = np.polyval(LaguerreGen(n - l - 1, 2 * l + 1), 2 * Z * r / n / amu)

R = r1 * r2 * r3 * r4

Y = compute_Ylm(l, m, theta, phi)

psi = R * Y

out = np.sqrt(psi * np.conj(psi))

res = np.meshgrid(np.arange(-rx, rx + 1, 1), np.arange(-ry, ry + 1, 1),
                  np.arange(-rz, rz + 1, 1))

x1 = res(0) * rlims / rn
y1 = res(1) * rlims / rn
z1 = res(2) * rlims / rn

vertices, simplices = measure.marching_cubes_classic(out, V)
#x,y,z = zip(*vertices)
colormap = ['rgb(255,105,180)', 'rgb(255,255,51)', 'rgb(0,191,255)']
fig = plotly.figure_factory.create_trisurf(x=x1,
                                           y=y1,
                                           z=z1,
                                           plot_edges=False,
                                           colormap=colormap,
                                           simplices=simplices,
                                           title="Isosurface")
py.iplot(fig)
        myoseg_2d_mask, mask_epi_3d, mask_endo_3d, scar3d = registration(
            'pkl_data/cine_lv_1143____.pkl',
            'pkl_data/LGE_scar_1143____new.pkl')

    end_time = time.time()

    print('registration : ', end_time - start_time)

    text_pos = get_text_position(myoseg_2d_mask)

    start_time = time.time()
    # uniform_filter() is equivalent to smooth3() in matlab.
    mask_diastole = scipy.ndimage.uniform_filter(mask_epi_3d, [4, 4, 20],
                                                 mode='nearest')
    # Using marching cubes algorithm to get a polygonal mesh of an isosurface
    verts, faces = measure.marching_cubes_classic(mask_diastole, level=0.5)
    end_time = time.time()
    print('marching_cubes : ', end_time - start_time)

    [avgX, avgY, avgZ] = map(np.mean, zip(*verts))
    [avgX_text, avgY_text] = map(np.mean, zip(*text_pos))
    text_pos = list(
        map(lambda p: (p[0] - avgX_text, p[1] - avgY_text), text_pos))

    app = QtWidgets.QApplication(sys.argv)

    # vis3D_method = 'glmeshitem'   # 'glvolumeitem' or 'glmeshitem'
    vis3D_method = 'glmeshitem'

    if vis3D_method == 'glvolumeitem':
Exemple #30
0
treePoints = annotatedSegmentationVolume[tumorPointsNameInMat]

# Configuration for cutter
barDepth = 10
columnHeight = mouldSlabHeight + 25

print(
    "#######################################\n####### TISSUE CUTTER GENERATOR #######\n#######################################"
)
print("### Input file: " + inputFilePath)
print("##### Matrix name: " + tumorVolumeNameInMat)
print("### Output file prefix: " + outputFilePath + "*")

print("# Performing marching cubes algorithm on tumor volume...")
verts, faces = measure.marching_cubes_classic(tree, )
tumorMesh = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
for i, f in enumerate(faces):
    for j in range(3):
        tumorMesh.vectors[i][j] = verts[f[j], :]
print("# done.")
print("# Save intermediate mesh...")
tumorMesh.save(outputFilePath + "tumour_preproc.stl")
print("# done.")

print("# Process and re-save intermediate mesh...")
in_file = outputFilePath + "tumour_preproc.stl"
out_file = outputFilePath + "tumour_postproc.stl"
filter_script_path = 'filter.mlx'
# Add input mesh
command = "/Applications/meshlab.app/Contents/MacOS/meshlabserver -i '" + os.getcwd(
Exemple #31
0
def plot_cartesian_isosurface(function_grids, levels, contours=[], cont_kwargs=[{}], tri_kwargs=[{'cmap': 'Spectral', 'lw': 1}],
                    fig_kwargs={'figsize': [12., 15.]}, ax_kwargs={}, font_kwargs={'name': 'serif', 'size': 30},
                    show_plot=True, fname=None, fig_num=None):

    # Repeat axis and line formats if only one value is given
    if len(tri_kwargs) == 1:
        tri_kwargs = tri_kwargs * len(function_grids)
    if len(cont_kwargs) == 1:
        cont_kwargs = cont_kwargs * len(function_grids)
    if len(levels) == 1:
        levels = levels * len(function_grids)

    # Checks that all inputs are now the same length
    assert len(function_grids) == len(tri_kwargs) == len(cont_kwargs) == len(levels)

    # Format Figure and Axes
    fig = plt.figure(fig_num, **fig_kwargs)
    ax = fig.add_axes([0.025, 0.15, 0.8, 0.85], projection='3d')

    # Format Axes
    format_3d_axes(ax, font_kwargs=font_kwargs, **ax_kwargs)

    for fg, level, tri_kwarg, cont_kwarg in zip(function_grids, levels, tri_kwargs, cont_kwargs):
        func = fg.data
        x, y, z = fg.grid.coordinates

        # Calculate Projected Functions (Normalized to the same max as original Function)
        yz_func = np.sum(func, axis=0)
        yz_func *= np.max(func)/np.max(yz_func)
        xz_func = np.sum(func, axis=1)
        xz_func *= np.max(func)/np.max(xz_func)
        xy_func = np.sum(func, axis=2)
        xy_func *= np.max(func)/np.max(xy_func)

        # Calculate and Plot Isosurface
        # Factor of 2 for consistency with bloch sphere convention
        del_x, del_y, del_z = 2 * (x[1] - x[0]), 2 * (y[1] - y[0]), 2 * (z[1] - z[0])
        x_min, y_min, z_min = 2 * np.min(x), 2 * np.min(y), 2 * np.min(z)
        x_max, y_max, z_max = 2 * np.max(x), 2 * np.max(y), 2 * np.max(z)
        verts, faces = measure.marching_cubes_classic(volume=func, level=level)
        verts[:, 0] = verts[:, 0] * del_x + x_min
        verts[:, 1] = verts[:, 1] * del_y + y_min
        verts[:, 2] = verts[:, 2] * del_z + z_min
        tri = ax.plot_trisurf(verts[:, 0], verts[:, 1], faces, verts[:, 2], zorder=100., **tri_kwarg)
        for contour in contours:
            lvl = contour * level
            if np.min(yz_func) < lvl < np.max(yz_func):
                cont = np.array(measure.find_contours(yz_func, lvl))
                cont = cont[0]
                cont[:, 0] = cont[:, 0] * del_y + y_min
                cont[:, 1] = cont[:, 1] * del_z + z_min
                tri = ax.plot(xs=x_min * np.ones_like(cont[:, 0]), ys=cont[:, 0], zs=cont[:, 1], zorder=-1., **cont_kwarg)
            if np.min(xz_func) < lvl < np.max(xz_func):
                cont = np.array(measure.find_contours(xz_func, lvl))
                cont = cont[0]
                cont[:, 0] = cont[:, 0] * del_x + x_min
                cont[:, 1] = cont[:, 1] * del_z + z_min
                tri = ax.plot(xs=cont[:, 0], ys=y_max * np.ones_like(cont[:, 0]), zs=cont[:, 1], zorder=-1., **cont_kwarg)
            if np.min(xy_func) < lvl < np.max(xy_func):
                cont = np.array(measure.find_contours(xy_func, lvl))
                cont = cont[0]
                cont[:, 0] = cont[:, 0] * del_x + x_min
                cont[:, 1] = cont[:, 1] * del_y + y_min
                tri = ax.plot(xs=cont[:, 0], ys=cont[:, 1], zs=z_min * np.ones_like(cont[:, 0]), zorder=-1., **cont_kwarg)

    # Draw and Save Figure
    if show_plot:
        plt.show()
    if fname is not None:
        fig.savefig(fname)

    return fig, tri
Exemple #32
0
def plot_contours(clf,
                  xx,
                  yy,
                  zz,
                  ww,
                  X_Circle,
                  X_Triangle,
                  X_MIN,
                  X_MAX,
                  Y_MIN,
                  Y_MAX,
                  Z_MIN,
                  Z_MAX,
                  type=2,
                  eps=0.1,
                  **params):
    """Plot the decision boundaries for a classifier.

    Parameters
    ----------
    ax: matplotlib axes object
    """
    plt.close('all')
    Z = clf.decision_function(np.c_[xx.ravel(),
                                    yy.ravel(),
                                    zz.ravel(),
                                    ww.ravel()])
    Z = Z.reshape(xx.shape)

    # Create a figure with axes for 3D plotting
    fig = plt.figure()
    ax = fig.gca(projection='3d')
    # Plot the different input points using 3D scatter plotting
    if type == 0:
        Z = Z[:, 0, :, :]
        b1 = ax.scatter(X_Circle[:, 1],
                        X_Circle[:, 2],
                        X_Circle[:, 3],
                        c='red')
        b2 = ax.scatter(X_Triangle[:, 1],
                        X_Triangle[:, 2],
                        X_Triangle[:, 3],
                        c='green')
        ax.set_xlabel("Y")
        ax.set_ylabel("Z")
        ax.set_zlabel("W")
    elif type == 1:
        Z = Z[:, :, 0, :]
        b1 = ax.scatter(X_Circle[:, 0],
                        X_Circle[:, 2],
                        X_Circle[:, 3],
                        c='red')
        b2 = ax.scatter(X_Triangle[:, 0],
                        X_Triangle[:, 2],
                        X_Triangle[:, 3],
                        c='green')
        ax.set_xlabel("X")
        ax.set_ylabel("Z")
        ax.set_zlabel("W")
    elif type == 2:
        Z = Z[:, :, :, 0]
        b1 = ax.scatter(X_Circle[:, 0],
                        X_Circle[:, 1],
                        X_Circle[:, 3],
                        c='red')
        b2 = ax.scatter(X_Triangle[:, 0],
                        X_Triangle[:, 1],
                        X_Triangle[:, 3],
                        c='green')
        ax.set_xlabel("X")
        ax.set_ylabel("Y")
        ax.set_zlabel("W")
    elif type == 3:
        Z = Z[:, :, :, 0]
        b1 = ax.scatter(X_Circle[:, 0],
                        X_Circle[:, 1],
                        X_Circle[:, 2],
                        c='red')
        b2 = ax.scatter(X_Triangle[:, 0],
                        X_Triangle[:, 1],
                        X_Triangle[:, 2],
                        c='green')
        ax.set_xlabel("X")
        ax.set_ylabel("Y")
        ax.set_zlabel("Z")

    # Plot the separating hyperplane by recreating the isosurface for the distance
    # == 0 level in the distance grid computed through the decision function of the
    # SVM. This is done using the marching cubes algorithm implementation from
    # scikit-image.
    try:
        verts, faces = measure.marching_cubes_classic(Z)
        # Scale and transform to actual size of the interesting volume
        verts = verts * \
            [X_MAX - X_MIN, Y_MAX - Y_MIN, Z_MAX - Z_MIN] / SPACE_SAMPLING_POINTS
        verts = verts + [X_MIN + 1, Y_MIN + 1, Z_MIN + 1]
        # and create a mesh to display
        alpha = 0.5
        fc = "orange"
        mesh = Poly3DCollection(verts[faces], alpha=alpha, linewidths=1)
        mesh.set_edgecolor('w')
        mesh.set_facecolor((0, 1, 0, alpha))
        ax.add_collection3d(mesh)

        # Some presentation tweaks
        #ax.set_xlim((-5, 5))
        #ax.set_ylim((-5, 5))
        #ax.set_zlim((-5, 5))
        filename = "image_eps_poly_n_" + str(eps) + str(type) + ".png"
        name_Image = os.path.join(FILEROOT, filename)
        ax.legend([mpatches.Patch(color='orange', alpha=0.3), b1, b2], [
            "Projected hyperplane", "class of circles", "class of  triangles"
        ],
                  loc="lower left",
                  prop=mpl.font_manager.FontProperties(size=11))
        plt.savefig(name_Image)
    except BaseException as e:
        print('Failed to do something: ' + str(e))
    plt.clf()
)

xTraj = currentPoint.kft[0,0,:]
yTraj = currentPoint.kft[1,0,:]
zTraj = currentPoint.kft[2,0,:]
trajectoryData = go.Scatter3d(
    x = xTraj, y = yTraj, z = zTraj,
    mode='lines',
    line=dict(
        color='#ff0000',
        width=10
    )
)

bands = band.e_3D_func(kxx, kyy, kzz)
vertices, simplices = measure.marching_cubes_classic(bands, 0)
x = (vertices[:,0]/(mesh_xy_graph-1)-0.5)*(5/2.)*pi/band.a
y = (vertices[:,1]/(mesh_xy_graph-1)-0.5)*(5/2.)*pi/band.b
z = (vertices[:,2]/(mesh_z_graph-1)-0.5)*4*pi/band.c
def vzFunction(kx,ky,kz):
    return (band.v_3D_func(kx, ky, kz)[2]+10)
colormap=['rgb(255,105,180)','rgb(255,255,51)','rgb(0,191,255)']
fermiSurface = ff.create_trisurf(
    x = x, y = y, z = z,
    simplices = simplices,
    plot_edges = False,
    color_func = vzFunction
)

# could use 'type': 'scatter3d',
graph3D = {