Esempio n. 1
0
 def draw_one(self, title, Lx, Ly, Lz, X, Y, Z, f, iso,
              elev=None, azim=None):
     """ Draw a single plot
             title: title of the plot
             X, Y, Z: 1D axes data
             f: 3D data set (C style index?!)
     """
     self.clf()
     vert, face = measure.marching_cubes(f, iso)
     self.rescale(vert, X, Y, Z, f.shape)
     self.ax = self.add_subplot(111, projection='3d')
     cmap, col = self.getcolor(vert, face)
     surface = Poly3DCollection(vert[face])
     surface.set_color(col)
     surface.set_edgecolor('')
     self.ax.add_collection3d(surface)
     self.ax.set_xlabel(Lx, fontsize=14)
     self.ax.set_ylabel(Ly, fontsize=14)
     self.ax.set_zlabel(Lz, fontsize=14)
     self.ax.set_xlim(X[0], X[-1])
     self.ax.set_ylim(Y[0], Y[-1])
     self.ax.set_zlim(Z[0], Z[-1])
     self.ax.set_title(title)
     self.ax.view_init(elev, azim)
     self.colorbar(cmap, shrink=0.8, fraction=0.1, label=r'V $^2$')
     self.tight_layout()
     self.canvas.draw()
Esempio n. 2
0
def plot_surface(voxels, voxel_size = 0.1):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    # First grid the data
    res = np.amax(voxels[1,:] - voxels[0,:])
    ux = np.unique(voxels[:,0])
    uy = np.unique(voxels[:,1])
    uz = np.unique(voxels[:,2])

    # Expand the model by one step in each direction
    ux = np.hstack((ux[0] - res, ux, ux[-1] + res))
    uy = np.hstack((uy[0] - res, uy, uy[-1] + res))
    uz = np.hstack((uz[0] - res, uz, uz[-1] + res))

    # Convert to a grid
    X, Y, Z = np.meshgrid(ux, uy, uz)

    # Create an empty voxel grid, then fill in the elements in voxels
    V = np.zeros(X.shape)
    N = voxels.shape[0]
    for ii in xrange(N):
            ix = ux == voxels[ii,0]
            iy = uy == voxels[ii,1]
            iz = uz == voxels[ii,2]
            V[iy, ix, iz] = 1

    marching_cubes = measure.marching_cubes(V, 0, spacing=(voxel_size, voxel_size, voxel_size))
    verts = marching_cubes[0]
    faces = marching_cubes[1]
    ax.plot_trisurf(verts[:, 0], verts[:,1], faces, verts[:, 2], lw=0, color='red')
    axis_equal(ax, verts[:, 0], verts[:,1], verts[:,2])
    plt.show()
Esempio n. 3
0
 def tsdf2mesh(voxel_size, origin, tsdf_vol):
     verts, faces, norms, vals = measure.marching_cubes(tsdf_vol, level=0)
     verts = verts * voxel_size + origin  # voxel grid coordinates to world coordinates
     mesh = trimesh.Trimesh(vertices=verts,
                            faces=faces,
                            vertex_normals=norms)
     return mesh
Esempio n. 4
0
def load_nii_file(fname, threshold=0.5):
    """Uses the marching cube algorithm to turn a .nii binary mask into a surface weighted point cloud."""

    mask = sitk.GetArrayFromImage(sitk.ReadImage(fname))
    # mask = skimage.transform.downscale_local_mean(mask, (4,4,4))
    verts, faces, normals, values = marching_cubes(mask, threshold)

    return to_measure(verts, faces)
Esempio n. 5
0
def plot_3d_image(ax, image, threshold=0.5, *args, **kwargs):
    vertices, faces = measure.marching_cubes(image, level=threshold)[:2]
    mesh = Poly3DCollection(vertices[faces], **kwargs)
    ax.add_collection3d(mesh)
    ax.set_xlabel("x")
    ax.set_ylabel("y")
    ax.set_zlabel("z")
    set_equal_3d_axis(ax, vertices)
Esempio n. 6
0
def test_marching_cubes_isotropic():
    ellipsoid_isotropic = ellipsoid(6, 10, 16, levelset=True)
    _, surf = ellipsoid_stats(6, 10, 16)
    verts, faces = marching_cubes(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
Esempio n. 7
0
def make_mesh(image, threshold=-300, step_size=1):

    print "Transposing surface"
    p = image.transpose(2,1,0)

    print "Calculating surface"
    verts, faces, norm, val = measure.marching_cubes(p, threshold, step_size=step_size, allow_degenerate=True)
    return verts, faces
def march_the_cubes(data, aff):
    from skimage.measure import marching_cubes
    import numpy as np
    from dipy.tracking.utils import move_streamlines
    verts, faces = marching_cubes(data, level=0.5)
    verts = np.asarray(list(move_streamlines(verts, aff)))
    #TODO: apply affine here
    return verts, faces
Esempio n. 9
0
def mesh_and_extract_largest_connected_surface(volume, level_set):
    vertices, faces = marching_cubes(volume, level_set)
    mesh = Trimesh()
    mesh.vertices = vertices
    mesh.faces = faces
    meshes = mesh.split(only_watertight=False)
    sorted_meshes = sorted(meshes, key=lambda x: len(x.vertices))
    return sorted_meshes[-1]
def test_marching_cubes_isotropic():
    ellipsoid_isotropic = ellipsoid(6, 10, 16, levelset=True)
    _, surf = ellipsoid_stats(6, 10, 16)
    verts, faces = marching_cubes(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
Esempio n. 11
0
 def march_cube(volume, level):
     """
     help method for the march cube, using the skimage module
     """
     verts, faces = measure.marching_cubes(volume,
                                           level,
                                           spacing=(1, 1, 1))
     return verts, faces
def march_the_cubes(data, aff):
    from skimage.measure import marching_cubes
    import numpy as np
    from dipy.tracking.utils import move_streamlines
    verts, faces = marching_cubes(data, level=0.5)
    verts = np.asarray(list(move_streamlines(verts, aff)))
    #TODO: apply affine here
    return verts, faces
Esempio n. 13
0
def _extract_surface(pot_field, val, res, spacing):
    from skimage import measure

    vertices, simplices, normals, values = measure.marching_cubes(pot_field.reshape(res[0], res[1], res[2]),
                                                                  val  # , #0.2424792,  # -0.559606
                                                                  # spacing=spacing, # (10.0, 10.0, 10.0)
                                                                  )
    return vertices, simplices, normals, values
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(sphere_small, 0, method='_lorensen')[:2]
    vertices2, faces2 = marching_cubes(sphere_small, 0,
                                       allow_degenerate=False)[:2]
    vertices3, faces3 = marching_cubes(sphere_small,
                                       0,
                                       allow_degenerate=False,
                                       method='lorensen')[: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)
Esempio n. 15
0
def plot_3D_image(3D_image,threshold=-300):
    p = 3D_image.transpose(2,1,0)
    verts, faces,normals, values = measure.marching_cubes(p, threshold, spacing=(0.1, 0.1, 0.1))
    
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')    
    ax.plot_trisurf(verts[:, 0], verts[:,1], faces, verts[:, 2],cmap='Spectral', lw=1)
    plt.show()
Esempio n. 16
0
def plot_3d_seg(image,name,threshold=1,save=False):
    # Position the scan upright,
    # so the head of the patient would be at the top facing the camera
    check = np.max(np.unique(image))>1
    verts, faces = measure.marching_cubes(image,threshold-1)
    if check:
        verts2, faces2 = measure.marching_cubes(image,threshold)
    fig = plt.figure(figsize=(15, 15))
    ax = fig.add_subplot(111, projection='3d')
    # Fancy indexing: `verts[faces]` to generate a collection of triangles
    mesh = Poly3DCollection(verts[faces], alpha=0.3)
    if check:
        mesh2 = Poly3DCollection(verts2[faces2], alpha=0.3)
    face_color = [1, 0.2, 0.2]
    if check:
        face_color2 = [0.3, 0.3, 1]
    mesh.set_facecolor(face_color)
    if check:
        mesh2.set_facecolor(face_color2)
    ax.add_collection3d(mesh)
    if check:
        ax.add_collection3d(mesh2)
    mesh_z = np.mean(image,axis=2)
    #mesh_y = np.mean(image,axis=1)
    #mesh_x = np.mean(image,axis=0)

    X=np.linspace(0,image.shape[0]-1,image.shape[0])
    Y=np.linspace(0,image.shape[1]-1,image.shape[1])
    Z=np.linspace(0,image.shape[2]-1,image.shape[2])
    #a,b=np.meshgrid(Y,Z)
    c,d=np.meshgrid(X,Y)
    #e,f=np.meshgrid(X,Z)
    cest = ax.contourf(c,d, np.transpose(mesh_z), zdir='z', offset=0, cmap="Blues")
    #cest = ax.contourf(np.transpose(mesh_x),b,a,zdir='x', offset=0, cmap="Greys")
    #cest = ax.contourf(e,np.transpose(mesh_y),f,zdir="y", offset=image.shape[1], cmap="Greys")
    ax.tick_params(axis='both', which='major', labelsize=18)
    ax.set_ylim(0, image.shape[1])
    ax.set_xlim(0, image.shape[0])
    ax.set_zlim(0, image.shape[2])
    ax.set_title(name+": 3D nodules and liver")
    if save:
        fig.savefig("/home/nnk/Bachelor/LiTS/Liver_segmentations/"+name+"_3D_nodules_and_liver.png", bbox_inches='tight')
    plt.close(fig)
    del mesh, verts, faces, face_color
    if check:
        del mesh2, verts2, faces2, face_color2
def test_marching_cubes_anisotropic():
    spacing = (1.0, 10 / 6.0, 16 / 6.0)
    ellipsoid_anisotropic = ellipsoid(6, 10, 16, spacing=spacing, levelset=True)
    _, surf = ellipsoid_stats(6, 10, 16)
    verts, faces = marching_cubes(ellipsoid_anisotropic, 0.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
Esempio n. 18
0
def update_segmentation_slices(selected, annotations):
    ctx = dash.callback_context
    # When shape annotations are changed, reset segmentation visualization
    if (ctx.triggered[0]["prop_id"] == "annotations.data"
            or annotations is None or annotations.get("x") is None
            or annotations.get("z") is None):
        mask = np.zeros_like(med_img)
        overlay1 = slicer1.create_overlay_data(mask)
        overlay2 = slicer2.create_overlay_data(mask)
        return go.Mesh3d(), overlay1, overlay2
    elif selected is not None and "range" in selected:
        if len(selected["points"]) == 0:
            return dash.no_update
        v_min, v_max = selected["range"]["x"]
        t_start = time()
        # Horizontal mask
        path = path_to_coords(annotations["z"]["path"])
        rr, cc = draw.polygon(path[:, 1] / spacing[1], path[:, 0] / spacing[2])
        mask = np.zeros(img.shape[1:])
        mask[rr, cc] = 1
        mask = ndimage.binary_fill_holes(mask)
        # top and bottom, the top is a lower number than the bottom because y values
        # increase moving down the figure
        top, bottom = sorted(
            [int(annotations["x"][c] / spacing[0]) for c in ["y0", "y1"]])
        img_mask = np.logical_and(med_img > v_min, med_img <= v_max)
        img_mask[:top] = False
        img_mask[bottom:] = False
        img_mask[top:bottom, np.logical_not(mask)] = False
        img_mask = largest_connected_component(img_mask)
        # img_mask_color = mask_to_color(img_mask)
        t_end = time()
        print("build the mask", t_end - t_start)
        t_start = time()
        # Update 3d viz
        verts, faces, _, _ = measure.marching_cubes(filters.median(
            img_mask, selem=np.ones((1, 7, 7))),
                                                    0.5,
                                                    step_size=3)
        t_end = time()
        print("marching cubes", t_end - t_start)
        x, y, z = verts.T
        i, j, k = faces.T
        trace = go.Mesh3d(x=z,
                          y=y,
                          z=x,
                          color="red",
                          opacity=0.8,
                          i=k,
                          j=j,
                          k=i)
        overlay1 = slicer1.create_overlay_data(img_mask)
        overlay2 = slicer2.create_overlay_data(img_mask)
        # todo: do we need an output to trigger an update?
        return trace, overlay1, overlay2
    else:
        return (dash.no_update, ) * 3
Esempio n. 19
0
def measure_surface_dist_real_size(struct1, struct2, pixdim):
    """
    :param struct1: ndarray of 3D image 1 (the result of nib.get_data())
    :param struct2: ndarray of 3D image 2 (the result of nib.get_data())
    :param pixdim:
    :return: Averaged Euclidan distance between the structures surface points (in mm)
    """
    voxel_size = [pixdim[2], pixdim[1], pixdim[3]]

    verts1, faces1, normals1, values1 = measure.marching_cubes(struct1, 0.5)
    verts2, faces2, normals2, values2 = measure.marching_cubes(struct2, 0.5)
    min_s_dist_array = np.zeros(verts1.shape[0])
    for ind, surface_point in enumerate(verts1):
        min_s_dist_array[ind] = min(
            np.linalg.norm(((verts2 - surface_point) * voxel_size), axis=1))

    mean_surface_dist = np.mean(min_s_dist_array)
    return mean_surface_dist
Esempio n. 20
0
def make_mesh(image, threshold=-500, step_size=1):

    p = image.transpose(2, 1, 0)

    verts, faces, norm, val = measure.marching_cubes(p,
                                                     threshold,
                                                     step_size=step_size,
                                                     allow_degenerate=True)
    return verts, faces
def plot_3d(image_1, image_2, threshold=-300):
    # Position the scan upright,
    # so the head of the patient would be at the top facing the camera

    try:
        print('Plotting...')
        global first_pass
        first_pass = '******'
        p_1 = image_1.transpose(2, 1, 0)
        verts1, faces1 = measure.marching_cubes(p_1, threshold)


        fig = plt.figure(figsize=(10, 10))
        ax1 = fig.add_subplot(121, projection='3d')

        # Fancy indexing: `verts[faces]` to generate a collection of triangles
        mesh1 = Poly3DCollection(verts1[faces1], alpha=0.70)
        face_color = [0.45, 0.45, 0.75]
        mesh1.set_facecolor(face_color)
        #return mesh
        ax1.add_collection3d(mesh1)
        ax1.set_xlim(0, p_1.shape[0])
        ax1.set_ylim(0, p_1.shape[1])
        ax1.set_zlim(0, p_1.shape[2])
        p_2 = image_2.transpose(2, 1, 0)

        verts2, faces2 = measure.marching_cubes(p_2, threshold)

        ax2 = fig.add_subplot(122, projection='3d')
        mesh2 = Poly3DCollection(verts2[faces2], alpha=0.70)
        mesh2.set_facecolor(face_color)

        ax2.add_collection3d(mesh2)

        ax2.set_xlim(0, p_2.shape[0])
        ax2.set_ylim(0, p_2.shape[1])
        ax2.set_zlim(0, p_2.shape[2])

        print('Done!')
        first_pass = '******'
    except:
        print('Problem Plotting Graph...\n ABORT')
        first_pass = '******'
    return fig
Esempio n. 22
0
    def _compute_shape_size_features(self):
        """ compute volume under a given mask"""

        # mask volume
        vox_size_SRC = 0.1 * np.array(self._IG.samplingSRC)  # unit: cm
        vox_vol = np.prod(vox_size_SRC)  # unit: cm^
        vol_cm3 = np.sum(self._maskImage_ndarray) * vox_vol  # unit: ml or cm^3
        self._df_feature_output['ShapeSize_vol_cm3'] = vol_cm3

        # mask surface area
        the_tumor_vol = np.zeros(self._inputImage_ndarray.shape)
        the_tumor_vol[self._maskImage_ndarray] = self._inputImage_ndarray[
            self._maskImage_ndarray]
        verts, faces = skm.marching_cubes(the_tumor_vol, 0.0,
                                          tuple(vox_size_SRC))
        surf_area_cm2 = skm.mesh_surface_area(verts, faces)  # unit: cm^2

        self._df_feature_output['ShapeSize_surf_area_cm2'] = surf_area_cm2
        self._df_feature_output['ShapeSize_compactness1'] = vol_cm3 / (
            np.sqrt(np.pi) * surf_area_cm2**(2. / 3.))
        self._df_feature_output['ShapeSize_compactness2'] = (
            36. * np.pi * vol_cm3**2) / (surf_area_cm2**3)
        self._df_feature_output['ShapeSize_sphericity'] = (np.pi**(
            1. / 3.)) * (6 * vol_cm3)**(2. / 3.) / surf_area_cm2
        self._df_feature_output[
            'ShapeSize_surface2volratio'] = surf_area_cm2 / vol_cm3

        # maximum 3D euclidean distance (or diameter?)
        kk, ii, jj = np.where(self._maskImage_ndarray == True)

        # skip computing max euclidean distance if the mask is too big such as including skin and etc.
        if len(kk) > 300000 and vol_cm3 > 70.:
            print '::ImageFeature:: compute_shape_size_feature, tumor mask is TOO big (vol: {} ml)! will not compute euc max distance :/'.format(
                vol_cm3)
        else:
            print '::ImageFeature:: max euc distance # of voxels to go through: {}, vol = {} cm3'.format(
                len(kk), vol_cm3)
            eucdis_tmp = np.zeros((len(kk), 1))
            for n in range(len(kk) - 1):
                px1 = np.column_stack((kk[n + 1:], ii[n + 1:], jj[n + 1:]))
                px2 = np.tile(np.array([kk[n], ii[n], jj[n]]),
                              (px1.shape[0], 1))
                vox_size_tile = np.tile(vox_size_SRC, (px1.shape[0], 1))
                eucdis = np.sqrt(
                    np.sum(((px1 - px2) * vox_size_tile)**2, axis=1))
                eucdis_tmp[n] = np.amax(eucdis)
            max_euc_dis = np.amax(eucdis_tmp)
            self._df_feature_output['ShapeSize_max_euc_dis'] = max_euc_dis

        # R is the radius of the sphere with the same volume as the tumor
        tumor_sphere_R = (3 * vol_cm3 / (4 * np.pi))**(1. / 3)
        self._df_feature_output[
            'ShapeSize_spherical_disproportion'] = surf_area_cm2 / (
                4 * np.pi * tumor_sphere_R**2)

        print '::ImageFeature:: complete compute_shape_size_features!'
Esempio n. 23
0
def mask2mesh(mask, mesh_processing=None, voxel_size=(1.0, 1.0, 1.0), level=0, step_size=2, preprocessing=None):
    # apply volume preprocessing
    mask = mask if preprocessing is None else preprocessing(mask)

    # create mesh using marching cubes
    vertx, faces, normals, _ = measure.marching_cubes(mask, level=level, spacing=voxel_size, step_size=step_size)

    # if no mesh processing is defined returns tuple with marching cubes outputs
    mesh = (vertx, faces, normals) if mesh_processing is None else mesh_processing(vertx, faces, normals)
    return mesh
Esempio n. 24
0
def extract_and_save_object(
    image, output_file_name, voxel_size, threshold=0, step_size=1
):
    verts, faces, normals, values = measure.marching_cubes(
        image, threshold, step_size=step_size
    )
    verts, faces = convert_obj_to_br(verts, faces, voxel_size)
    marching_cubes_to_obj(
        (verts, faces, normals, values), str(output_file_name)
    )
Esempio n. 25
0
    def make_mesh(self, threshold=400, step_size=1):
        images = self.resample()
        result = dict()

        for key, image in images.items():
            p = image.transpose(2, 1, 0)
            verts, faces, norm, val = measure.marching_cubes(p, threshold, step_size=step_size, allow_degenerate=True)
            result[key] = (verts, faces)

        return result
Esempio n. 26
0
def tsdf2mesh(tsdf_vol, mesh_path):
    tsdf_vol = np.transpose(tsdf_vol, (1, 0, 2))
    # Marching cubes
    verts, faces, norms, vals = measure.marching_cubes(tsdf_vol, level=0.0)

    # Get vertex colors
    colors = np.array([(186 // 2, 176 // 2, 172 // 2)
                       for _ in range(verts.shape[0])],
                      dtype=np.uint8)
    meshwrite(mesh_path, verts, faces, norms, colors)
def test_masked_marching_cubes():

    ellipsoid_scalar = ellipsoid(6, 10, 16, levelset=True)
    mask = np.ones_like(ellipsoid_scalar, dtype=bool)
    mask[:10, :, :] = False
    mask[:, :, 20:] = False
    ver, faces, _, _ = marching_cubes(ellipsoid_scalar, 0, mask=mask)
    area = mesh_surface_area(ver, faces)

    assert_allclose(area, 299.56878662109375, rtol=.01)
Esempio n. 28
0
    def from_volume(self, voxel_grid, level=0):
        '''
        generates a mesh from a volume voxel_grid, using marching cubes
        voxel_grid should be a voxel grid object.
        This allows for the coordinates of the found mesh to be in world space.
        '''
        temp_verts, temp_faces = marching_cubes(voxel_grid.V, level)

        self.vertices = voxel_grid.idx_to_world(temp_verts)
        self.faces = temp_faces
Esempio n. 29
0
def make_meshNew(image, threshold=-100, step_size=1):
    # Generates a mesh from a stack of images (image variable)

    print "Transposing surface"
    #     p = image.transpose(2,1,0)
    p = image

    print "Calculating surface"
    try:
        if (threshold == 0.0):
            verts, faces = measure.marching_cubes(p)
        else:
            verts, faces = measure.marching_cubes(p, threshold)
    except:
        if (threshold == 0.0):
            verts, faces = measure.marching_cubes_classic(p)
        else:
            verts, faces = measure.marching_cubes_classic(p, threshold)
    return verts, faces
Esempio n. 30
0
def make_outer_surface(filled_file, output_surface_file, se_diameter=15):
    if os.path.isfile(output_surface_file):
        log.info('Dural surface mesh %s already exists' %
                 os.path.basename(output_surface_file))
        return
    # read MRI
    volume = nbfs.MGHImage.from_filename(filled_file)
    volume = volume.get_data()

    # change elements from {0,1} to {0,255}
    volume *= 255

    # Gaussian filter (sigma=1mm)
    gaussian_volume = scimage.gaussian_filter(
        volume, 1, mode='constant')  # Is this correct?

    # Binarize filtered image
    avg = gaussian_volume.mean()
    gaussian_volume[gaussian_volume > avg] = 255
    gaussian_volume[gaussian_volume < avg] = 0

    # Morphological closing:

    # Construct structuring element
    xx, yy = np.meshgrid(list(range(-1 * se_diameter + 1, se_diameter)),
                         list(range(-1 * se_diameter + 1, se_diameter)))
    se = (xx**2 + yy**2) < se_diameter**2

    # Take closing

    closed_volume = np.stack([
        scimage.grey_closing(
            gaussian_volume[..., i], structure=se, mode='constant')
        for i in range(gaussian_volume.shape[-1])
    ],
                             axis=-1)

    # Binarize closed image
    thresh = closed_volume.max() / 2
    closed_volume[closed_volume <= thresh] = 0
    closed_volume[closed_volume > thresh] = 255

    # vertices,faces = isosurface(*,100)
    vertices, faces, _, _ = measure.marching_cubes(closed_volume, 100)

    # Reorient
    v2 = np.zeros(vertices.shape)
    v2[:, 0] = 129 - vertices[:, 0]
    v2[:, 1] = vertices[:, 2] - 129
    v2[:, 2] = 129 - vertices[:, 1]

    vertices = v2

    # Write geometry file
    nbfs.write_geometry(output_surface_file, vertices, faces)
Esempio n. 31
0
 def __build_mesh(self, image, threshold=300, step_size=1):
     '''
     Helper method to build mesh for given 3D scan
     '''
     print("Transposing surface")
     p = image.transpose(2, 1, 0)
     print("Generating mesh")
     verts, faces, _, _ = measure.marching_cubes(p, threshold,
                                                step_size=step_size)#, 
                                                #allow_degenerate=True)
     return verts, faces, p
Esempio n. 32
0
def calculate_burning_area_3d(regression_map, regression_depth, mc_mask,
                              volume_ratio):
    regression_depth = regression_depth / volume_ratio
    verts, faces, norm, line = measure.marching_cubes(
        regression_map,
        level=regression_depth,
        mask=mc_mask,
        spacing=(volume_ratio, volume_ratio,
                 volume_ratio))  # (hide false values)
    burning_area = measure.mesh_surface_area(verts, faces)
    return burning_area
Esempio n. 33
0
def reconstruction(structured_implicit,
                   resolution, b_min, b_max,
                   use_octree=False, num_samples=10000,
                   marching_cube=True):
    '''
    Reconstruct meshes from sdf predicted by the network.
    :param structured_implicit: a StructuredImplicit object.
    :param resolution: resolution of the grid cell
    :param b_min: bounding box corner [x_min, y_min, z_min]
    :param b_max: bounding box corner [x_max, y_max, z_max]
    :param use_octree: whether to use octree acceleration
    :param num_samples: how many points to query each gpu iteration
    :return: marching cubes results.
    '''
    # First we create a grid by resolution
    # and transforming matrix for grid coordinates to real world xyz
    coords, mat = create_grid(resolution, resolution, resolution,
                              b_min, b_max)

    # Then we define the lambda function for cell evaluation
    def eval_func(points, structured_implicit):
        points = np.expand_dims(points, axis=0)
        samples = torch.from_numpy(points).to(device=structured_implicit.device).float()
        samples = samples.transpose(-1, -2)
        samples = samples.expand(structured_implicit.batch_size, -1, -1)
        pred = structured_implicit.class_at_samples(samples, apply_class_transfer=False)[0][..., 0]
        return pred.detach().cpu().numpy()

    # Then we evaluate the grid
    if use_octree:
        sdf = []
        for s in structured_implicit.unbind():
            sdf.append(eval_grid_octree(coords, lambda p:eval_func(p, s), num_samples=num_samples).squeeze())
        sdf = np.stack(sdf)
    else:
        sdf = eval_grid(coords, lambda p:eval_func(p, structured_implicit),
                        num_samples=num_samples, batch_size=structured_implicit.batch_size)

    # Finally we do marching cubes
    if marching_cube:
        mesh = []
        for s in sdf:
            try:
                verts, faces, _, _ = measure.marching_cubes(s, -0.07)
                # transform verts into world coordinate system
                verts = np.matmul(mat[:3, :3], verts.T) + mat[:3, 3:4]
                verts = verts.T
                mesh.append(trimesh.Trimesh(vertices=verts, faces=faces))
            except (ValueError, RuntimeError) as e:
                print('Failed to extract mesh with error %s. Setting to unit sphere.' % repr(e))
                mesh.append(trimesh.primitives.Sphere(radius=0.5))
        return mesh
    else:
        return sdf, mat
Esempio n. 34
0
    def getModel(self):
        cloudField = self.cloudSet.getCloud()
        verts, faces, normals, values = (np.array((), dtype=np.float32)
                                         for i in range(4))
        if np.any(cloudField > 0.1):
            verts, faces, normals, values = measure.marching_cubes(
                cloudField, 0.1)
        # edges = self.cloudSet.getEdgeStrength(verts)
        # verts, faces, normals, edges = self.decimate(verts, faces, normals, edges, 3)

        return verts, faces, normals
def seg2mesh(idx, segmentation, step_size=1):
    mask = segmentation == idx

    _z, _x, _y = np.nonzero(mask)
    # returns True only if mask is not flat in any dimension
    if abs(_z.max() - _z.min()) > 1 and abs(_x.max() - _x.min()) > 1 and abs(
            _y.max() - _y.min()) > 1:
        coords, faces, _, _ = marching_cubes(mask, step_size=step_size)
        return coords, faces
    else:
        return None, None
Esempio n. 36
0
def add_trisurf(ax, arr, x, y, z, iso_val, **kwds):

    verts, faces, normals, values = measure.marching_cubes(arr, iso_val)
    verts_p = verts.copy()
    verts_p[:, 2] = np.interp(verts_p[:, 2], np.arange(len(x)), x)
    verts_p[:, 1] = np.interp(verts_p[:, 1], np.arange(len(y)), y)
    verts_p[:, 0] = np.interp(verts_p[:, 0], np.arange(len(z)), z)
    psurf = ax.plot_trisurf(verts_p[:, 2], verts_p[:, 1], faces, verts_p[:, 0],
                            **kwds)

    return psurf
def three_d_print(volume_data):
	b =  raw_input('What resolution? (enter an int between 0 and 6, where 0 is highest resolution):\n')
	name = raw_input('What should the filename be?') + '.stl'
	

	verts, faces = measure.marching_cubes(volume_data, 0)

	solid = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
	for i, f in enumerate(faces):
		for j in range(3):
			solid.vectors[i][j] = verts[f[j],:]

	
	solid.save(name)
Esempio n. 38
0
def isosurface(M,v,step,title=""):
    """
    returns the isosurface of value v of M, subsetting M with the steps argument
    """
    sel = np.arange(0,np.shape(M)[0],step)
    
    verts, faces = measure.marching_cubes(M[np.ix_(sel,sel,sel)], v, spacing=(1.0, 1.0, 1.0))
    
    fig = plt.figure(figsize = (10,7))
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_trisurf(verts[:, 0], verts[:,1], faces, verts[:, 2], lw=.1, cmap="jet")
    ax.axis("off")
    ax.view_init(elev=35, azim=70)
    plt.title(title)
    plt.show()
    def three_d_print(self):
        """This will produce a 3d printable stl based on self.volume_data. It is to be used for the final "print" button, and needs to be fed high quality data."""

        name = raw_input('What should the filename be?') + '.stl'
        

        verts, faces = measure.marching_cubes(self.volume_data, 0)   #Marching Cubes algorithm

        solid = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
        for i, f in enumerate(faces):
            for j in range(3):
                solid.vectors[i][j] = verts[f[j],:]

        
        solid.save(name)
Esempio n. 40
0
def marchingcubesobj(data,iso,objfile,scale=(1,1,1),center=(0,0,0),vertexoffset=0,excludeslice=False,debug=True):
    if iso < data.min() or iso > data.max():
        return 0,0
    vert,face = measure.marching_cubes(data,iso)
    vert[:,0]=scale[0]*(vert[:,0]-data.shape[0]/2.)+center[0]
    vert[:,1]=scale[1]*(vert[:,1]-data.shape[1]/2.)+center[1]
    vert[:,2]=scale[2]*(vert[:,2]-data.shape[2]/2.)+center[2]
    if debug:
        print 'Writing Data:'
    for i in xrange(vert.shape[0]):
        outstr = 'v %7.3f %7.3f %7.3f\n'%(vert[i,0],vert[i,1],vert[i,2])
        objfile.write(outstr)
    for i in xrange(face.shape[0]):
        outstr = 'f %9d %9d %9d\n'%(face[i,0]+1+vertexoffset,face[i,1]+1+vertexoffset,face[i,2]+1+vertexoffset)
        objfile.write(outstr)
   # print (vert[:,0].min(),vert[:,1].min(),vert[:,2].min()),(vert[:,0].max(),vert[:,1].max(),vert[:,2].max())
    return vert.shape[0], face.shape[0]
Esempio n. 41
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(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
Esempio n. 42
0
def test_correct_mesh_orientation():
    sphere_small = ellipsoid(1, 1, 1, levelset=True)
    verts, faces = marching_cubes(sphere_small, 0.)

    # Correct mesh orientation - descent
    corrected_faces1 = correct_mesh_orientation(sphere_small, verts, faces,
                                                gradient_direction='descent')
    corrected_faces2 = correct_mesh_orientation(sphere_small, verts, faces,
                                                gradient_direction='ascent')

    # Ensure ascent is opposite of descent for all faces
    np.testing.assert_array_equal(corrected_faces1, corrected_faces2[:, ::-1])

    # Ensure correct faces have been reversed: 1, 4, and 5
    idx = [1, 4, 5]
    expected = faces.copy()
    expected[idx] = expected[idx, ::-1]
    np.testing.assert_array_equal(expected, corrected_faces1)
def implicit_surface(density_field,size,resolution,iso=0.5):
    import numpy as np
    from scipy.cluster.vq                       import kmeans, vq
    from openalea.container import array_dict
   
    from skimage.measure import marching_cubes
    surface_points, surface_triangles = marching_cubes(density_field,iso)
    
    surface_points = (np.array(surface_points))*(size*resolution/np.array(density_field.shape)) - size*resolution/2.

    points_ids = np.arange(len(surface_points))
    points_to_delete = []
    for p,point in enumerate(surface_points):
        matching_points = np.sort(np.where(vq(surface_points,np.array([point]))[1] == 0)[0])
        if len(matching_points) > 1:
            points_to_fuse = matching_points[1:]
            for m_p in points_to_fuse:
                surface_triangles[np.where(surface_triangles==m_p)] = matching_points[0]
                points_to_delete.append(m_p)

    points_to_delete = np.unique(points_to_delete)
    print len(points_to_delete),"points deleted"
    surface_points = np.delete(surface_points,points_to_delete,0)
    points_ids = np.delete(points_ids,points_to_delete,0)
    surface_triangles = array_dict(np.arange(len(surface_points)),points_ids).values(surface_triangles)

    for p,point in enumerate(surface_points):
        matching_points = np.where(vq(surface_points,np.array([point]))[1] == 0)[0]
        if len(matching_points) > 1:
            print p,point
            raw_input()

    triangles_to_delete = []
    for t,triangle in enumerate(surface_triangles):
        if len(np.unique(triangle)) < 3:
            triangles_to_delete.append(t)
        # elif triangle.max() >= len(surface_points):
        #     triangles_to_delete.append(t)
    surface_triangles = np.delete(surface_triangles,triangles_to_delete,0)

    return surface_points, surface_triangles
def marching_cubes(field,iso=0.5):
    try:
        from skimage.measure import marching_cubes
        surface_points, surface_triangles = marching_cubes(density_field,iso)

    except ImportError:
        print "Please try to install SciKit-Image!"

        from mayavi import mlab
        from mayavi.mlab import contour3d

        mlab.clf()
        surface = mlab.contour3d(field,contours=[iso])

        my_actor=surface.actor.actors[0] 
        poly_data_object=my_actor.mapper.input 
        surface_points = (np.array(poly_data_object.points) - np.array([abs(grid_points/2.),abs(grid_points/2.),abs(grid_points/2.)])[np.newaxis,:])*(grid_max/abs(grid_points/2.))
        surface_triangles = poly_data_object.polys.data.to_array().reshape([-1,4]) 
        surface_triangles = surface_triangles[:,1:]

    return surface_points, surface_triangles
Esempio n. 45
0
def plot_3d(image, threshold=-300):
    
    # Position the scan upright, 
    # so the head of the patient would be at the top facing the camera
    p = image.transpose(2,1,0)
    
    verts, faces = measure.marching_cubes(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])

    plt.show()
Esempio n. 46
0
    def test_mc_skimage_orig_example(self):
        import numpy as np
        import matplotlib.pyplot as plt
        from mpl_toolkits.mplot3d.art3d import Poly3DCollection

        from skimage import measure
        from skimage.draw import ellipsoid


        # Generate a level set about zero of two identical ellipsoids in 3D
        ellip_base = ellipsoid(6, 10, 16, levelset=True)
        ellip_double = np.concatenate((ellip_base[:-1, ...],
                                       ellip_base[2:, ...]), axis=0)

        # Use marching cubes to obtain the surface mesh of these ellipsoids
        # outs = measure.marching_cubes(ellip_double, 0)
        # verts, faces, normals, values = measure.marching_cubes(ellip_double, 0)
        verts, faces = measure.marching_cubes(ellip_double, 0)

        # Display resulting triangular mesh using Matplotlib. This can also be done
        # with mayavi (see skimage.measure.marching_cubes docstring).
        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])
        mesh.set_edgecolor('k')
        ax.add_collection3d(mesh)

        ax.set_xlabel("x-axis: a = 6 per ellipsoid")
        ax.set_ylabel("y-axis: b = 10")
        ax.set_zlabel("z-axis: c = 16")

        ax.set_xlim(0, 24)  # a = 6 (times two for 2nd ellipsoid)
        ax.set_ylim(0, 20)  # b = 10
        ax.set_zlim(0, 32)  # c = 16

        plt.tight_layout()
        plt.show()
Esempio n. 47
0
def plot_voxels(volume):
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d.art3d import Poly3DCollection
    from skimage import measure

    # Use marching cubes to obtain the surface mesh
    verts, faces = measure.marching_cubes(volume, 0.5)

    # Display resulting triangular mesh using Matplotlib. This can also be done
    # with mayavi (see skimage.measure.marching_cubes docstring).
    fig = plt.figure(figsize=(10, 12))
    ax = fig.add_subplot(111, projection='3d')

    # Fancy indexing: `verts[faces]` to generate a collection of triangles
    mesh = Poly3DCollection(verts[faces])
    ax.add_collection3d(mesh)

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

    ax.set_aspect('equal')
    plt.show()
Esempio n. 48
0
def marche_cubes( ids , volume):
  """ 
  Given a segmentation volume and set of ids, 
  it first computes a boolean volume, where every voxel 
  which correspond to an id present in the ids set is set to true.
  It then create a mesh in the boundaries between true and false.
  
  The generated mesh guarantees coherent orientation as of 
  version 0.12. of scikit-image
  
  Args:
      ids (tuple): segment ids that we want to generate a mesh from.
      volume (numpy.array): volume to process
  """

  shape = volume.shape
  volume = np.in1d(volume,ids).reshape(shape)

  try:
    vertices, triangles =  measure.marching_cubes(volume, 0.4)

  except Exception, e:
    return np.array([]), np.array([])
Esempio n. 49
0
def isoSurface3d(image, level=1, fn='./plots/isosurf3d.html'):
	'''
	wrapper function for plotly's isosurface 3d plots

	args:
		@a image: 3d array of numbers

		@a level: level at which to make an isocontour

		@a fn: string, filename to save plot as
	'''

	vertices, simplices = measure.marching_cubes(image, level)

	x,y,z = zip(*vertices)

	fig = FF.create_trisurf(
		x=x,
		y=y,
		z=z,
		simplices=simplices
	)

	py.offline.plot(fig, filename=fn)
def reconstruction_from2DtoSTL(path, name, way, size):
    
    """
    Build a 3D object from a serie of 2D images.
    
    Input parameters
    ----------------
    path : str
        Folder with 2D images.
    name : str
        Wanted name for the created STL file.
    way : 'plot' or 'save'
        Can plot the 3D object or can save it with the STL extension.
    size : int or 'all'
        Can have a 3D object with every face, or can have a divided 3D object.
        Example : if size = 2, 1 of 2 slices on the x axis is taken,
                               1 of 2 slices on the y axis is taken,
                               and 1 of 2 slices on the z axis is taken,
                               so the 3D object is 8 times 'lighter'.
    """
    
    plt.close('all')
    
    line = currentframe().f_back.f_lineno
    if path.__class__ != str:
        print 'Line', line, '- Error: Directory must be str.'
        exit()
    elif name.__class__ != str:
        print 'Line', line, '- Error: Name must be str.'
        exit()
    elif (way != 'plot' and way != 'save'):
        print 'Line', line, '- Error: Way must be "plot" or "save".'
        exit()
    elif (size != 'all' and size.__class__ != int):
        print 'Line', line, '- Error: Size must be "all" or int.'
        exit()
    else:
        
        begin_time = time.time()
        
#        pixel_file = (glob.glob(path.split(path.split('/')[-2])[0] + 'pixel_spacing.txt'))[0]
#        with open(pixel_file, 'r') as pixel_readfile:
#            for line in pixel_readfile:
#                pixel_width = float(line.split('\t')[1])
#                pixel_height = float(line.split('\t')[2])
#                voxel_depth = float(line.split('\t')[3])$
        pixel_width = 1.0
        pixel_height = 1.0
        voxel_depth = 1.0
        
        files = glob.glob(path + '*')
        files.sort()
#        files.remove(pixel_file)
        
        width = (misc.imread(files[0])).shape[0]
        height = (misc.imread(files[0])).shape[1]
#        width, height = (misc.imread(files[0])).shape
        
        ZD_object = np.array([[0 for i in range(width)] for j in range(height)])
        
        k = 1
        
        for file in files:
            
            try:
                filename = file.split('/')[-1]
            except:
                filename = file.split('\\')[-1]
            
            print 'Reading image', filename, '(', k, '/', str(len(files)), ')...'
            
            image = misc.imread(file)
            
            for i in range(width):
                for j in range(height):
                    if len((image[i][j]).shape) != 0:
                        image[i][j] = image[i][j][0]
                          
            ZD_object = np.dstack((ZD_object, image))
            
            k = k+1
            
        append_time = time.time()
        print 'Image reading and appending to 3D object time:', round(append_time - begin_time, 3), 'seconds'
        
        print '\nSize of 3D object:', ZD_object.shape[0], 'x', ZD_object.shape[1], 'x', ZD_object.shape[2]
        print '\nStarting the 3D reconstruction...'
        
        if size == 'all':
            verts, faces = measure.marching_cubes(ZD_object, 0.5, spacing = (pixel_width, pixel_height, voxel_depth))
        else:
            verts, faces = measure.marching_cubes(ZD_object[::size,::size,::size], 0.5, spacing = (pixel_width, pixel_height, voxel_depth))
            
        marchingcubes_time = time.time()    
        print 'Marching cubes time:', round(marchingcubes_time - append_time, 3), 'seconds'
        
        if way == 'plot':
            
            print '\nPlotting the 3D object...'
            fig = plt.figure(figsize=(10, 12))
            ax = fig.add_subplot(111, projection='3d')
            #ax = Axes3D(fig)
            
            isosurface = Poly3DCollection(verts[faces])
            ax.add_collection3d(isosurface)
            
            ax.set_xlabel('x')
            ax.set_ylabel('y')
            ax.set_zlabel('z')
            
            ax.set_xlim(0, 100)
            ax.set_ylim(0, 100)
            ax.set_zlim(0, 100)
            
            plt.show()
            
            plot_time = time.time()
            print 'Plotting time:', round(plot_time - marchingcubes_time, 3), 'seconds'
        
        elif way == 'save':
            
            print '\nSaving the STL file...'
            final_obj = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
            for i,f in enumerate(faces):
                for j in range(3):
                    final_obj.vectors[i][j] = verts[f[j],:]
            try:
                path_1 = path.split(path.split('/')[-2])[0]
            except:
                path_1 = path.split(path.split('\\')[-2])[0]
            final_obj.save(path_1 + name + '.stl')
            
            save_time = time.time()
            print 'Saving time:', round(save_time - marchingcubes_time, 3), 'seconds'
        
        print '\n3D reconstruction done.\n'
            dcm.append(os.path.join(filename))
            
#read first file to start array
ds = dicom.read_file(dcm[0])
ds1p = ds.pixel_array
dsfull = ds1p

for i in range(1,len(dcm)):
    imgref = dcm[i]
    ds = dicom.read_file(imgref)
    pa = ds.pixel_array
    dsfull = np.dstack((dsfull, pa))
    
    
dsfull = dsfull.swapaxes(0,2)
                               
verts, faces = measure.marching_cubes(dsfull, 255)

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


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


ax.set_xlim(0, 21)  
ax.set_ylim(0, 692)  
ax.set_zlim(0, 778)  

plt.show()
Esempio n. 52
0
    def plot_ellipsoid(self, hkle, dpi=100):
        r"""Plots the resolution ellipsoid in the $Q_x$, $Q_y$, $W$ zone

        Parameters
        ----------
        hkle : tup
            A tuple of intergers or arrays of H, K, L, and W (energy transfer)
            values at which resolution ellipsoid are desired to be plotted

        dpi : int, optional
            Number of points in the plot

        """
        try:
            from skimage import measure
            import matplotlib.pyplot as plt
            from mpl_toolkits.mplot3d import Axes3D
        except ImportError:
            raise

        # clean arguments
        [length, H, K, L, W] = _CleanArgs(*hkle)

        # check if resolution already calculated at given hkle
        try:
            if np.all(H == self.H) and np.all(K == self.K) and np.all(L == self.L) and np.all(W == self.W):
                NP = np.array(self.RMS)
                R0 = self.R0
            else:
                self.calc_resolution(hkle)
                NP = np.array(self.RMS)
                R0 = self.R0
        except AttributeError:
            self.calc_resolution(hkle)
            NP = np.array(self.RMS)
            R0 = self.R0

        if NP.shape == (4, 4):
            NP = NP[np.newaxis]
            R0 = [R0]
        else:
            NP = NP.T

        # Create a canvas with a 3D viewport
        fig = plt.figure(facecolor='w', edgecolor='k')
        ax = fig.add_subplot(111, projection='3d')

        for ind, (r0, rms) in enumerate(zip(R0, NP)):
            qx0, qy0 = [np.dot([H[ind], K[ind], L[ind]], self.orient1 / np.linalg.norm(self.orient1) ** 2),
                        np.dot([H[ind], K[ind], L[ind]], self.orient2 / np.linalg.norm(self.orient2) ** 2)]
            qw0 = W[ind]

            def resolution_ellipsoid(prefac, resmat, x, y, w, x0, y0, w0):
                r"""Resolution ellipsoid equation for qx, qy, and w dimensions

                Parameters
                ----------
                prefac : float
                resmat : ndarray(4,4)
                x : ndarray
                y : ndarray
                w : ndarray
                x0 : float
                y0 : float
                w0 : float

                Returns
                -------
                    res_func : ndarray
                """
                ee = (resmat[0, 0] * (x - x0) ** 2 +
                      resmat[1, 1] * (y - qy0) ** 2 +
                      resmat[3, 3] * (w - w0) ** 2 +
                      2 * resmat[0, 1] * (x - x0) * (y - y0) +
                      2 * resmat[0, 2] * (x - x0) * (w - w0) +
                      2 * resmat[1, 2] * (y - y0) * (w - w0))

                return prefac * np.exp(-1 / 2 * ee)

            # get fwhm to generate grid for plotting
            w = []
            for i in range(3):
                _rms = np.delete(np.delete(rms, 2, axis=0), 2, axis=1)
                w.append(fproject(_rms.reshape((3, 3, 1)), i)[0] * 1.01)
            wx, wy, ww = w

            # build grid
            xg, yg, zg = np.mgrid[qx0 - wx:qx0 + wx:(dpi + 1) * 1j,
                                  qy0 - wy:qy0 + wy:(dpi + 1) * 1j,
                                  qw0 - ww:qw0 + ww:(dpi + 1) * 1j]

            # resolution function (ellipsoidal gaussian)
            vol = resolution_ellipsoid(r0, rms, xg, yg, zg, qx0, qy0, qw0)

            # isosurface of resolution function at half-max
            vertices, faces, normals, values = measure.marching_cubes(vol, vol.max() / 2.0, spacing=(wx / dpi, wy / dpi, ww / dpi))

            # properly center ellipsoid
            x_verts = vertices[:, 0] + qx0 - wx / 2
            y_verts = vertices[:, 1] + qy0 - wy / 2
            z_verts = vertices[:, 2] + qw0 - ww / 2

            # plot ellipsoid
            ax.plot_trisurf(x_verts, y_verts, faces, z_verts, lw=0, cmap='Spectral')

        # figure labels
        ax.ticklabel_format(style='plain', useOffset=False)
        ax.set_xlabel(r'$q_x$ (along {0}) (r.l.u.)'.format(self.orient1), fontsize=12)
        ax.set_ylabel(r'$q_y$ (along {0}) (r.l.u.)'.format(self.orient2), fontsize=12)
        ax.set_zlabel(r'$\hbar \omega$ (meV)', fontsize=12)

        plt.show()
Esempio n. 53
0
"""
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

from skimage import measure
from skimage.draw import ellipsoid

# Generate a level set about zero of two identical ellipsoids in 3D
ellip_base = ellipsoid(6, 10, 16, levelset=True)
ellip_double = np.concatenate((ellip_base[:-1, ...],
                               ellip_base[2:, ...]), axis=0)

# Use marching cubes to obtain the surface mesh of these ellipsoids
verts, faces, normals, values = measure.marching_cubes(ellip_double, 0)

# Display resulting triangular mesh using Matplotlib. This can also be done
# with mayavi or visvis (see skimage.measure.marching_cubes docstring).
fig = plt.figure(figsize=(10, 12))
ax = fig.add_subplot(111, projection='3d')

# Fancy indexing: `verts[faces]` to generate a collection of triangles
mesh = Poly3DCollection(verts[faces])
ax.add_collection3d(mesh)

ax.set_xlabel("x-axis: a = 6 per ellipsoid")
ax.set_ylabel("y-axis: b = 10")
ax.set_zlabel("z-axis: c = 16")

ax.set_xlim(0, 24)  # a = 6 (times two for 2nd ellipsoid)
print 'losses max -> ',(np.amax( losses ))
print 'losses argmax -> ',(np.argmax( losses ))
print 'losses x[max] -> ',g_x[(np.argmax( losses ))]
print 'v',v
print 'sigma',sigma

data = pop_data_grid(g_Desc[g_counter], g_Desc[g_counter].beta,g_Desc[g_counter].rho,
                     x0_max,x1_max,x2_max,x0_min,x1_min,x2_min)

proc_data(g_Desc[g_counter].beta,g_Desc[g_counter].rho,data)


# In[22]:

# Use marching cubes to obtain the surface mesh of these ellipsoids
verts, faces = measure.marching_cubes(data, 0)

for elev in [180,120,60,90]:
    for azim in [30,90,180,240]:
        # Display resulting triangular mesh using Matplotlib. This can also be done
        # with mayavi (see skimage.measure.marching_cubes docstring).
        fig = plt.figure(figsize=(10, 12))
        ax = fig.add_subplot(111, projection='3d')

        # Fancy indexing: `verts[faces]` to generate a collection of triangles
        mesh = Poly3DCollection(verts[faces])
        ax.add_collection3d(mesh)
        ax.view_init(elev=elev, azim=azim)

        ax.set_xlim(0,grid_steps)  
        ax.set_ylim(0,grid_steps)  
Esempio n. 55
0
def getVFByMarchingCubes(voxels, threshold=0.5):
    v, f =  sk.marching_cubes(voxels, level=threshold)
    return v, f
def reconstruction_fromXYZtoSTL(file, way, size):
    
    """
    Build a 3D object from a XYZ file.
    
    Input parameters
    ----------------
    file : str
        XYZ file.
    way : 'plot' or 'save'
        Can plot the 3D object or can save it with the STL extension.
    size : int or 'all'
        Can have a 3D object with every face, or can have a divided 3D object.
        Example : if size = 2, 1 of 2 slices on the x axis is taken,
                               1 of 2 slices on the y axis is taken,
                               and 1 of 2 slices on the z axis is taken,
                               so the 3D object is 8 times 'lighter'.
    """
    
    line = currentframe().f_back.f_lineno
    if file.__class__ != str:
        print 'Line', line, '- Error: File must be str.'
        exit()
    elif (way != 'plot' and way != 'save'):
        print 'Line', line, '- Error: Way must be "plot" or "save".'
        exit()
    elif (size != 'all' and size.__class__ != int):
        print 'Line', line, '- Error: Size must be "all" or int.'
        exit()
    else:
        
        begin_time = time.time()
        print '\nStarting the conversion from a XYZ file to a STL file...'
        
        images = reconstruction_fromXYZto2D(file, 'nosave')
            
        XYZto2D_time = time.time()
        print 'Converting from XYZ file to 2D images:', round(XYZto2D_time - begin_time, 3), 'seconds'
        
        
        width = (images[0]).shape[0]
        height = (images[0]).shape[1]
        
        begin_time = time.time()
        
        print "\nStarting the 3D reconstruction..."
        
        ZD_object = np.array([[0 for i in range(width)] for j in range(height)])
        
        for image in images:
            
            ZD_object = np.dstack((ZD_object, image))
            
        append_time = time.time()
        print 'Image reading and appending to 3D object time:', round(append_time - XYZto2D_time, 3), 'seconds'
        
        print '\nSize of 3D object:', ZD_object.shape[0], 'x', ZD_object.shape[1], 'x', ZD_object.shape[2]
            
        if size == 'all':
            verts, faces = measure.marching_cubes(ZD_object, 0.5)
        else:
            verts, faces = measure.marching_cubes(ZD_object[::size,::size,::size], 0.5)
            
        marchingcubes_time = time.time()
        print 'Marching cubes time:', round(marchingcubes_time - begin_time, 3), 'seconds'
        
        if way == 'plot':
            
            print '\nPlotting the 3D object...'
            fig = plt.figure(figsize=(10, 12))
            ax = fig.add_subplot(111, projection='3d')
            #ax = Axes3D(fig)
            
            isosurface = Poly3DCollection(verts[faces])
            ax.add_collection3d(isosurface)
            
            ax.set_xlabel('x')
            ax.set_ylabel('y')
            ax.set_zlabel('z')
            
            ax.set_xlim(0, 100)
            ax.set_ylim(0, 100)
            ax.set_zlim(0, 100)
            
            plt.show()
            
            plot_time = time.time()
            print 'Plotting time:', round(plot_time - marchingcubes_time, 3), 'seconds'
        
        elif way == 'save':
                
            print '\nSaving the STL file...'
            final_obj = mesh.Mesh(np.zeros(faces.shape[0], dtype=mesh.Mesh.dtype))
            for i,f in enumerate(faces):
                for j in range(3):
                    final_obj.vectors[i][j] = verts[f[j],:]
            name = file.split('.xyz')[0]
            final_obj.save(name + '.stl')
            
            save_time = time.time()
            print 'Saving time:', round(save_time - marchingcubes_time, 3), 'seconds'
        
        print '\n3D reconstruction done.\n'
Esempio n. 57
0
def writeContoursToJson(LFP, x, y, z, n=1, directory='neuron'):
    dname_base = 'contour_'
    fname_base = 'frame_'
    config_name = 'config.js'
    dirs_config_name = 'contour_dir_list.js'

    dx = np.abs(x[1] - x[0])
    dy = np.abs(y[1] - y[0])
    dz = np.abs(z[1] - z[0])

    nx = len(x)
    ny = len(y)
    nz = len(z)

    baseline = 0
    # Choose n isopotentials between max amplitude and baseline, not 
    # including endpoints.
    amp_max = LFP.max()
    values_pos = []
    if amp_max > 0:
        values_pos = np.linspace(baseline, amp_max, n + 2)
        values_pos = values_pos[1:-1]

    amp_min = LFP.min()
    values_neg = []
    if amp_min < 0:
        values_neg = np.linspace(baseline, amp_min, n + 2)
        values_neg = values_neg[1:-1]

    contour_directories = []
    contour_cnt = 0
    for iso_pot_val in values_pos:
        # Create a seperate folder for each contour animation.
        dir_name = dname_base + '%04d' % (contour_cnt)
        contour_directories.append(dir_name)
        dir_path = directory + '/' + dir_name
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

        for i in xrange(LFP.shape[1]):
            U = LFP[:, i].reshape(nx, ny, nz)
            # The marching cubes algorithm cannot deal with levels
            # outside the range of U.
            if U.max() < iso_pot_val or U.min() > iso_pot_val:
                verts = np.zeros([0, 3])
                faces = np.zeros([0, 3])
            else:
                verts, faces = measure.marching_cubes(U,
                                                      iso_pot_val,
                                                      spacing=(dx, dy, dz))
                verts[:, 0] = verts[:, 0] + x[0]
                verts[:, 1] = verts[:, 1] + y[0]
                verts[:, 2] = verts[:, 2] + z[0]
            filename = fname_base + '%04d.js' % (i)
            meshToJson(verts, faces, filename, dir_path)

        # Save a config file listing all the data files.
        data = {'n_frames': LFP.shape[1]}
        dataString = json.dumps(data)
        f = open(dir_path + '/' + config_name, 'w')
        f.write(dataString)
        f.close()
        contour_cnt += 1
    for iso_pot_val in values_neg:
        # Create a seperate folder for each contour animation.
        dir_name = dname_base + '%04d' % (contour_cnt)
        contour_directories.append(dir_name)
        dir_path = directory + '/' + dir_name
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

        for i in xrange(LFP.shape[1]):
            U = LFP[:, i].reshape(nx, ny, nz)
            # The marching cubes algorithm cannot deal with levels
            # outside the range of U.
            if U.max() < iso_pot_val or U.min() > iso_pot_val:
                verts = np.zeros([0, 3])
                faces = np.zeros([0, 3])
            else:
                verts, faces = measure.marching_cubes(U,
                                                      iso_pot_val,
                                                      spacing=(dx, dy, dz))
                verts[:, 0] = verts[:, 0] + x[0]
                verts[:, 1] = verts[:, 1] + y[0]
                verts[:, 2] = verts[:, 2] + z[0]
            filename = fname_base + '%04d.js' % (i)
            meshToJson(verts, faces, filename, dir_path)

        # Save a config file listing all the data files.
        data = {'n_frames': LFP.shape[1]}
        dataString = json.dumps(data)
        f = open(dir_path + '/' + config_name, 'w')
        f.write(dataString)
        f.close()
        contour_cnt += 1
    # Save a config file listing all the data files.
    data = {'n_contours': len(contour_directories)}
    dataString = json.dumps(data)
    f = open(directory + '/' + dirs_config_name, 'w')
    f.write(dataString)
    f.close()
Esempio n. 58
0
            # get the error size
            n_error_train = y_pred_train[y_pred_train == -1].size

            # Distance of the samples X, Y, Z to the sperating hyperplane
            Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel(), zz.ravel()])
            Z = Z.reshape(xx.shape)

            plt.title("Novelty Detection")
            ax = plt.gca(projection='3d')

            # draw the points on the 3D graph
            b1 = ax.scatter(X_train[:, 0], X_train[:, 1], X_train[:, 2], c='white')

            # Signifies the Learning Curve
            # IMP it should be better as the data set gets better
            verts, faces = measure.marching_cubes(Z, 0)
            verts = verts * \
                [X_MAX - X_MIN, Y_MAX - Y_MIN, Z_MAX - Z_MIN] / SPACE_SAMPLING_POINTS
            verts = verts + [X_MIN, Y_MIN, Z_MIN]
            mesh = Poly3DCollection(verts[faces], facecolor='orange', edgecolor='gray', alpha=0.3)
            ax.add_collection3d(mesh)

            ax.set_xlim((-20, 20))
            ax.set_ylim((-20, 20))
            ax.set_zlim((-20, 20))
            ax.axis('tight')

            ax.set_xlabel("X")
            ax.set_ylabel("Y")
            ax.set_zlabel("Z")
            # ax.legend([mpatches.Patch(color='orange', alpha=0.3), b1, b2, c],
Esempio n. 59
0


phi = la.spsolve(K3, source3)
phi = phi.reshape((N,N,N))


x = np.linspace(0,L,N,endpoint=False)
y = np.linspace(0,L,N,endpoint=False)
z = np.linspace(0,L,N,endpoint=False)
xv, yv, zv = np.meshgrid(x,y,z)


# http://scikit-image.org/docs/dev/auto_examples/plot_marching_cubes.html
from skimage import measure
verts, faces = measure.marching_cubes(phi, 0.01) #-.1
#print verts
verts = verts * L / N # rescale verts
from mpl_toolkits.mplot3d.art3d import Poly3DCollection


import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()

ax = fig.add_subplot(111, projection='3d')
mesh = Poly3DCollection(verts[faces])
ax.add_collection3d(mesh)


verts, faces = measure.marching_cubes(phi, -0.01) #-.1
Esempio n. 60
0
"""
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

from skimage import measure
from skimage.draw import ellipsoid

# Generate a level set about zero of two identical ellipsoids in 3D
ellip_base = ellipsoid(6, 10, 16, levelset=True)
ellip_double = np.concatenate((ellip_base[:-1, ...],
                               ellip_base[2:, ...]), axis=0)

# Use marching cubes to obtain the surface mesh of these ellipsoids
verts, faces = measure.marching_cubes(ellip_double, 0)

# Display resulting triangular mesh using Matplotlib. This can also be done
# with mayavi (see skimage.measure.marching_cubes docstring).
fig = plt.figure(figsize=(10, 12))
ax = fig.add_subplot(111, projection='3d')

# Fancy indexing: `verts[faces]` to generate a collection of triangles
mesh = Poly3DCollection(verts[faces])
ax.add_collection3d(mesh)

ax.set_xlabel("x-axis: a = 6 per ellipsoid")
ax.set_ylabel("y-axis: b = 10")
ax.set_zlabel("z-axis: c = 16")

ax.set_xlim(0, 24)  # a = 6 (times two for 2nd ellipsoid)