Exemple #1
0
def skeletoniseSkimg(maskFilePath):
    image = io.imread(maskFilePath)

    image = rgb2gray(image)

    binary = image > 0

    # perform skeletonization
    skeleton = skeletonize(binary)
    summary = summarize(Skeleton(skeleton, spacing=1))

    # starting coordinate in y, x
    startCoord = [
        summary.iloc[0]['image-coord-src-0'],
        summary.iloc[0]['image-coord-src-1']
    ]
    endCoord = [
        summary.iloc[0]['image-coord-dst-0'],
        summary.iloc[0]['image-coord-dst-1']
    ]

    # c0 contains information of all points on the skeleton
    # g0 is the adjacency list
    g0, c0, _ = skeleton_to_csgraph(skeleton, spacing=1)
    all_pts = c0[1:]

    # get points along skeleton in the correct sequence
    pts = traverseSkeleton(startCoord, endCoord, g0.toarray(), all_pts)

    return pts.astype(int)
Exemple #2
0
    def get_no_of_forks(self, plot=False):

        # get the degree for every cell pixel (no. of neighbouring pixels)
        pixel_graph, coordinates, degrees = skeleton_to_csgraph(
            self.cell_skeleton)
        # array of all pixel locations with degree more than 2
        fork_image = np.where(degrees > [2], 1, 0)
        s = scipy.ndimage.generate_binary_structure(2, 2)
        labeled_array, num_forks = scipy.ndimage.label(fork_image, structure=s)

        if plot == True:
            fork_indices = np.where(degrees > [2])
            fork_coordinates = zip(fork_indices[0], fork_indices[1])

            fig, ax = plt.subplots(figsize=(4, 4))
            ax.set_title('path')
            ax.imshow(self.cell_skeleton, interpolation='nearest')

            for i in fork_coordinates:
                c = plt.Circle((i[1], i[0]), 0.6, color='green')
                ax.add_patch(c)

            ax.set_axis_off()
            plt.tight_layout()
            plt.show()

        return num_forks
Exemple #3
0
    def refresh_seeds(self, n_trees=1) -> np.ndarray:
        """Fetch a new set of tip seeds from the current canvas."""
        new_seeds = list()
        logging.info("TipTracerSeedPolicy skeletonizing and extracting seeds")
        # Transform logits to probabilities, apply threshold, and skeletonize to
        # extract the locations of leaf nodes ("tips")
        c_t = expit(np.squeeze(self.canvas.seed))
        c_t = np.nan_to_num(c_t)
        c_t = (c_t >= self.skeletonization_threshold).astype(np.uint8)
        s_t = morphology.skeletonize(c_t)
        self._check_save_skeleton(s_t)
        g_t, c_t, _ = skeleton_to_csgraph(s_t)
        g_t = nx.from_scipy_sparse_matrix(g_t)
        # Get connected components and extract leaf nodes, sorting from large to small.
        subgraphs = sorted(nx.connected_components(g_t), key=len, reverse=True)
        for subgraph_nodes in subgraphs[:n_trees]:

            leaf_node_ids = [
                node_id for node_id, node_degree in g_t.degree(subgraph_nodes)
                if node_degree == 1
            ]
            # Produce a nested list of [y, x] coordinates of leaf nodes in this subgraph.
            leaf_node_yx = c_t[leaf_node_ids, :].astype(int).tolist()
            new_seeds.extend(leaf_node_yx)

        # Add z-coordinate to new_seeds and append to list of seed coords.
        new_seeds = np.hstack((np.zeros((len(new_seeds), 1),
                                        dtype=int), new_seeds,
                               np.full((len(new_seeds), 1),
                                       self.idx,
                                       dtype=int)))

        # Compute the unique union of existing coords and new seeds (do not re-seed in
        # locations which have already been seeded.

        coord_update = np.vstack((self.coords, new_seeds))
        coord_update = np.unique(coord_update, axis=0)
        coord_update = coord_update[np.argsort(coord_update[:, 3])]
        self.coords = coord_update
def bw_skel_and_analyze(bw):
    if bw.ndim == 3:
        skeleton = skeletonize_3d(bw)
    elif bw.ndim == 2:
        skeleton = skeletonize(bw)
    skeleton[skeleton > 0] = 1

    if skeleton.any() and np.count_nonzero(skeleton) > 1:
        try:
            pixel_graph, coordinates, degrees = skeleton_to_csgraph(skeleton)
            coordinates = coordinates[0::]  ### get rid of zero at beginning
        except:
            pixel_graph = np.zeros(np.shape(skeleton))
            coordinates = []
            degrees = np.zeros(np.shape(skeleton))
            print('error, could not skeletonize')
    else:
        pixel_graph = np.zeros(np.shape(skeleton))
        coordinates = []
        degrees = np.zeros(np.shape(skeleton))

    return pixel_graph, degrees, coordinates
Exemple #5
0
import pandas as pd

pd.set_option('display.max_columns', 10)
pd.set_option('display.width', 1000)

path = "C:/Users/Christian/Desktop/Third_CV/Complete_images/MitoSegNet/170412 MD4046 w1 next to vulva FL200.tif"
#path = "skeletonize_examples/5.tif"

# reads the image, converts from rgb to grayscale, converts to boolean array
image = img_as_bool(color.rgb2gray(io.imread(path)))
out = skeletonize(image).astype("uint8")

#print(type(out))
#io.imsave("test2.tif", out)

pixel_graph, coordinates, degrees = skeleton_to_csgraph(out)

branch_data = summarise(out)

print(branch_data)

grouped_branch_data_mean = branch_data.groupby(["skeleton-id"],
                                               as_index=False).mean()
grouped_branch_data_sum = branch_data.groupby(["skeleton-id"],
                                              as_index=False).sum()

sum_table = pd.DataFrame(columns=[
    "Number of branches", "Average branch length", "Total object length",
    "Average curvature index"
])
Exemple #6
0
    def classify_branching_structure(self, plot=False):
        def get_soma_node():
            near = []
            for i in range(skan.csr.Skeleton(self.cell_skeleton).n_paths):
                path_coords = skan.csr.Skeleton(
                    self.cell_skeleton).path_coordinates(i)
                nearest = min(
                    path_coords,
                    key=lambda x: self.distance(self.soma_on_skeleton, x))
                near.append(nearest)

            soma_on_path = min(
                near, key=lambda x: self.distance(self.soma_on_skeleton, x))

            for i, j in enumerate(
                    skan.csr.Skeleton(self.cell_skeleton).coordinates):
                if all(soma_on_path == j):
                    soma_node = [i]
                    break

            return soma_node

        def get_soma_branches(soma_node, paths_list):
            soma_branches = []
            for path in paths_list:
                # print(path)
                if soma_node in path:
                    soma_branches.append(path)
            return soma_branches

        pixel_graph, coordinates, degrees = skeleton_to_csgraph(
            self.cell_skeleton)
        branch_statistics = skan.csr.branch_statistics(pixel_graph)
        paths_list = skan.csr.Skeleton(self.cell_skeleton).paths_list()

        terminal_branches = []
        branching_structure_array = []
        # get branches containing soma node

        soma_node = get_soma_node()
        soma_branches = get_soma_branches(soma_node, paths_list)
        if len(soma_branches) > 2:
            junctions = soma_node
            delete_soma_branch = False
        else:
            # collect first level/primary branches
            junctions = [soma_branches[0][0], soma_branches[0][-1]]
            delete_soma_branch = True

        # eliminate loops in branches and path lists
        branch_statistics, paths_list = self.eliminate_loops(
            branch_statistics, paths_list)

        while True:
            junctions, branches, terminal_branch, branch_statistics = self.branch_structure(
                junctions, branch_statistics, paths_list)
            branching_structure_array.append(branches)
            terminal_branches.extend(terminal_branch)
            if len(junctions) == 0:
                break

        if delete_soma_branch == True:
            branching_structure_array[0].remove(soma_branches[0])

        if plot == True:
            # store same level branch nodes in single array
            color_branches_coords = []
            for branch_level in branching_structure_array:
                single_branch_level = []
                for path in branch_level:
                    path_coords = []
                    for node in path:
                        path_coords.append(coordinates[node])
                        single_branch_level.extend(path_coords)
                color_branches_coords.append(single_branch_level)

            fig, ax = plt.subplots(figsize=(4, 4))
            ax.set_title('path')
            ax.imshow(self.cell_skeleton, interpolation='nearest')

            color_codes = ['red', 'blue', 'magenta', 'green', 'cyan']
            for j, color_branch in enumerate(color_branches_coords):
                if j > 4:
                    j = 4
                for k in color_branch:
                    c = plt.Circle((k[1], k[0]), 0.5, color=color_codes[j])
                    ax.add_patch(c)

            ax.set_axis_off()
            plt.tight_layout()
            plt.show()

        self.branching_structure_array = branching_structure_array
        self.terminal_branches = terminal_branches
Exemple #7
0
def detect_peduncle(peduncle_img,
                    settings=None,
                    px_per_mm=None,
                    bg_img=None,
                    save=False,
                    name="",
                    pwd=""):
    if settings is None:
        settings = settings.detect_peduncle()

    if (bg_img is not None) and save:
        fig = plt.figure()
        plot_image(bg_img)
        save_fig(fig, pwd, name + "_00")

    if bg_img is None:
        bg_img = peduncle_img

    if px_per_mm:
        branch_length_min_px = px_per_mm * settings['branch_length_min_mm']
    else:
        branch_length_min_px = settings['branch_length_min_px']

    skeleton_img = skeletonize_img(peduncle_img)
    junc_coords, end_coords = get_node_coord(skeleton_img)

    if save:
        visualize_skeleton(bg_img,
                           skeleton_img,
                           coord_junc=junc_coords,
                           coord_end=end_coords,
                           name=name + "_01",
                           pwd=pwd)

    if save:
        fit_ransac(peduncle_img,
                   bg_img=bg_img.copy(),
                   save=True,
                   name=name + "_ransac",
                   pwd=pwd)

    # update_image = True
    # while update_image:
    skeleton_img, b_remove = threshold_branch_length(skeleton_img,
                                                     branch_length_min_px)
    # update_image = b_remove.any()
    junc_coords, end_coords = get_node_coord(skeleton_img)

    if save:
        visualize_skeleton(bg_img.copy(),
                           skeleton_img,
                           coord_junc=junc_coords,
                           coord_end=end_coords,
                           name=name + "_02",
                           pwd=pwd)

    graph, pixel_coordinates, degree_image = skan.skeleton_to_csgraph(
        skeleton_img, unique_junctions=True)
    dist, pred = csgraph.shortest_path(graph,
                                       directed=False,
                                       return_predecessors=True)

    end_nodes = coords_to_nodes(pixel_coordinates, end_coords[:, [1, 0]])
    junc_nodes = coords_to_nodes(pixel_coordinates, junc_coords[:, [1, 0]])

    path, path_length_px, branch_data = find_path(dist,
                                                  pred,
                                                  junc_nodes,
                                                  end_nodes,
                                                  pixel_coordinates,
                                                  bg_image=bg_img.copy(),
                                                  do_animate=False)

    branch_data = get_branch_center(branch_data, dist, pixel_coordinates,
                                    skeleton_img)

    path_img = path_mask(path, pixel_coordinates, skeleton_img.shape)
    junc_coords = pixel_coordinates[get_ids_on_path(path, pixel_coordinates,
                                                    junc_nodes)][:, [1, 0]]
    end_coords = pixel_coordinates[get_ids_on_path(path, pixel_coordinates,
                                                   end_nodes)][:, [1, 0]]

    end_coords = np.array([
        pixel_coordinates[path[0]][[1, 0]], pixel_coordinates[path[-1]][[1, 0]]
    ])

    # make sure that end nodes are not labeled as junctions
    if junc_coords.shape[0] != 0:
        for end_coord in end_coords:
            dst = distance(junc_coords, end_coord)
            mask = dst > 0.1
            junc_coords = junc_coords[mask]

    if save:
        visualize_skeleton(
            bg_img,
            path_img,
            coord_junc=
            junc_coords,  # junc_nodes=junc_nodes, end_nodes=end_nodes,
            coord_end=end_coords,
            name=name + "_03",
            pwd=pwd)

    if save:
        visualize_skeleton(bg_img,
                           path_img,
                           coord_junc=junc_coords,
                           branch_data=branch_data,
                           coord_end=end_coords,
                           name=name + "_04",
                           pwd=pwd)

    return path_img, branch_data, junc_coords, end_coords
Exemple #8
0
#h, w = imgb.shape[:2]
#imgb = cv2.resize(imgb,(h,h), interpolation=cv2.INTER_CUBIC)
pbef = Process(imgb)
pbef.lowp = np.array([150, 60, 100])
pbef.highp = np.array([170, 255, 255])
pbef.loww = np.array([90, 15, 150])
pbef.highw = np.array([115, 255, 255])
maskb = pbef.mask(kernel)
resb = pbef.res(maskb)
maskb = cv2.blur(maskb, (5, 5))

binaryb = maskb > filters.threshold_otsu(maskb)
skeletonb = morphology.skeletonize(binaryb)
fig, ax = plt.subplots()
draw.overlay_skeleton_2d(maskb, skeletonb, dilate=1, axes=ax)

#graphb = csgraph_from_masked(binaryb)
#plt.imshow(graphb)
gb, cb, db = skeleton_to_csgraph(skeletonb)
draw.overlay_skeleton_networkx(gb, cb, image=maskb)
branch_datab = summarize(Skeleton(skeletonb))
dfb = branch_datab.loc[branch_datab['branch-type'] == 1]

#dfb.to_csv(r'./before.csv')
draw.overlay_euclidean_skeleton_2d(maskb,
                                   branch_datab,
                                   skeleton_color_source='branch-type')

plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
Exemple #9
0
path = fileRoot + '/box/Sites/DeepVess/data/20200228/20200228__0001_z_dvSkel.tif'
dvSkel = tifffile.imread(path)
print('    dvSkel:', dvSkel.shape)

# convert the deepvess mask to a skeleton (same as deepves postprocess)
print('    making skeleton from binary stack dvMask ...')
# todo: fix this, older version need to use max_pool3d
#skeleton0 = morphology.skeletonize(dvMask)
startSeconds = time.time()
skeleton0 = morphology.skeletonize_3d(dvMask)
print('    skeleton0:', type(skeleton0), skeleton0.dtype, skeleton0.shape,
      np.min(skeleton0), np.max(skeleton0))
print('        took:', round(time.time() - startSeconds, 2), 'seconds')
#
# analysis of skeleton
pixel_graph, coordinates, degrees = skan.skeleton_to_csgraph(skeleton0)
print('    pixel_graph:', type(pixel_graph))
print('    coordinates:', type(coordinates),
      coordinates.shape)  # (n,3) each row is a point in skel
print('    degrees:', type(degrees), degrees.shape)

# make a list of coordinate[i] that are segment endpoints_src
nCoordinates = coordinates.shape[0]
slabs = coordinates.copy()  #np.full((nCoordinates,3), np.nan)
nodes = np.full((nCoordinates), np.nan)
nodeEdgeList = [[] for tmp in range(nCoordinates)]
edges = np.full((nCoordinates), np.nan)

print('degrees==0:', degrees[degrees == 0].shape)
print('degrees==1:', degrees[degrees == 1].shape)
print('degrees==2:', degrees[degrees == 2].shape)