def collapse_soma_skeleton(soma_pt,
                           verts,
                           edges,
                           soma_d_thresh=12000,
                           mesh_to_skeleton_map=None):
    if soma_pt is not None:
        soma_pt_m = soma_pt[np.newaxis, :]
        dv = np.linalg.norm(verts - soma_pt_m, axis=1)
        soma_verts = np.where(dv < soma_d_thresh)[0]
        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 mesh_to_skeleton_map is None:
            return simple_verts, simple_edges[good_edges]
        else:
            return simple_verts, simple_edges[
                good_edges], new_mesh_to_skeleton_map
    else:
        simple_verts, simple_edges = trimesh_vtk.remove_unused_verts(
            verts, edges)
        return simple_verts, simple_edges
Beispiel #2
0
def collapse_soma_skeleton(soma_pt, verts, edges, soma_d_thresh=12000):
    if soma_pt is not None:
        soma_pt_m = soma_pt[np.newaxis, :]
        dv = np.linalg.norm(verts - soma_pt_m, axis=1)
        soma_verts = np.where(dv < soma_d_thresh)[0]
        new_verts = np.vstack((verts, soma_pt_m))
        soma_i = verts.shape[0]
        edges[np.isin(edges, soma_verts)] = soma_i
        simple_verts, simple_edges = trimesh_vtk.remove_unused_verts(
            new_verts, edges)
        good_edges = ~(simple_edges[:, 0] == simple_edges[:, 1])
        return simple_verts, simple_edges[good_edges]
    else:
        simple_verts, simple_edges = trimesh_vtk.remove_unused_verts(
            verts, edges)
        return simple_verts, simple_edges
Beispiel #3
0
def skeletonize(mesh_meta,
                seg_id,
                soma_pt=None,
                soma_thresh=7500,
                invalidation_d=10000,
                smooth_neighborhood=5,
                max_tip_d=2000,
                large_skel_path_threshold=5000,
                cc_vertex_thresh=100,
                do_cross_section=False):

    mesh = mesh_meta.mesh(seg_id=seg_id,
                          merge_large_components=False,
                          remove_duplicate_vertices=False)
    mesh.stitch_overlapped_components()

    all_paths, roots, tot_path_lengths = skeletonize_components(
        mesh,
        soma_pt=soma_pt,
        soma_thresh=soma_thresh,
        invalidation_d=invalidation_d,
        cc_vertex_thresh=cc_vertex_thresh)
    tot_edges = merge_tips(mesh,
                           all_paths,
                           roots,
                           tot_path_lengths,
                           large_skel_path_threshold=large_skel_path_threshold,
                           max_tip_d=max_tip_d)

    skel_verts, skel_edges = trimesh_vtk.remove_unused_verts(
        mesh.vertices, tot_edges)
    smooth_verts = smooth_graph(skel_verts,
                                skel_edges,
                                neighborhood=smooth_neighborhood)
    if do_cross_section:
        cross_sections, centers = trimesh_vtk.calculate_cross_sections(
            mesh, smooth_verts, skel_edges)
        center_verts = recenter_verts(smooth_verts, skel_edges, centers)
        smooth_center_verts = smooth_graph(center_verts,
                                           skel_edges,
                                           neighborhood=smooth_neighborhood)
        return skel_verts, skel_edges, cross_sections, smooth_verts, smooth_center_verts
    else:
        return skel_verts, skel_edges, smooth_verts
Beispiel #4
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