示例#1
0
 def csgraph_binary(self):
     if self._csgraph_binary is None:
         self._csgraph_binary = utils.create_csgraph(self.vertices,
                                                     self.edges,
                                                     euclidean_weight=False,
                                                     directed=True)
     return self._csgraph_binary
示例#2
0
 def _create_default_root(self):
     temp_graph = utils.create_csgraph(self.vertices,
                                       self.edges,
                                       euclidean_weight=True,
                                       directed=False)
     r = utils.find_far_points_graph(temp_graph)
     self.reroot(int(r[0]), reset_other_components=True)
示例#3
0
 def csgraph(self):
     if self._csgraph is None:
         self._csgraph = utils.create_csgraph(self.vertices,
                                              self.edges,
                                              euclidean_weight=True,
                                              directed=True)
     return self._csgraph
示例#4
0
 def _create_csgraph(self, directed=True, euclidean_weight=True):
     """Create the csgraph for the skeleton.
     """
     return utils.create_csgraph(self.vertices,
                                 self.edges,
                                 euclidean_weight=euclidean_weight,
                                 directed=directed)
示例#5
0
def soma_via_sphere(soma_pt, verts, edges, soma_d_thresh):
    """Get indices within soma_d_thresh of a soma_pt. Exclude vertices that left and come back."""
    closest_soma_ind = np.argmin(np.linalg.norm(verts - soma_pt, axis=1))
    close_inds = np.linalg.norm(verts - soma_pt, axis=1) < soma_d_thresh
    orig_graph = utils.create_csgraph(verts, edges, euclidean_weight=False)
    speye = sparse.diags(close_inds.astype(int))
    _, compids = sparse.csgraph.connected_components(orig_graph * speye)
    return np.flatnonzero(compids[closest_soma_ind] == compids), soma_d_thresh
示例#6
0
 def _create_default_root(self):
     temp_graph = utils.create_csgraph(
         self._rooted.vertices,
         self._rooted.edges,
         euclidean_weight=True,
         directed=False,
     )
     r = utils.find_far_points_graph(temp_graph)
     self._rooted.reroot(int(r[0]))
示例#7
0
    def _create_csgraph(self):
        """ Computes csgraph """
        if self.mesh_edges is not None:
            edges = self.mesh_edges
        else:
            edges = self.edges

        return utils.create_csgraph(self.vertices,
                                    edges,
                                    euclidean_weight=True,
                                    directed=False)
示例#8
0
    def __init__(self,
                 vertices,
                 edges,
                 vertex_properties={},
                 edge_properties={},
                 root=None):
        self._vertex_components = np.full(len(vertices), None)
        self._edge_components = np.full(len(edges), None)
        self._skeletons = []
        self._kdtree = None
        self._csgraph = None
        self._csgraph_binary = None

        vertices = np.array(vertices)
        edges = np.array(edges)
        bin_csgraph = utils.create_csgraph(vertices,
                                           edges,
                                           euclidean_weight=False)

        nc, v_lbls = sparse.csgraph.connected_components(bin_csgraph)
        lbls, count = np.unique(v_lbls, return_counts=True)
        lbl_order = np.argsort(count)[::-1]
        for lbl in lbls[lbl_order]:
            v_filter = np.where(v_lbls == lbl)[0]
            vertices_f, edges_f, filters = utils.reduce_vertices(
                vertices, edges, v_filter=v_filter, return_filter_inds=True)
            vertex_properties_f = {
                vp_n: np.array(vp_v)[filters[0]]
                for vp_n, vp_v in vertex_properties.items()
            }
            edge_properties_f = {
                ep_n: np.array(ep_v)[filters[1]]
                for ep_n, ep_v in edge_properties.items()
            }

            self._vertex_components[filters[0]] = lbl
            self._edge_components[filters[1]] = lbl
            if root in v_filter:
                root_f = np.where(root == v_filter)[0][0]
            else:
                root_f = None
            self._skeletons.append(
                Skeleton(vertices_f,
                         edges_f,
                         vertex_properties_f,
                         edge_properties_f,
                         root=root_f))
示例#9
0
 def cut_graph(self, vinds, directed=True, euclidean_weight=True):
     """Return a csgraph for the skeleton with specified vertices cut off from their parent vertex.
     
     Parameters
     ----------
     vinds :  
         Collection of indices to cut off from their parent.
     directed : bool, optional
         Return the graph as directed, by default True
     euclidean_weight : bool, optional
         Return the graph with euclidean weights, by default True. If false, the unweighted.
     
     Returns
     -------
     scipy.sparse.csr.csr_matrix  
         Graph with vertices in vinds cutt off from parents.
     """
     e_keep = ~np.isin(self.edges[:,0], vinds)
     es_new = self.edges[e_keep]
     return utils.create_csgraph(self.vertices, es_new,
                                 euclidean_weight=euclidean_weight,
                                 directed=directed)
示例#10
0
def find_edges_to_link(mesh,
                       vert_ind_a,
                       vert_ind_b,
                       distance_upper_bound=2500,
                       verbose=False):
    '''Given a mesh and two points on that mesh
    find a way to add edges to the  mesh graph so that those indices
    are on the same connected component 
    
    Parameters
    ----------
    mesh: trimesh_io.Mesh
        a mesh to find edges on
    vert_ind_a: int
        one index into mesh.vertices, the first point
    vert_ind_b: int
        a second index into mesh.vertices, the second point
    distance_upper_bound: float
        a maximum distance to (default 2500 in units of mesh.vertices)
    verbose: bool
        whether to print debug info

    Returns
    -------
    np.array
        a Kx2 array of mesh indices that represent edges to add to the mesh to link the two points
        in a way that creates the shortest path between the points across mututally closest vertices
        from connected components.. not adding edges if they are larger than distance_upper_bound
        TODO: distance_upper_bound not presently implemented
    '''
    timings = {}
    start_time = time.time()

    # find the distance between the merge points and their center
    d = np.linalg.norm(mesh.vertices[vert_ind_a, :] -
                       mesh.vertices[vert_ind_b, :])
    c = np.mean(mesh.vertices[[vert_ind_a, vert_ind_b], :], axis=0)
    # cut down the mesh to only include mesh vertices near the center of this
    # merge edge and within 2x the euclidean length of the edge
    inds = mesh.kdtree.query_ball_point(c, d * 2)
    # convert this to a mask
    mask = np.zeros(len(mesh.vertices), dtype=np.bool)
    mask[inds] = True

    timings['create_mask'] = time.time() - start_time
    start_time = time.time()
    # create a masked version of the mesh
    mask_mesh = mesh.apply_mask(mask)

    timings['apply_mask'] = time.time() - start_time
    start_time = time.time()
    ccs, labels = sparse.csgraph.connected_components(mask_mesh.csgraph,
                                                      return_labels=True)

    # map the original indices into this masked space
    mask_inds = mask_mesh.filter_unmasked_indices(
        np.array([vert_ind_a, vert_ind_b]))

    timings['masked_ccs'] = time.time() - start_time
    start_time = time.time()

    # find all the multually closest edges between the linked components
    new_edges = find_close_edges_sym(mask_mesh.vertices, labels,
                                     labels[mask_inds[0]],
                                     labels[mask_inds[1]])
    timings['find_close_edges_sym'] = time.time() - start_time
    start_time = time.time()

    # if there is now way to do this, fall back to adding all
    # edges that are close
    if len(new_edges) == 0:
        if verbose:
            print('finding all close edges')
        new_edges = find_all_close_edges(mask_mesh.vertices, labels, ccs)
        if verbose:
            print(f'new_edges shape {new_edges.shape}')
    # if there are still not edges we have a problem
    if len(new_edges) == 0:
        raise Exception('no close edges found')

    # create a new mesh that has these added edges
    #new_mesh = make_new_mesh_with_added_edges(mask_mesh, new_edges)
    total_edges = np.vstack([mask_mesh.graph_edges, new_edges])
    graph = utils.create_csgraph(mask_mesh.vertices, total_edges)
    timings['make_new_mesh'] = time.time() - start_time
    start_time = time.time()

    # find the shortest path to one of the linking spots in this new mesh
    d_ais_to_all, pred = sparse.csgraph.dijkstra(graph,
                                                 indices=mask_inds[0],
                                                 unweighted=False,
                                                 directed=False,
                                                 return_predecessors=True)
    timings['find_close_edges_sym'] = time.time() - start_time
    start_time = time.time()
    # make sure we found a good path
    if np.isinf(d_ais_to_all[mask_inds[1]]):
        raise Exception(
            f"cannot find link between {vert_ind_a} and {vert_ind_b}")

    # turn this path back into a original mesh index edge list
    path = utils.get_path(mask_inds[0], mask_inds[1], pred)
    path_as_edges = utils.paths_to_edges([path])
    good_edges = np_shared_rows(path_as_edges, new_edges)
    good_edges = np.sort(path_as_edges[good_edges], axis=1)
    timings['remap answers'] = time.time() - start_time
    if verbose:
        print(timings)
    return mask_mesh.map_indices_to_unmasked(good_edges)
示例#11
0
def collapse_soma_skeleton(soma_pt,
                           verts,
                           edges,
                           soma_d_thresh=12000,
                           mesh_to_skeleton_map=None,
                           soma_mesh_indices=None,
                           return_filter=False,
                           only_soma_component=True,
                           return_soma_ind=False):
    """function to adjust skeleton result to move root to soma_pt 

    Parameters
    ----------
    soma_pt : numpy.array
        a 3 long vector of xyz locations of the soma (None to just remove duplicate )
    verts : numpy.array
        a Nx3 array of xyz vertex locations
    edges : numpy.array
        a Kx2 array of edges of the skeleton
    soma_d_thresh : float
        distance from soma_pt to collapse skeleton nodes
    mesh_to_skeleton_map : np.array
        a M long array of how each mesh index maps to a skeleton vertex
        (default None).  The function will update this as it collapses vertices to root.
    soma_mesh_indices : np.array
         a K long array of indices in the mesh that should be considered soma
         Any  skeleton vertex on these vertices will all be collapsed to root.
    return_filter : bool
        whether to return a list of which skeleton vertices were used in the end
        for the reduced set of skeleton vertices
    only_soma_component : bool
        whether to collapse only the skeleton connected component which is closest to the soma_pt
        (default True)
    return_soma_ind : bool
        whether to return which skeleton index that is the soma_pt

    Returns
    -------
    np.array
        verts, Px3 array of xyz skeleton vertices
    np.array
        edges, Qx2 array of skeleton edges
    (np.array)
        new_mesh_to_skeleton_map, returned if mesh_to_skeleton_map and soma_pt passed 
    (np.array)
        used_vertices, if return_filter this contains the indices into the passed verts which the return verts is using
    int
        an index into the returned verts that is the root of the skeleton node, only returned if return_soma_ind is True
        
    """
    if soma_pt is not None:
        if only_soma_component:
            closest_soma_ind = np.argmin(
                np.linalg.norm(verts - soma_pt, axis=1))
            close_inds = np.linalg.norm(verts - soma_pt,
                                        axis=1) < soma_d_thresh
            orig_graph = utils.create_csgraph(verts,
                                              edges,
                                              euclidean_weight=False)
            speye = sparse.diags(close_inds.astype(int))
            _, compids = sparse.csgraph.connected_components(orig_graph *
                                                             speye)
            soma_verts = np.flatnonzero(compids[closest_soma_ind] == compids)
        else:
            dv = np.linalg.norm(verts - soma_pt_m, axis=1)
            soma_verts = np.where(dv < soma_d_thresh)[0]

        soma_pt_m = soma_pt[np.newaxis, :]
        new_verts = np.vstack((verts, soma_pt_m))
        soma_i = verts.shape[0]
        edges_m = edges.copy()
        edges_m[np.isin(edges, soma_verts)] = soma_i

        simple_verts, simple_edges = trimesh_vtk.remove_unused_verts(
            new_verts, edges_m)
        good_edges = ~(simple_edges[:, 0] == simple_edges[:, 1])

        if mesh_to_skeleton_map is not None:
            new_mesh_to_skeleton_map = mesh_to_skeleton_map.copy()
            remap_rows = np.isin(mesh_to_skeleton_map, soma_verts)
            new_mesh_to_skeleton_map[remap_rows] = soma_i
            new_mesh_to_skeleton_map = utils.nanfilter_shapes(
                np.unique(edges_m.ravel()), new_mesh_to_skeleton_map)
            if soma_mesh_indices is not None:
                new_mesh_to_skeleton_map[soma_mesh_indices] = len(
                    simple_verts) - 1

        output = [simple_verts, simple_edges[good_edges]]
        if mesh_to_skeleton_map is not None:
            output.append(new_mesh_to_skeleton_map)
        if return_filter:
            used_vertices = np.unique(
                edges_m.ravel())[:
                                 -1]  #Remove the largest value which is soma_i
            output.append(used_vertices)
        if return_soma_ind:
            output.append(len(simple_verts) - 1)
        return output

    else:
        simple_verts, simple_edges = trimesh_vtk.remove_unused_verts(
            verts, edges)
        return simple_verts, simple_edges
示例#12
0
def skeletonize_mesh(mesh,
                     soma_pt=None,
                     soma_radius=7500,
                     collapse_soma=True,
                     invalidation_d=12000,
                     smooth_vertices=False,
                     compute_radius=True,
                     compute_original_index=True,
                     verbose=True):
    '''
    Build skeleton object from mesh skeletonization
    
    Parameters
    ----------
    mesh: meshparty.trimesh_io.Mesh
        the mesh to skeletonize, defaults assume vertices in nm
    soma_pt: np.array
        a length 3 array specifying to soma location to make the root
        default=None, in which case a heuristic root will be chosen
        in units of mesh vertices. 
    soma_radius: float
        distance in mesh vertex units over which to consider mesh 
        vertices close to soma_pt to belong to soma
        these vertices will automatically be invalidated and no
        skeleton branches will attempt to reach them.
        This distance will also be used to collapse all skeleton
        points within this distance to the soma_pt root if collpase_soma
        is true. (default=7500 (nm))
    collapse_soma: bool
        whether to collapse the skeleton around the soma point (default True)
    invalidation_d: float
        the distance along the mesh to invalidate when applying TEASAR
        like algorithm.  Controls how detailed a structure the skeleton
        algorithm reaches. default (12000 (nm))
    smooth_vertices: bool
        whether to smooth the vertices of the skeleton
    compute_radius: bool
        whether to calculate the radius of the skeleton at each point on the skeleton
        (default True)
    compute_original_index: bool
        whether to calculate how each of the mesh nodes maps onto the skeleton
        (default True)
    verbose: bool
        whether to print verbose logging

    Returns
    -------
    :obj:`meshparty.skeleton.Skeleton`
           a Skeleton object for this mesh
    '''
    skel_verts, skel_edges, smooth_verts, orig_skel_index, skel_map = calculate_skeleton_paths_on_mesh(
        mesh,
        soma_pt=soma_pt,
        soma_thresh=soma_radius,
        invalidation_d=invalidation_d,
        return_map=True)

    if smooth_vertices is True:
        skel_verts = smooth_verts

    if collapse_soma is True and soma_pt is not None:
        soma_verts = mesh_filters.filter_spatial_distance_from_points(
            mesh, [soma_pt], soma_radius)
        new_v, new_e, new_skel_map, vert_filter, root_ind = collapse_soma_skeleton(
            soma_pt,
            skel_verts,
            skel_edges,
            soma_d_thresh=soma_radius,
            mesh_to_skeleton_map=skel_map,
            soma_mesh_indices=soma_verts,
            return_filter=True,
            return_soma_ind=True)
    else:
        new_v, new_e, new_skel_map = skel_verts, skel_edges, skel_map
        vert_filter = np.arange(len(orig_skel_index))

        if soma_pt is None:
            sk_graph = utils.create_csgraph(new_v, new_e)
            root_ind = utils.find_far_points_graph(sk_graph)[0]
        else:
            _, qry_inds = pyKDTree(new_v).query(
                soma_pt[np.newaxis, :])  # Still try to root close to the soma
            root_ind = qry_inds[0]

    skel_map_full_mesh = np.full(mesh.node_mask.shape, -1, dtype=np.int64)
    skel_map_full_mesh[mesh.node_mask] = new_skel_map
    ind_to_fix = mesh.map_boolean_to_unmasked(np.isnan(new_skel_map))
    skel_map_full_mesh[ind_to_fix] = -1

    props = {}
    if compute_original_index is True:
        props['mesh_index'] = np.append(
            mesh.map_indices_to_unmasked(orig_skel_index[vert_filter]), -1)
    if compute_radius is True:

        rs = ray_trace_distance(orig_skel_index[vert_filter], mesh)
        rs = np.append(rs, soma_radius)
        props['rs'] = rs

    sk = Skeleton(new_v,
                  new_e,
                  mesh_to_skel_map=skel_map_full_mesh,
                  vertex_properties=props,
                  root=root_ind)
    return sk
示例#13
0
def skeletonize_mesh(
    mesh,
    soma_pt=None,
    soma_radius=7500,
    collapse_soma=True,
    collapse_function="sphere",
    invalidation_d=12000,
    smooth_vertices=False,
    compute_radius=True,
    shape_function="single",
    compute_original_index=True,
    verbose=True,
    smooth_iterations=12,
    smooth_neighborhood=2,
    smooth_r=0.1,
    cc_vertex_thresh=100,
    root_index=None,
    remove_zero_length_edges=True,
    collapse_params={},
    meta={},
):
    """
    Build skeleton object from mesh skeletonization

    Parameters
    ----------
    mesh: meshparty.trimesh_io.Mesh
        the mesh to skeletonize, defaults assume vertices in nm
    soma_pt: np.array
        a length 3 array specifying to soma location to make the root
        default=None, in which case a heuristic root will be chosen
        in units of mesh vertices.
    soma_radius: float
        distance in mesh vertex units over which to consider mesh
        vertices close to soma_pt to belong to soma
        these vertices will automatically be invalidated and no
        skeleton branches will attempt to reach them.
        This distance will also be used to collapse all skeleton
        points within this distance to the soma_pt root if collpase_soma
        is true. (default=7500 (nm))
    collapse_soma: bool
        whether to collapse the skeleton around the soma point (default True)
    collapse_function: 'sphere' or 'branch'
        Determines which soma collapse function to use. Sphere uses the soma_radius
        and collapses all vertices within that radius to the soma. Branch is an experimental
        approach that tries to compute the right boundary for each branch into soma.
    invalidation_d: float
        the distance along the mesh to invalidate when applying TEASAR
        like algorithm.  Controls how detailed a structure the skeleton
        algorithm reaches. default (12000 (nm))
    smooth_vertices: bool
        whether to smooth the vertices of the skeleton
    compute_radius: bool
        whether to calculate the radius of the skeleton at each point on the skeleton
        (default True)
    shape_function: 'single' or 'cone'
        Selects how to compute the radius, either with a single ray or a cone of rays. Default is 'single'.
    compute_original_index: bool
        whether to calculate how each of the mesh nodes maps onto the skeleton
        (default True)
    smooth_iterations: int, optional
        Number of iterations to smooth (default is 12)
    smooth_neighborhood: int, optional
        Size of neighborhood to look at for smoothing
    smooth_r: float, optional
        Weight of update step in smoothing algorithm, default is 0.2
    root_index: int or None, optional
        A precise mesh vertex to use as the skeleton root. If provided, the vertex location overrides soma_pt. By default, None.
    remove_zero_length_edges: bool
        If True, removes vertices involved in zero length edges, which can disrupt graph computations. Default True.
    collapse_params: dict
        Extra keyword arguments for the collapse function. See soma_via_sphere and soma_via_branch_starts for specifics.
    cc_vertex_thresh : int, optional
        Smallest number of vertices in a connected component to skeletonize.
    verbose: bool
        whether to print verbose logging
    meta: dict
        Skeletonization metadata to add to the skeleton. See skeleton.SkeletonMetadata for keys.

    Returns
    -------
    :obj:`meshparty.skeleton.Skeleton`
           a Skeleton object for this mesh
    """
    (
        skel_verts,
        skel_edges,
        orig_skel_index,
        skel_map,
    ) = calculate_skeleton_paths_on_mesh(
        mesh,
        invalidation_d=invalidation_d,
        cc_vertex_thresh=cc_vertex_thresh,
        root_index=root_index,
        return_map=True,
    )

    if smooth_vertices is True:
        smooth_verts = smooth_graph(
            skel_verts,
            skel_edges,
            neighborhood=smooth_neighborhood,
            iterations=smooth_iterations,
            r=smooth_r,
        )
        skel_verts = smooth_verts

    if root_index is not None and soma_pt is None:
        soma_pt = mesh.vertices[root_index]

    if soma_pt is not None:
        soma_pt = np.array(soma_pt).reshape(1, 3)

    rs = None

    if collapse_soma is True and soma_pt is not None:
        temp_sk = Skeleton(
            skel_verts,
            skel_edges,
            mesh_index=mesh.map_indices_to_unmasked(orig_skel_index),
            mesh_to_skel_map=skel_map,
        )
        _, close_ind = temp_sk.kdtree.query(soma_pt)
        temp_sk.reroot(close_ind[0])

        if collapse_function == "sphere":
            soma_verts, soma_r = soma_via_sphere(
                soma_pt, temp_sk.vertices, temp_sk.edges, soma_radius
            )
        elif collapse_function == "branch":

            if shape_function == "single":
                rs = ray_trace_distance(
                    mesh.filter_unmasked_indices_padded(temp_sk.mesh_index), mesh
                )
            elif shape_function == "cone":
                rs = shape_diameter_function(
                    mesh.filter_unmasked_indices_padded(temp_sk.mesh_index),
                    mesh,
                    num_points=30,
                    cone_angle=np.pi / 3,
                )

            soma_verts, soma_r = soma_via_branch_starts(
                temp_sk,
                mesh,
                soma_pt,
                rs,
                search_radius=collapse_params.get("search_radius", 25000),
                fallback_radius=collapse_params.get("fallback_radius", soma_radius),
                cutoff_threshold=collapse_params.get("cutoff_threshold", 0.4),
                min_cutoff=collapse_params.get("min_cutoff", 0.1),
                dynamic_range=collapse_params.get("dynamic_range", 1),
                dynamic_threshold=collapse_params.get("dynamic_threshold", False),
            )
        if root_index is not None:
            collapse_index = np.flatnonzero(orig_skel_index == root_index)[0]
        else:
            collapse_index = None
        new_v, new_e, new_skel_map, vert_filter, root_ind = collapse_soma_skeleton(
            soma_verts,
            soma_pt,
            temp_sk.vertices,
            temp_sk.edges,
            mesh_to_skeleton_map=temp_sk.mesh_to_skel_map,
            collapse_index=collapse_index,
            return_filter=True,
            return_soma_ind=True,
        )
    else:
        new_v, new_e, new_skel_map = skel_verts, skel_edges, skel_map
        vert_filter = np.arange(len(orig_skel_index))
        if root_index is not None:
            root_ind = np.flatnonzero(orig_skel_index == root_index)[0]
        elif soma_pt is None:
            sk_graph = utils.create_csgraph(new_v, new_e)
            root_ind = utils.find_far_points_graph(sk_graph)[0]
        else:
            # Still try to root close to the soma
            _, qry_inds = spatial.cKDTree(new_v, balanced_tree=False).query(
                soma_pt[np.newaxis, :]
            )
            root_ind = qry_inds[0]

    skel_map_full_mesh = np.full(mesh.node_mask.shape, -1, dtype=np.int64)
    skel_map_full_mesh[mesh.node_mask] = new_skel_map
    ind_to_fix = mesh.map_boolean_to_unmasked(np.isnan(new_skel_map))
    skel_map_full_mesh[ind_to_fix] = -1

    props = {}

    if compute_original_index is True:
        if collapse_soma is True and soma_pt is not None:
            mesh_index = temp_sk.mesh_index[vert_filter]
            if root_index is None:
                mesh_index = np.append(mesh_index, -1)
        else:
            mesh_index = orig_skel_index[vert_filter]
        props["mesh_index"] = mesh_index

    if compute_radius is True:
        if rs is None:
            if shape_function == "single":
                rs = ray_trace_distance(orig_skel_index[vert_filter], mesh)
            elif shape_function == "cone":
                rs = shape_diameter_function(orig_skel_index[vert_filter], mesh)
        else:
            rs = rs[vert_filter]
        if collapse_soma is True and soma_pt is not None:
            if root_index is None:
                rs = np.append(rs, soma_r)
            else:
                rs[root_ind] = soma_r
        props["rs"] = rs

    sk_params = {
        "soma_pt_x": soma_pt[0, 0] if soma_pt is not None else None,
        "soma_pt_y": soma_pt[0, 1] if soma_pt is not None else None,
        "soma_pt_z": soma_pt[0, 2] if soma_pt is not None else None,
        "soma_radius": soma_radius,
        "collapse_soma": collapse_soma,
        "collapse_function": collapse_function,
        "invalidation_d": invalidation_d,
        "smooth_vertices": smooth_vertices,
        "compute_radius": compute_radius,
        "shape_function": shape_function,
        "smooth_iterations": smooth_iterations,
        "smooth_neighborhood": smooth_neighborhood,
        "smooth_r": smooth_r,
        "cc_vertex_thresh": cc_vertex_thresh,
        "remove_zero_length_edges": remove_zero_length_edges,
        "collapse_params": collapse_params,
        "timestamp": time.time(),
    }
    sk_params.update(meta)

    sk = Skeleton(
        new_v,
        new_e,
        mesh_to_skel_map=skel_map_full_mesh,
        mesh_index=props.get("mesh_index", None),
        radius=props.get("rs", None),
        root=root_ind,
        remove_zero_length_edges=remove_zero_length_edges,
        meta=sk_params,
    )

    if compute_radius is True:
        _remove_nan_radius(sk)

    return sk
示例#14
0
 def _create_csgraph(self):
     """ Computes csgraph """
     return utils.create_csgraph(self.vertices, self.graph_edges, euclidean_weight=True,
                                 directed=False)
示例#15
0
    def _create_csgraph(self, directed=True, euclidean_weight=True):

        return utils.create_csgraph(self.vertices,
                                    self.edges,
                                    euclidean_weight=euclidean_weight,
                                    directed=directed)