def fit_ransac(peduncle_img, bg_img=None, save=False, name="", pwd=""):
    # skeletonize peduncle segment
    h, w = peduncle_img.shape

    mask_index = np.argwhere(peduncle_img)
    x = mask_index[:, 1].reshape(-1, 1)  # x, spould be 2D
    y = mask_index[:, 0]  # y

    # Robustly fit linear model with RANSAC algorithm
    mad_y = mad(y)
    ransac = linear_model.RANSACRegressor(max_trials=500,
                                          residual_threshold=0.8 * mad_y)
    ransac.fit(x, y)
    inlier_mask = ransac.inlier_mask_
    outlier_mask = np.logical_not(inlier_mask)

    i_remove = [y[outlier_mask], x[outlier_mask, 0]]
    peduncle_img[tuple(i_remove)] = 0

    #    skeleton_img = skeletonize_img(peduncle_img)
    #    skeleton = skan.Skeleton(skeleton_img)
    #
    #    # branch data
    #    for i, path in enumerate(skeleton.path_coordinates):
    #        px_coords = path.astype(int)

    if save:
        line_x = np.arange(x.min(), x.max())[:, np.newaxis]
        line_y = h - ransac.predict(line_x)

        fig = plt.figure()
        plt.scatter(x[inlier_mask],
                    h - y[inlier_mask],
                    color='yellowgreen',
                    marker='.',
                    label='Inliers')
        plt.scatter(x[outlier_mask],
                    h - y[outlier_mask],
                    color='gold',
                    marker='.',
                    label='Outliers')
        plt.plot(line_x,
                 line_y,
                 color='navy',
                 linewidth=2,
                 label='RANSAC regressor')
        plt.axis('equal')
        plt.legend(loc='lower right')
        plt.xlabel("Input")
        plt.ylabel("Response")

        if pwd is not None:
            save_fig(fig, pwd, name + "_00", title="RANSAC")
        plt.close(fig)

    return peduncle_img
Esempio n. 2
0
    def get_truss_visualization(self, local=False, save=False):
        pwd = os.path.join(self.pwd, '08_result')

        if local:
            frame_id = self.LOCAL_FRAME_ID
            shape = self.shape  # self.bbox[2:4]
            zoom = True
            name = 'local'
            skeleton_width = 4
            grasp_linewidth = 3
        else:
            frame_id = self.ORIGINAL_FRAME_ID
            shape = self.shape
            zoom = False
            name = 'original'
            skeleton_width = 2
            grasp_linewidth = 1

        grasp = self.get_grasp_location(local=local)
        tomato = self.get_tomatoes(local=local)
        xy_junc = coords_from_points(self.junction_points, frame_id)
        img = self.get_rgb(local=local)

        # generate peduncle image
        xy_peduncle = coords_from_points(self.peduncle_points, frame_id)
        rc_peduncle = np.around(np.array(xy_peduncle)).astype(np.int)[:,(1, 0)]
        arr = np.zeros(shape, dtype=np.uint8)
        arr[rc_peduncle[:, 0], rc_peduncle[:, 1]] = 1

        # plot
        plt.figure()
        plot_image(img)
        plot_features(tomato=tomato, zoom=zoom)
        visualize_skeleton(img, arr, coord_junc=xy_junc, show_img=False, skeleton_width=skeleton_width)

        if (grasp["xy"] is not None) and (grasp["angle"] is not None):
            settings = self.settings['compute_grasp']
            if self.px_per_mm is not None:
                minimum_grasp_length_px = self.px_per_mm * settings['grasp_length_min_mm']
                open_dist_px = settings['open_dist_mm'] * self.px_per_mm
                finger_thickenss_px = settings['finger_thinkness_mm'] * self.px_per_mm
            else:
                minimum_grasp_length_px = settings['grasp_length_min_px']
            plot_grasp_location(grasp["xy"], grasp["angle"], finger_width=minimum_grasp_length_px,
                                finger_thickness=finger_thickenss_px, finger_dist=open_dist_px, linewidth=grasp_linewidth)

        if save:
            if name is None:
                name = self.name
            else:
                name = self.name + '_' + name
            save_fig(plt.gcf(), pwd, name)

        return figure_to_image(plt.gcf())
Esempio n. 3
0
def a_hist(img_a,
           centers,
           lbl,
           bins=80,
           a_min=-1.0,
           a_max=1.0,
           name="",
           pwd=""):
    # plot Hue (HSV)
    fig, ax = plt.subplots(1)
    plt.yscale("log")

    center_background = centers[lbl["background"]]
    center_tomato = centers[lbl["tomato"]]
    center_peduncle = centers[lbl["peduncle"]]

    ax.axvline(x=center_background, color='b')
    ax.axvline(x=center_tomato, color='r')
    ax.axvline(x=center_peduncle, color='g')

    x0 = a_min
    x1 = (center_background + center_peduncle) / 2
    x2 = (center_peduncle + center_tomato) / 2
    x3 = a_max
    alpha = 0.2

    plt.axvspan(x0, x1, color='b', alpha=alpha, lw=0)
    plt.axvspan(x1, x2, color='g', alpha=alpha, lw=0)
    plt.axvspan(x2, x3, color='r', alpha=alpha, lw=0)

    angle = img_a.flatten()  # .astype('uint16')
    radii, bins, patches = ax.hist(angle,
                                   bins=bins,
                                   range=(a_min, a_max),
                                   color="black",
                                   lw=0)
    ax.set_xlabel("a")
    ax.set_ylabel("frequency")
    save_fig(fig, pwd, name + "_a_hist")  # , titleSize=10
Esempio n. 4
0
def hue_hist(img_hue, centers, lbl, name, pwd):
    # [-180, 180] => [0, 360]
    centers[centers < 0] += 360

    # plot Hue (HSV)
    fig, ax = plt.subplots(1)
    plt.yscale("log")

    center_background = centers[lbl["background"]]
    center_tomato = centers[lbl["tomato"]]
    center_peduncle = centers[lbl["peduncle"]]

    ax.axvline(x=center_background, color='b')
    ax.axvline(x=center_tomato, color='r')
    ax.axvline(x=center_peduncle, color='g')

    x0 = 0
    x1 = (center_tomato + center_peduncle) / 2
    x2 = (center_peduncle + center_background) / 2
    x3 = (center_background + center_tomato + 360) / 2
    x4 = 360
    alpha = 0.2

    plt.axvspan(x0, x1, color='r', alpha=alpha, lw=0)
    plt.axvspan(x1, x2, color='g', alpha=alpha, lw=0)
    plt.axvspan(x2, x3, color='b', alpha=alpha, lw=0)
    plt.axvspan(x3, x4, color='r', alpha=alpha, lw=0)

    bins = 180
    angle = img_hue.flatten().astype('uint16') * 2
    radii, bins, patches = ax.hist(angle,
                                   bins=bins,
                                   range=(0, 360),
                                   color="black",
                                   lw=0)
    ax.set_xlabel("hue [$^\circ$]")
    ax.set_ylabel("frequency")
    save_fig(fig, pwd, name + "_hue_hist")  # , titleSize=10
Esempio n. 5
0
def fit_ransac(peduncle_img, bg_img=None, save=False, name="", pwd=""):
    pend_color = np.array([0, 150, 30])
    stem_color = np.array([110, 255, 128])
    # skeletonize peduncle segment
    shape = peduncle_img.shape

    factor = 5
    mask_index = np.argwhere(peduncle_img)
    cols = mask_index[:, 1].reshape(-1, 1)  # x, spould be 2D
    rows = mask_index[:, 0]  # y

    i = range(0, len(rows), factor)
    fit_cols = cols[i]  # x, spould be 2D
    fit_rows = rows[i]  # y

    # Robustly fit linear model with RANSAC algorithm
    mad = mean_absolute_deviation(rows)
    residual_threshold = 0.8 * mad
    ransac = linear_model.RANSACRegressor(
        max_trials=1000, residual_threshold=residual_threshold)
    ransac.fit(fit_cols, fit_rows)

    # predict on full data set
    rows_pred = ransac.predict(cols)

    # idenitfy in and outliers
    data_train = np.stack((rows, cols[:, 0]), axis=1)
    data_pred = np.stack((rows_pred, cols[:, 0]), axis=1)
    dist = euclidean_distances(data_train, data_pred)
    inlier_mask = np.min(dist, axis=1) < residual_threshold
    outlier_mask = np.logical_not(inlier_mask)

    coord_inlier = [rows[inlier_mask], cols[inlier_mask, 0]]
    coord_outlier = [rows[outlier_mask], cols[outlier_mask, 0]]

    img_inlier = np.zeros(shape, dtype=np.uint8)
    img_outlier = np.zeros(shape, dtype=np.uint8)

    img_inlier[tuple(coord_inlier)] = 255
    img_outlier[tuple(coord_outlier)] = 255

    inlier_contours, hierarchy = cv2.findContours(img_inlier, cv2.RETR_TREE,
                                                  cv2.CHAIN_APPROX_SIMPLE)[-2:]
    outlier_contours, hierarchy = cv2.findContours(
        img_outlier, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:]

    fig = plt.figure()
    plot_image(bg_img)

    for contour in inlier_contours:
        plt.plot(contour[:, 0, 0],
                 contour[:, 0, 1],
                 linestyle='-',
                 linewidth=1,
                 color=pend_color.astype(float) / 255)
    for contour in outlier_contours:
        plt.plot(contour[:, 0, 0],
                 contour[:, 0, 1],
                 linestyle='-',
                 linewidth=1,
                 color=stem_color.astype(float) / 255)

    line_cols = np.arange(fit_cols.min(), fit_cols.max())[:, np.newaxis]
    line_rows = ransac.predict(line_cols)
    plt.plot(line_cols,
             line_rows,
             color='navy',
             linewidth=2,
             label='RANSAC regressor')
    plt.legend(loc='lower right')
    if pwd is not None:
        save_fig(fig, pwd, name, title="RANSAC")

    return img_inlier
Esempio n. 6
0
def visualize_skeleton(img,
                       skeleton_img,
                       skeletonize=False,
                       coord_junc=None,
                       coord_end=None,
                       junc_nodes=None,
                       end_nodes=None,
                       branch_data=None,
                       name="",
                       pwd=None,
                       show_nodes=True,
                       skeleton_color=None,
                       skeleton_width=4,
                       show_img=True):

    if skeleton_color is None:
        skeleton_color = (0, 150, 30)

    if skeletonize:
        skeleton_img = skeletonize_img(skeleton_img)

    if show_img:
        fig = plt.figure()
        plot_image(img)
    else:
        fig = plt.gcf()

    add_contour(skeleton_img,
                skeleton_color,
                linewidth=skeleton_width,
                zorder=6)

    if (len(np.argwhere(skeleton_img)) > 2) and show_nodes:

        if (coord_junc is None) and (coord_end is None):
            coord_junc, coord_end = get_node_coord(skeleton_img)

        if coord_junc is not None:
            add_circles(coord_junc,
                        radii=4,
                        fc=JUNC_COLOR,
                        linewidth=0,
                        zorder=7)

        if coord_end is not None:
            add_circles(coord_end,
                        radii=4,
                        fc=END_COLOR,
                        linewidth=0,
                        zorder=7)

    if branch_data:
        branch_center = {}
        branch_angle = {}
        for branch_type in branch_data:
            branch_center[branch_type] = []
            branch_angle[branch_type] = []
            for branch in branch_data[branch_type]:
                branch_center[branch_type].append(branch['center_node_coord'])
                branch_angle[branch_type].append(branch['angle'])

        add_arrows(branch_center['junction-junction'],
                   np.deg2rad(branch_angle['junction-junction']),
                   color=JUNC_COLOR,
                   linewidth=2)
        add_arrows(branch_center['junction-endpoint'],
                   np.deg2rad(branch_angle['junction-endpoint']),
                   color=END_COLOR,
                   linewidth=2)

    if (junc_nodes is not None) or (end_nodes is not None):
        if junc_nodes is not None:
            for junc_node, coord in zip(junc_nodes, coord_junc):
                plt.text(coord[0], coord[1], str(junc_node))

        if end_nodes is not None:
            for end_node, coord in zip(end_nodes, coord_end):
                plt.text(coord[0], coord[1], str(end_node))

    if pwd:
        save_fig(fig, pwd, name)
Esempio n. 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
Esempio n. 8
0
def both_hist(img_hue,
              img_a,
              centers,
              lbl,
              a_bins=80,
              pwd="",
              name="",
              hue_min=0,
              hue_max=180,
              hue_radius=1.0,
              a_min=-1.0,
              a_max=1.0,
              true_scale=False):
    a_height = 500
    if true_scale:
        hue_height = 2 * np.pi * hue_radius / 2 * a_height  # 180*scale
    else:
        hue_height = 2 * 500

    hue_step = float(hue_max - hue_min) / float(hue_height)
    a_step = float(a_max - a_min) / float(a_height)

    # label every possible location
    values_a, values_hue = np.mgrid[a_min:a_max:a_step,
                                    hue_min:hue_max:hue_step]
    shape = values_hue.shape
    labels = assign_labels(values_hue,
                           centers,
                           img_a=values_a,
                           hue_radius=hue_radius)
    tomato = label2img(labels, lbl["tomato"], shape)
    peduncle = label2img(labels, lbl["peduncle"], shape)
    background = label2img(labels, lbl["background"], shape)

    #
    hue_range = [0, 360]
    a_range = [a_min, a_max]
    my_range = [a_range, hue_range]
    x = img_a.flatten()
    y = img_hue.flatten().astype('uint16') * 2

    scale = 4.0
    hue_bins = 180 * scale
    a_bins = a_bins * scale

    hist, _, _, _ = plt.hist2d(x,
                               y,
                               range=my_range,
                               bins=[a_bins / scale, hue_bins / scale])
    hist[hist > 0] = np.log(hist[hist > 0])
    img_hist_gray = 255 - (hist / np.amax(hist) * 255).astype(np.uint8)
    img_hist_rgb = grey_2_rgb(
        img_hist_gray
    )  # (255*mapping.to_rgba(img_hist_gray)[:, :, 0:3]).astype(np.uint8)

    # rescale based on scala param
    new_shape = (shape[1], shape[0])  # [width, height]
    img_hist_rgb = cv2.resize(img_hist_rgb,
                              new_shape,
                              interpolation=cv2.INTER_NEAREST)

    # overlay with histogram
    plot_segments(img_hist_rgb,
                  background,
                  tomato,
                  peduncle,
                  show_background=True,
                  alpha=0.1,
                  linewidth=1,
                  show_axis=True,
                  use_image_colours=False,
                  ncols=2)

    # cmap = mpl.cm.hot_r
    # norm = mpl.colors.Normalize(vmin=0, vmax=100)
    # plt.gcf().colorbar(cm.ScalarMappable(norm=norm, cmap=cmap)) # ticks=['low', 'high'], format='%s'

    # plot cluster centers
    centers_hue = np.rad2deg(centers['hue'])
    centers_hue[centers_hue < 0] += 360
    hue_coords = (centers_hue / 2) / hue_step  # [rad]
    a_coords = (centers['a'] - a_min) / a_step

    for label in lbl:
        i = lbl[label]
        if label == 'tomato':
            color = 'r'
        elif label == 'peduncle':
            color = 'g'
        elif label == 'background':
            color = 'b'
        plt.plot(hue_coords[i],
                 a_coords[i],
                 'o',
                 color=color,
                 markeredgecolor='w',
                 markersize=4,
                 markeredgewidth=0.5,
                 alpha=1.0)

    # fix axis, only plot x axis for last image, only plot title for first
    # if name == final_image_id:
    plt.xticks([hue_min, hue_height / 2, hue_height - 1],
               map(str, (0, 180, 360)))
    plt.xlabel("hue [$^\circ$]")
    plt.title('K-means clustering result')
    # else:
    #     plt.xticks([])

    plt.ylabel("a*")
    plt.yticks([0, a_height / 2, a_height - 1],
               map(str, (a_min, (a_min + a_max) / 2, a_max)))

    if True:
        axs = plt.gcf().get_axes()
        plt.sca(axs[-1])
        cmap = mpl.cm.hot_r
        norm = mpl.colors.Normalize(vmin=0, vmax=100)
        cb1 = mpl.colorbar.ColorbarBase(plt.gca(),
                                        cmap=cmap,
                                        norm=norm,
                                        orientation='vertical')
        cb1.set_label('frequency', labelpad=-20)
        plt.yticks([])
        cb1.set_ticks([0, 100], True)
        plt.yticks([0, 100], ['low', 'high'])

    save_fig(plt.gcf(), pwd, name + "_hist", no_ticks=False)