def add_metric_plot(self,
                        plot_collection,
                        dataset_name,
                        metric,
                        fig_title="",
                        plot_title="",
                        metric_units=""):
        """ Adds a metric plot to a plot collection.

            Args:
                plot_collection: a PlotCollection containing plots.
                dataset_name: a string representing the name of the dataset being evaluated.
                metric: an evo.core.metric object with statistics and information.
                fig_title: a string representing the title of the figure. Must be unique in the plot_collection.
                plot_title: a string representing the title of the plot.
                metric_units: a string representing the units of the metric being plotted.
        """
        fig = plt.figure(figsize=(8, 8))
        stats = metric.get_all_statistics()

        plot.error_array(fig,
                         metric.error,
                         statistics=stats,
                         name=plot_title,
                         title=plot_title,
                         xlabel="Keyframe index [-]",
                         ylabel=plot_title + " " + metric_units)
        plot_collection.add_figure(fig_title, fig)
Пример #2
0
def plot(args, result, traj_ref, traj_est):
    from evo.tools import plot
    from evo.tools.settings import SETTINGS

    import matplotlib.pyplot as plt
    import numpy as np

    logger.debug(SEP)
    logger.debug("Plotting results... ")
    plot_mode = plot.PlotMode(args.plot_mode)

    # Plot the raw metric values.
    fig1 = plt.figure(figsize=SETTINGS.plot_figsize)
    if "seconds_from_start" in result.np_arrays:
        seconds_from_start = result.np_arrays["seconds_from_start"]
    else:
        seconds_from_start = None

    plot.error_array(
        fig1, result.np_arrays["error_array"], x_array=seconds_from_start,
        statistics={
            s: result.stats[s]
            for s in SETTINGS.plot_statistics if s not in ("min", "max")
        }, name=result.info["label"], title=result.info["title"],
        xlabel="$t$ (s)" if seconds_from_start else "index")

    # Plot the values color-mapped onto the trajectory.
    fig2 = plt.figure(figsize=SETTINGS.plot_figsize)
    ax = plot.prepare_axis(fig2, plot_mode)
    plot.traj(ax, plot_mode, traj_ref, style=SETTINGS.plot_reference_linestyle,
              color=SETTINGS.plot_reference_color, label='reference',
              alpha=SETTINGS.plot_reference_alpha)

    if args.plot_colormap_min is None:
        args.plot_colormap_min = result.stats["min"]
    if args.plot_colormap_max is None:
        args.plot_colormap_max = result.stats["max"]
    if args.plot_colormap_max_percentile is not None:
        args.plot_colormap_max = np.percentile(
            result.np_arrays["error_array"], args.plot_colormap_max_percentile)

    plot.traj_colormap(ax, traj_est, result.np_arrays["error_array"],
                       plot_mode, min_map=args.plot_colormap_min,
                       max_map=args.plot_colormap_max,
                       title="Error mapped onto trajectory")
    fig2.axes.append(ax)

    plot_collection = plot.PlotCollection(result.info["title"])
    plot_collection.add_figure("raw", fig1)
    plot_collection.add_figure("map", fig2)
    if args.plot:
        plot_collection.show()
    if args.save_plot:
        plot_collection.export(args.save_plot,
                               confirm_overwrite=not args.no_warnings)
    if args.serialize_plot:
        logger.debug(SEP)
        plot_collection.serialize(args.serialize_plot,
                                  confirm_overwrite=not args.no_warnings)
def plot_metric(metric, plot_title="", figsize=(8, 8)):
    """ Adds a metric plot to a plot collection.

        Args:
            plot_collection: a PlotCollection containing plots.
            metric: an evo.core.metric object with statistics and information.
            plot_title: a string representing the title of the plot.
            figsize: a 2-tuple representing the figure size.

        Returns:
            A plt figure.
    """
    fig = plt.figure(figsize=figsize)
    stats = metric.get_all_statistics()

    plot.error_array(fig,
                     metric.error,
                     statistics=stats,
                     title=plot_title,
                     xlabel="Keyframe index [-]",
                     ylabel=plot_title + " " + metric.unit.value)

    return fig
Пример #4
0
print("calculating APE")
data = (traj_ref, traj_est)
ape_metric = metrics.APE(metrics.PoseRelation.translation_part)
ape_metric.process_data(data)
ape_statistics = ape_metric.get_all_statistics()
print("mean:", ape_statistics["mean"])

print("loading plot modules")
from evo.tools import plot
import matplotlib.pyplot as plt

print("plotting")
plot_collection = plot.PlotCollection("Example")
# metric values
fig_1 = plt.figure(figsize=(8, 8))
plot.error_array(fig_1, ape_metric.error, statistics=ape_statistics,
                 name="APE", title=str(ape_metric))
plot_collection.add_figure("raw", fig_1)

# trajectory colormapped with error
fig_2 = plt.figure(figsize=(8, 8))
plot_mode = plot.PlotMode.xy
ax = plot.prepare_axis(fig_2, plot_mode)
plot.traj(ax, plot_mode, traj_ref, '--', 'gray', 'reference')
plot.traj_colormap(ax, traj_est, ape_metric.error, plot_mode,
                   min_map=ape_statistics["min"], max_map=ape_statistics["max"],
                   title="APE mapped onto trajectory")
plot_collection.add_figure("traj (error)", fig_2)

# trajectory colormapped with speed
fig_3 = plt.figure(figsize=(8, 8))
plot_mode = plot.PlotMode.xy
Пример #5
0
def main_ape(traj_ref,
             traj_est,
             pose_relation,
             align=True,
             correct_scale=False,
             ref_name="",
             est_name="",
             show_plot=False,
             save_plot=None,
             plot_mode=None,
             save_results=None,
             no_warnings=False,
             serialize_plot=None):

    from evo.algorithms import metrics
    from evo.algorithms import trajectory
    from evo.tools import file_interface
    from evo.tools.settings import SETTINGS

    only_scale = correct_scale and not align
    if align or correct_scale:
        logging.debug(SEP)
        if only_scale:
            logging.debug("correcting scale...")
        else:
            logging.debug("aligning using Umeyama's method..." + (
                " (with scale correction)" if correct_scale else ""))
        traj_est = trajectory.align_trajectory(traj_est, traj_ref,
                                               correct_scale, only_scale)
    logging.debug(SEP)

    # calculate APE
    data = (traj_ref, traj_est)
    ape_metric = metrics.APE(pose_relation)
    ape_metric.process_data(data)
    ape_statistics = ape_metric.get_all_statistics()

    title = str(ape_metric)
    if align and not correct_scale:
        title += "\n(with SE(3) Umeyama alignment)"
    elif align and correct_scale:
        title += "\n(with Sim(3) Umeyama alignment)"
    elif only_scale:
        title += "\n(scale corrected)"
    else:
        title += "\n(not aligned)"
    logging.debug(SEP)
    res_str = ""
    for name, val in sorted(ape_statistics.items()):
        res_str += "{:>10}".format(name) + "\t" + "{0:.6f}".format(val) + "\n"
    logging.info("\nstatistics of " + title + ":\n\n" + res_str)

    if show_plot or save_plot or save_results or serialize_plot:
        if isinstance(traj_est, trajectory.PoseTrajectory3D):
            seconds_from_start = [
                t - traj_est.timestamps[0] for t in traj_est.timestamps
            ]
        else:
            seconds_from_start = None

        if show_plot or save_plot or serialize_plot:
            from evo.tools import plot
            import matplotlib.pyplot as plt
            logging.debug(SEP)
            logging.debug("plotting results... ")
            fig1 = plt.figure(figsize=(SETTINGS.plot_figsize[0],
                                       SETTINGS.plot_figsize[1]))
            # metric values
            plot.error_array(
                fig1,
                ape_metric.error,
                x_array=seconds_from_start,
                statistics=ape_statistics,
                name="APE" + (" (" + ape_metric.unit.value + ")")
                if ape_metric.unit else "",
                title=title,
                xlabel="$t$ (s)" if seconds_from_start else "index")
            # info text
            if SETTINGS.plot_info_text and est_name and ref_name:
                ax = fig1.gca()
                ax.text(0,
                        -0.12,
                        "estimate:  " + est_name + "\nreference: " + ref_name,
                        transform=ax.transAxes,
                        fontsize=8,
                        color="gray")
            # trajectory colormapped
            fig2 = plt.figure(figsize=(SETTINGS.plot_figsize[0],
                                       SETTINGS.plot_figsize[1]))
            plot_mode = plot_mode if plot_mode is not None else plot.PlotMode.xyz
            ax = plot.prepare_axis(fig2, plot_mode)
            plot.traj(ax,
                      plot_mode,
                      traj_ref,
                      '--',
                      'gray',
                      'reference',
                      alpha=0.0 if SETTINGS.plot_hideref else 1.0)
            plot.traj_colormap(ax,
                               traj_est,
                               ape_metric.error,
                               plot_mode,
                               min_map=ape_statistics["min"],
                               max_map=ape_statistics["max"],
                               title="APE mapped onto trajectory")
            fig2.axes.append(ax)
            plot_collection = plot.PlotCollection(title)
            plot_collection.add_figure("raw", fig1)
            plot_collection.add_figure("map", fig2)
            if show_plot:
                plot_collection.show()
            if save_plot:
                plot_collection.export(save_plot,
                                       confirm_overwrite=not no_warnings)
            if serialize_plot:
                logging.debug(SEP)
                plot_collection.serialize(serialize_plot,
                                          confirm_overwrite=not no_warnings)

        if save_results:
            logging.debug(SEP)
            file_interface.save_res_file(save_results,
                                         ape_metric,
                                         ape_statistics,
                                         title,
                                         ref_name,
                                         est_name,
                                         seconds_from_start,
                                         traj_ref,
                                         traj_est,
                                         confirm_overwrite=not no_warnings)

    return ape_statistics, ape_metric.error
Пример #6
0
def get_and_save_results_from_folder(folder_with_predicted_poses,category):
    
    global args
    global kitti_eval_tool
    global folder_with_gt_poses
    global output_folder
    global t
    global results
    
    values_for_excel = []
    columns_for_excel = []
    type_of_statistics = 'mean'
    for filename in sorted(os.listdir(folder_with_predicted_poses)):
        if not(os.path.exists(os.path.join(folder_with_gt_poses, filename))):
            print("file with gt poses doesn't exist for "+filename)
            continue
        if filename.find('.txt') == -1:
            continue
        seq_results = {}
        seq_results['name_seq'] = filename[:filename.rfind('.')]
        seq_results['category'] = category
        folder_name = seq_results['category']
        seq_results['metrics'] = {}
        seq_results['lost'] = False
        
        os.makedirs(os.path.join(output_folder, folder_name), exist_ok=True)
        output_folder_seq = os.path.join(output_folder, folder_name, filename[:filename.rfind('.')])
        os.makedirs(output_folder_seq, exist_ok=True)
        if os.path.isfile(os.path.join(output_folder, folder_name,"results.txt")):
            file_results_txt = open(os.path.join(output_folder, folder_name,"results.txt"), "a")
        else:
            file_results_txt = open(os.path.join(output_folder, folder_name,"results.txt"), "w")
            file_results_txt.write("translation_error(%) rotation_error(deg/m) ATE(m) APE_translation_error_median(m) APE_rotation_error_median(deg) dst_to_trgt\n")
        
        # -------------------------------------Getting results---------------------------------------------------
        if args.gt_format == 'kitti':        
            traj_ref = file_interface.read_kitti_poses_file(os.path.join(folder_with_gt_poses, filename))
        if args.gt_format == 'tum':        
            traj_ref = file_interface.read_tum_trajectory_file(os.path.join(folder_with_gt_poses, filename))
            seq_results["length_of_ref_traj"] = traj_ref.path_length
            end_time_gt = traj_ref.get_infos()["t_end (s)"]
        if args.gt_format == 'euroc':        
            traj_ref = file_interface.read_euroc_csv_trajectory(os.path.join(folder_with_gt_poses, filename))
        if args.result_format == 'kitti':
            traj_est = file_interface.read_kitti_poses_file(os.path.join(folder_with_predicted_poses, filename))
        if args.result_format == 'tum':
            traj_est = file_interface.read_tum_trajectory_file(os.path.join(folder_with_predicted_poses, filename))
            seq_results["length_of_estimated_traj"] = traj_est.path_length
        if args.result_format == 'euroc':
            traj_est = file_interface.read_euroc_csv_trajectory(os.path.join(folder_with_predicted_poses, filename))
        if args.result_format == 'tum' and args.gt_format == 'tum':
            seq_results["num_gt_poses"] = traj_ref.num_poses
            seq_results["num_predicted_poses"] = traj_est.num_poses
            traj_ref, traj_est = sync.associate_trajectories(traj_ref, traj_est, args.max_diff)
            end_time_est = traj_est.get_infos()["t_end (s)"]
            if (abs(end_time_est - end_time_gt) > 0.2) or (traj_est.get_infos()["t_start (s)"] > 0.2):
                print('LOST in track '+filename[:filename.rfind('.')])
                seq_results['lost'] = True
                results.append(seq_results)
                t.update(1)
                continue
        if args.alignment != None:
            traj_est = trajectory.align_trajectory(traj_est, traj_ref, correct_scale=args.alignment.find("scale") != -1, correct_only_scale=args.alignment=="scale")
        trajectory.align_trajectory_origin(traj_est, traj_ref)
        data = (traj_ref, traj_est)
        
        ape_metric_translation = metrics.APE(metrics.PoseRelation.translation_part)
        ape_metric_rotation = metrics.APE(metrics.PoseRelation.rotation_angle_deg)
        ape_metric_translation.process_data(data)
        ape_metric_rotation.process_data(data)
        ape_translation_statistics = ape_metric_translation.get_all_statistics()
        ape_rotation_statistics = ape_metric_rotation.get_all_statistics()
        
        ape_translation_statistics_plot = copy.deepcopy(ape_translation_statistics)
        ape_rotation_statistics_plot = copy.deepcopy(ape_rotation_statistics)
        ape_translation_statistics_plot.pop('sse')
        ape_translation_statistics_plot.pop('std')
        ape_translation_statistics_plot.pop('min')
        ape_translation_statistics_plot.pop('max')
        ape_rotation_statistics_plot.pop('sse')
        ape_rotation_statistics_plot.pop('std')
        ape_rotation_statistics_plot.pop('min')
        ape_rotation_statistics_plot.pop('max')
        
        kitti_trans_err, kitti_rot_err, ate = kitti_eval_tool.eval(traj_ref.poses_se3, 
                                                               traj_est.poses_se3, 
                                                               alignment=None)
    
        #---------------------------------adding results to variable seq_results for excel -----------------------------
        seq_results['metrics']['dist_to_trgt'] = traj_est.get_infos()['pos_end (m)'] - traj_ref.get_infos()['pos_end (m)']
        seq_results['metrics']['dist_to_trgt'] = np.sum(np.array(seq_results['metrics']['dist_to_trgt'])**2)**0.5
        seq_results['metrics']["Kitti trans err (%)"] = kitti_trans_err
        seq_results['metrics']["Kitti rot err (deg/m)"] = kitti_rot_err
        seq_results['metrics']["ATE (m)"] = ate
        seq_results['metrics']["APE(trans err) median (m)"] = ape_translation_statistics["median"]
        seq_results['metrics']["APE(rot err) median (deg)"] = ape_rotation_statistics["median"]
        #--------------------------------------------------------------------------------------------------------
        
        
        #-------------------------------------------------------------------------------------------------------    
    
        # --------------------------------printing results into console----------------------------------------------
        print('Results for "'+filename+'":')
        print('Kitti average translational error (%): {:.7f}'.format(kitti_trans_err))
        print('Kitti average rotational error (deg/m): {:.7f}'.format(kitti_rot_err))
        print('ATE (m): {:.7f}'.format(ate))
        print('APE(translation error) median (m): {:.7f}'.format(ape_translation_statistics["median"]))
        print('APE(rotation error) median (deg): {:.7f}'.format(ape_rotation_statistics["median"]))
        print('distance to target on the last frame: {:.7f}'.format(seq_results['metrics']['dist_to_trgt']))
        #------------------------------------------------------------------------------------------------------------
        
        #---------------------------------Saving results into overall results text file------------------------------
        file_results_txt.write('{:<24} '.format(filename[:filename.rfind('.')]))
        file_results_txt.write('{:>7.4f} '.format(kitti_trans_err))
        file_results_txt.write('{:>7.4f} '.format(kitti_rot_err))
        file_results_txt.write('{:>7.4f} '.format(ate))
        file_results_txt.write('{:>7.4f} '.format(ape_translation_statistics["median"]))
        file_results_txt.write('{:>7.4f} '.format(ape_rotation_statistics["median"]))
        file_results_txt.write('{:>7.4f}\n'.format(seq_results['metrics']['dist_to_trgt']))
        #------------------------------------------------------------------------------------------------------------
    
        # --------------------------------Saving metrics to text file for one track----------------------------------
        txt_filename = filename[:filename.rfind('.')]+"_metrics.txt"
        with open(os.path.join(output_folder_seq, txt_filename), "w") as txt_file:
            txt_file.write('Kitti average translational error (%): {:.7f}\n'.format(kitti_trans_err))
            txt_file.write('Kitti average rotational error (deg/m): {:.7f}\n'.format(kitti_rot_err))
            txt_file.write('ATE (m): {:.7f}\n'.format(ate))
            txt_file.write('APE(translation error) median (m): {:.7f}\n'.format(ape_translation_statistics["median"]))
            txt_file.write('APE(rotation error) median (deg): {:.7f}\n'.format(ape_rotation_statistics["median"]))
            txt_file.write('Distance to target on the last frame: {:.7f}\n'.format(seq_results['metrics']['dist_to_trgt']))
        #---------------------------------------------------------------------------------------------------------
    
        # ---------------------------------Saving values of errors for each frame to text file------------------------
        # ------------------------------------------for translation errors----------------------------------------
        txt_filename = filename[:filename.rfind('.')]+"_APE(translation)_errors.txt"
        output_folder_seq_translation = os.path.join(output_folder_seq,"translation")
        output_folder_seq_rotation = os.path.join(output_folder_seq,"rotation")
        os.makedirs(output_folder_seq_translation, exist_ok=True)
        os.makedirs(output_folder_seq_rotation, exist_ok=True)
        with open(os.path.join(output_folder_seq_translation, txt_filename), "w") as txt_file:
            for error in ape_metric_translation.error:
                txt_file.write('{:.10f}\n'.format(error))
        # -----------------------------------------for rotation degree errors--------------------------------------
        txt_filename = filename[:filename.rfind('.')]+"_APE(rotation_deg)_errors.txt"
        with open(os.path.join(output_folder_seq_rotation, txt_filename), "w") as txt_file:
            for error in ape_metric_rotation.error:
                txt_file.write('{:.10f}\n'.format(error))
        #----------------------------------------------------------------------------------------------------------
            
        # ---------------------------------------Saving plot of errors of each frame------------------------------
        # ------------------------------------------for translation errors----------------------------------------
        plot_collection = plot.PlotCollection("Example")
        fig_1 = plt.figure(figsize=(8, 8))
        plot.error_array(fig_1, ape_metric_translation.error, 
                         name="APE", title=str(ape_metric_translation), xlabel="Index of frame", ylabel='Error')
        plot_collection.add_figure("raw", fig_1)
        plot_filename = filename[:filename.rfind('.')]+"_APE(translation)_errors.png"
        plt.savefig(os.path.join(output_folder_seq_translation, plot_filename))
        plt.close(fig_1)
        # -----------------------------------------for rotation degree errors--------------------------------------
        plot_collection = plot.PlotCollection("Example")
        fig_1 = plt.figure(figsize=(8, 8))
        plot.error_array(fig_1, ape_metric_rotation.error, 
                         name="APE", title=str(ape_metric_rotation), xlabel="Index of frame", ylabel='Error')
        plot_collection.add_figure("raw", fig_1)
        plot_filename = filename[:filename.rfind('.')]+"_APE(rotation)_errors.png"
        plt.savefig(os.path.join(output_folder_seq_rotation,plot_filename))
        plt.close(fig_1)
        #-----------------------------------------------------------------------------------------------------------
    
        # -----------------------------------------Saving trajectory plot------------------------------------------- 
        # ------------------------------------------for translation errors----------------------------------------
        fig_2 = plt.figure(figsize=(8, 8))
        ax = plot.prepare_axis(fig_2, plot_mode)
        plot.traj(ax, plot_mode, traj_ref, '--', 'gray', 'reference')
        plot.traj_colormap( ax, traj_est, ape_metric_translation.error, plot_mode, 
                           min_map=ape_translation_statistics["min"],
                           max_map=ape_translation_statistics["max"], title="APE translation mapped onto trajectory")
        plot_collection.add_figure("traj (error)", fig_2)
        plot_filename = filename[:filename.rfind('.')]+"_APE(translation)_map.png"
        plt.savefig(os.path.join(output_folder_seq_translation,plot_filename))
        plt.close(fig_2)
        # -----------------------------------------for rotation degree errors--------------------------------------
        fig_2 = plt.figure(figsize=(8, 8))
        ax = plot.prepare_axis(fig_2, plot_mode)
        plot.traj(ax, plot_mode, traj_ref, '--', 'gray', 'reference')
        plot.traj_colormap( ax, traj_est, ape_metric_rotation.error, plot_mode, 
                           min_map=ape_rotation_statistics["min"],
                           max_map=ape_rotation_statistics["max"], title="APE rotation mapped onto trajectory")
        plot_collection.add_figure("traj (error)", fig_2)
        plot_filename = filename[:filename.rfind('.')]+"_APE(rotation)_map.png"
        plt.savefig(os.path.join(output_folder_seq_rotation,plot_filename))
        plt.close(fig_2)
        #-----------------------------------------------------------------------------------------------------------
        print()
        
        active_worksheet = wb['sheet1']
        thin = Side(border_style="thin", color="000000")
        thick = Side(border_style="thick", color="000000")
        medium = Side(border_style="medium", color="000000")
        font_header = Font(name='Arial',
                       size=10,
                       bold=True,
                       italic=False,
                       vertAlign=None,
                       underline='none',
                       strike=False,
                       color='FF000000')
        font_values = Font(name='Arial',
                       size=10,
                       bold=False,
                       italic=False,
                       vertAlign=None,
                               underline='none',
                       strike=False,
                       color='FF000000')

        active_worksheet.row_dimensions[2].height = 35
        
        file_results_txt.close()
        results.append(seq_results)
        t.update(1)
Пример #7
0
ape_metric = metrics.APE(metrics.PoseRelation.translation_part)
ape_metric.process_data(data)
ape_statistics = ape_metric.get_all_statistics()
print("mean:", ape_statistics["mean"])

print("loading plot modules")
from evo.tools import plot
import matplotlib.pyplot as plt

print("plotting")
plot_collection = plot.PlotCollection("Example")
# metric values
fig_1 = plt.figure(figsize=(8, 8))
plot.error_array(fig_1,
                 ape_metric.error,
                 statistics=ape_statistics,
                 name="APE",
                 title=str(ape_metric))
plot_collection.add_figure("raw", fig_1)

# trajectory colormapped with error
fig_2 = plt.figure(figsize=(8, 8))
plot_mode = plot.PlotMode.xy
ax = plot.prepare_axis(fig_2, plot_mode)
plot.traj(ax, plot_mode, traj_ref, '--', 'gray', 'reference')
plot.traj_colormap(ax,
                   traj_est,
                   ape_metric.error,
                   plot_mode,
                   min_map=ape_statistics["min"],
                   max_map=ape_statistics["max"],
Пример #8
0
def plot_result(args: argparse.Namespace,
                result: Result,
                traj_ref: PosePath3D,
                traj_est: PosePath3D,
                traj_ref_full: typing.Optional[PosePath3D] = None) -> None:
    from evo.tools import plot
    from evo.tools.settings import SETTINGS

    import matplotlib.pyplot as plt
    import numpy as np

    logger.debug(SEP)
    logger.debug("Plotting results... ")
    plot_mode = plot.PlotMode(args.plot_mode)

    # Plot the raw metric values.
    fig1 = plt.figure(figsize=SETTINGS.plot_figsize)
    if "seconds_from_start" in result.np_arrays:
        seconds_from_start = result.np_arrays["seconds_from_start"]
    else:
        seconds_from_start = None

    plot.error_array(
        fig1.gca(),
        result.np_arrays["error_array"],
        x_array=seconds_from_start,
        statistics={
            s: result.stats[s]
            for s in SETTINGS.plot_statistics if s not in ("min", "max")
        },
        name=result.info["label"],
        title=result.info["title"],
        xlabel="$t$ (s)" if seconds_from_start is not None else "index")

    # Plot the values color-mapped onto the trajectory.
    fig2 = plt.figure(figsize=SETTINGS.plot_figsize)
    ax = plot.prepare_axis(fig2, plot_mode)
    if args.ros_map_yaml:
        plot.ros_map(ax, args.ros_map_yaml, plot_mode)

    plot.traj(ax,
              plot_mode,
              traj_ref_full if traj_ref_full else traj_ref,
              style=SETTINGS.plot_reference_linestyle,
              color=SETTINGS.plot_reference_color,
              label='reference',
              alpha=SETTINGS.plot_reference_alpha)
    plot.draw_coordinate_axes(ax, traj_ref, plot_mode,
                              SETTINGS.plot_axis_marker_scale)

    if args.plot_colormap_min is None:
        args.plot_colormap_min = result.stats["min"]
    if args.plot_colormap_max is None:
        args.plot_colormap_max = result.stats["max"]
    if args.plot_colormap_max_percentile is not None:
        args.plot_colormap_max = np.percentile(
            result.np_arrays["error_array"], args.plot_colormap_max_percentile)

    plot.traj_colormap(ax,
                       traj_est,
                       result.np_arrays["error_array"],
                       plot_mode,
                       min_map=args.plot_colormap_min,
                       max_map=args.plot_colormap_max,
                       title="Error mapped onto trajectory")
    plot.draw_coordinate_axes(ax, traj_est, plot_mode,
                              SETTINGS.plot_axis_marker_scale)
    if SETTINGS.plot_pose_correspondences:
        plot.draw_correspondence_edges(
            ax,
            traj_est,
            traj_ref,
            plot_mode,
            style=SETTINGS.plot_pose_correspondences_linestyle,
            color=SETTINGS.plot_reference_color,
            alpha=SETTINGS.plot_reference_alpha)
    fig2.axes.append(ax)

    plot_collection = plot.PlotCollection(result.info["title"])
    plot_collection.add_figure("raw", fig1)
    plot_collection.add_figure("map", fig2)
    if args.plot:
        plot_collection.show()
    if args.save_plot:
        plot_collection.export(args.save_plot,
                               confirm_overwrite=not args.no_warnings)
    if args.serialize_plot:
        logger.debug(SEP)
        plot_collection.serialize(args.serialize_plot,
                                  confirm_overwrite=not args.no_warnings)
Пример #9
0
def main_rpe_for_each(traj_ref,
                      traj_est,
                      pose_relation,
                      mode,
                      bins,
                      rel_tols,
                      align=False,
                      correct_scale=False,
                      ref_name="",
                      est_name="",
                      show_plot=False,
                      save_plot=None,
                      save_results=None,
                      no_warnings=False,
                      serialize_plot=None):

    from evo.algorithms import metrics
    from evo.algorithms import filters
    from evo.algorithms import trajectory
    from evo.tools import file_interface
    from evo.tools.settings import SETTINGS

    if not bins or not rel_tols:
        raise RuntimeError(
            "bins and tolerances must have more than one element")
    if len(bins) != len(rel_tols):
        raise RuntimeError(
            "bins and tolerances must have the same number of elements")
    if mode in {"speed", "angular_speed"
                } and traj_est is trajectory.PosePath3D:
        raise RuntimeError("timestamps are required for mode: " + mode)

    bin_unit = None
    if mode == "speed":
        bin_unit = metrics.VelUnit.meters_per_sec
    elif mode == "path":
        bin_unit = metrics.Unit.meters
    elif mode == "angle":
        bin_unit = metrics.Unit.degrees
    elif mode == "angular_speed":
        bin_unit = metrics.VelUnit.degrees_per_sec

    rpe_unit = None
    if pose_relation is metrics.PoseRelation.translation_part:
        rpe_unit = metrics.Unit.meters
    elif pose_relation is metrics.PoseRelation.rotation_angle_deg:
        rpe_unit = metrics.Unit.degrees
    elif pose_relation is metrics.PoseRelation.rotation_angle_rad:
        rpe_unit = metrics.Unit.radians

    correct_only_scale = correct_scale and not align
    if align or correct_scale:
        logging.debug(SEP)
        if correct_only_scale:
            logging.debug("correcting scale...")
        else:
            logging.debug("aligning using Umeyama's method..." + (
                " (with scale correction)" if correct_scale else ""))
        traj_est = trajectory.align_trajectory(traj_est, traj_ref,
                                               correct_scale,
                                               correct_only_scale)

    results = []
    for bin, rel_tol, in zip(bins, rel_tols):
        logging.debug(SEP)
        logging.info("calculating RPE for each sub-sequence of " + str(bin) +
                     " (" + bin_unit.value + ")")

        tol = bin * rel_tol
        id_pairs = []
        if mode == "path":
            id_pairs = filters.filter_pairs_by_path(traj_ref.poses_se3,
                                                    bin,
                                                    tol,
                                                    all_pairs=True)
        elif mode == "angle":
            id_pairs = filters.filter_pairs_by_angle(traj_ref.poses_se3,
                                                     bin,
                                                     tol,
                                                     degrees=True)
        elif mode == "speed":
            id_pairs = filters.filter_pairs_by_speed(traj_ref.poses_se3,
                                                     traj_ref.timestamps, bin,
                                                     tol)
        elif mode == "angular_speed":
            id_pairs = filters.filter_pairs_by_angular_speed(
                traj_ref.poses_se3, traj_ref.timestamps, bin, tol, True)

        if len(id_pairs) == 0:
            raise RuntimeError("bin " + str(bin) + " (" + str(bin_unit.value) +
                               ") " +
                               "produced empty index list - try other values")

        # calculate RPE with all IDs (delta 1 frames)
        data = (traj_ref, traj_est)
        # the delta here has nothing to do with the bin - 1f delta just to use all poses of the bin
        rpe_metric = metrics.RPE(pose_relation,
                                 delta=1,
                                 delta_unit=metrics.Unit.frames,
                                 all_pairs=True)
        rpe_metric.process_data(data, id_pairs)
        mean = rpe_metric.get_statistic(metrics.StatisticsType.mean)
        results.append(mean)

    if SETTINGS.plot_usetex:
        mode.replace("_", "\_")
    title = "mean RPE w.r.t. " + pose_relation.value + "\nfor different " + mode + " sub-sequences"
    if align and not correct_scale:
        title += "\n(with SE(3) Umeyama alignment)"
    elif align and correct_scale:
        title += "\n(with Sim(3) Umeyama alignment)"
    elif correct_only_scale:
        title += "\n(scale corrected)"
    else:
        title += "\n(not aligned)"
    logging.debug(SEP)
    logging.info("\n" + title + "\n")
    res_str = ""
    for bin, result in zip(bins, results):
        res_str += "{:>10}".format(str(bin) + "(" + bin_unit.value + ")")
        res_str += "\t" + "{0:.6f}".format(result) + "\n"
    logging.info(res_str)

    if show_plot or save_plot or serialize_plot:
        from evo.tools import plot
        import matplotlib.pyplot as plt
        plot_collection = plot.PlotCollection(title)
        fig = plt.figure(figsize=(SETTINGS.plot_figsize[0],
                                  SETTINGS.plot_figsize[1]))
        plot.error_array(fig,
                         results,
                         x_array=bins,
                         name="mean RPE" +
                         (" (" + rpe_unit.value + ")") if rpe_unit else "",
                         marker="o",
                         title=title,
                         xlabel=mode + " sub-sequences " + " (" +
                         bin_unit.value + ")")
        # info text
        if SETTINGS.plot_info_text and est_name and ref_name:
            ax = fig.gca()
            ax.text(0,
                    -0.12,
                    "estimate:  " + est_name + "\nreference: " + ref_name,
                    transform=ax.transAxes,
                    fontsize=8,
                    color="gray")
        plt.title(title)
        plot_collection.add_figure("raw", fig)
        if show_plot:
            plot_collection.show()
        if save_plot:
            plot_collection.export(save_plot,
                                   confirm_overwrite=not no_warnings)
        if serialize_plot:
            logging.debug(SEP)
            plot_collection.serialize(serialize_plot,
                                      confirm_overwrite=not no_warnings)

    rpe_statistics = {bin: result for bin, result in zip(bins, results)}
    if save_results:
        logging.debug(SEP)

        # utility class to trick save_res_file
        class Metric:
            unit = rpe_unit
            error = results

        file_interface.save_res_file(save_results,
                                     Metric,
                                     rpe_statistics,
                                     title,
                                     ref_name,
                                     est_name,
                                     bins,
                                     traj_ref,
                                     traj_est,
                                     xlabel=mode + " sub-sequences " + " (" +
                                     bin_unit.value + ")",
                                     confirm_overwrite=not no_warnings)

    return rpe_statistics, results
Пример #10
0
def main_rpe(traj_ref,
             traj_est,
             pose_relation,
             delta,
             delta_unit,
             rel_delta_tol=0.1,
             all_pairs=False,
             align=False,
             correct_scale=False,
             ref_name="",
             est_name="",
             show_plot=False,
             save_plot=None,
             plot_mode=None,
             save_results=None,
             no_warnings=False,
             support_loop=False,
             serialize_plot=None):

    from evo.core import metrics, result
    from evo.core import trajectory
    from evo.tools import file_interface
    from evo.tools.settings import SETTINGS

    if (show_plot or save_plot or serialize_plot) and all_pairs:
        raise metrics.MetricsException(
            "all_pairs mode cannot be used with plotting functions")

    only_scale = correct_scale and not align
    if align or correct_scale:
        logging.debug(SEP)
        if only_scale:
            logging.debug("correcting scale...")
        else:
            logging.debug("aligning using Umeyama's method..." + (
                " (with scale correction)" if correct_scale else ""))
        traj_est = trajectory.align_trajectory(traj_est, traj_ref,
                                               correct_scale, only_scale)
    logging.debug(SEP)

    # calculate RPE
    data = (traj_ref, traj_est)
    rpe_metric = metrics.RPE(pose_relation, delta, delta_unit, rel_delta_tol,
                             all_pairs)
    rpe_metric.process_data(data)
    rpe_statistics = rpe_metric.get_all_statistics()

    title = str(rpe_metric)
    if align and not correct_scale:
        title += "\n(with SE(3) Umeyama alignment)"
    elif align and correct_scale:
        title += "\n(with Sim(3) Umeyama alignment)"
    elif only_scale:
        title += "\n(scale corrected)"
    else:
        title += "\n(not aligned)"

    rpe_result = result.from_metric(rpe_metric, title, ref_name, est_name)
    logging.debug(SEP)
    logging.info(rpe_result.pretty_str())

    # restrict trajectories to delta ids
    if support_loop:
        # avoid overwriting if called repeatedly e.g. in Jupyter notebook
        import copy
        traj_ref = copy.deepcopy(traj_ref)
        traj_est = copy.deepcopy(traj_est)
    traj_ref.reduce_to_ids(rpe_metric.delta_ids)
    traj_est.reduce_to_ids(rpe_metric.delta_ids)
    if isinstance(traj_est, trajectory.PoseTrajectory3D) and not all_pairs:
        seconds_from_start = [
            t - traj_est.timestamps[0] for t in traj_est.timestamps
        ]
        rpe_result.add_np_array("seconds_from_start", seconds_from_start)
    else:
        seconds_from_start = None

    if show_plot or save_plot or serialize_plot and not all_pairs:
        from evo.tools import plot
        import matplotlib.pyplot as plt
        logging.debug(SEP)
        logging.debug("plotting results... ")
        fig1 = plt.figure(figsize=(SETTINGS.plot_figsize[0],
                                   SETTINGS.plot_figsize[1]))
        # metric values
        plot.error_array(
            fig1,
            rpe_metric.error,
            x_array=seconds_from_start,
            statistics=rpe_statistics,
            name="RPE" +
            (" (" + rpe_metric.unit.value + ")") if rpe_metric.unit else "",
            title=title,
            xlabel="$t$ (s)" if seconds_from_start else "index")
        # info text
        if SETTINGS.plot_info_text and est_name and ref_name:
            ax = fig1.gca()
            ax.text(0,
                    -0.12,
                    "estimate:  " + est_name + "\nreference: " + ref_name,
                    transform=ax.transAxes,
                    fontsize=8,
                    color="gray")
        # trajectory colormapped
        fig2 = plt.figure(figsize=(SETTINGS.plot_figsize[0],
                                   SETTINGS.plot_figsize[1]))
        plot_mode = plot_mode if plot_mode is not None else plot.PlotMode.xyz
        ax = plot.prepare_axis(fig2, plot_mode)
        plot.traj(ax,
                  plot_mode,
                  traj_ref,
                  '--',
                  'gray',
                  'reference',
                  alpha=0 if SETTINGS.plot_hideref else 1)
        plot.traj_colormap(ax,
                           traj_est,
                           rpe_metric.error,
                           plot_mode,
                           min_map=rpe_statistics["min"],
                           max_map=rpe_statistics["max"],
                           title="RPE mapped onto trajectory")
        fig2.axes.append(ax)
        plot_collection = plot.PlotCollection(title)
        plot_collection.add_figure("raw", fig1)
        plot_collection.add_figure("map", fig2)
        if show_plot:
            plot_collection.show()
        if save_plot:
            plot_collection.export(save_plot,
                                   confirm_overwrite=not no_warnings)
        if serialize_plot:
            logging.debug(SEP)
            plot_collection.serialize(serialize_plot,
                                      confirm_overwrite=not no_warnings)

    if save_results:
        logging.debug(SEP)
        if SETTINGS.save_traj_in_zip:
            rpe_result.add_trajectory("traj_ref", traj_ref)
            rpe_result.add_trajectory("traj_est", traj_est)
        file_interface.save_res_file(save_results,
                                     rpe_result,
                                     confirm_overwrite=not no_warnings)

    return rpe_result
Пример #11
0
def plot_multi(args, result, traj_ref_list, traj_est_list):
    from evo.tools import plot
    from evo.tools.settings import SETTINGS

    import matplotlib.pyplot as plt
    import numpy as np

    logger.debug(SEP)
    logger.debug("Plotting results... ")
    plot_mode = plot.PlotMode(args.plot_mode)

    figs = []
    # Plot the raw metric values.
    error_array_comb = np.array([])
    for i in range(len(result)):
        figs.append(plt.figure(figsize=SETTINGS.plot_figsize))
        if "seconds_from_start" in result[i].np_arrays:
            seconds_from_start = result[i].np_arrays["seconds_from_start"]
        else:
            seconds_from_start = None

        plot.error_array(
            figs[i], result[i].np_arrays["error_array"], x_array=seconds_from_start,
            statistics={
                s: result[i].stats[s]
                for s in SETTINGS.plot_statistics if s not in ("min", "max")
            }, name=result[i].info["label"], title=result[i].info["title"],
            xlabel="$t$ (s)" if seconds_from_start else "index")

    # Plot the values color-mapped onto the trajectory.
    figs.append(plt.figure(figsize=SETTINGS.plot_figsize))
    ax = plot.prepare_axis(figs[-1], plot_mode)
    if args.ros_map_yaml:
        plot.ros_map(ax, args.ros_map_yaml, plot_mode)

    if args.plot_colormap_min is None:
        args.plot_colormap_min = min([result[i].stats["min"] for i in range(len(result))])
    if args.plot_colormap_max is None:
        args.plot_colormap_max = max([result[i].stats["max"] for i in range(len(result))])
    if args.plot_colormap_max_percentile is not None:
        args.plot_colormap_max = np.percentile(
            error_array_comb, args.plot_colormap_max_percentile)

    traj_est_list_comb = np.array([])
    for i in range(len(result)):
        plot.traj(ax, plot_mode, traj_ref_list[i], style=SETTINGS.plot_reference_linestyle,
                  color=multirobot_reference_color[i], label='reference'+str(i),
                  alpha=0.8)
        plot.draw_coordinate_axes(ax, traj_ref_list[i], plot_mode,
                                  SETTINGS.plot_axis_marker_scale)

        plot.draw_coordinate_axes(ax, traj_est_list[i], plot_mode,
                                  SETTINGS.plot_axis_marker_scale)
        figs[-1].axes.append(ax)
    
    plot.traj_colormap_multi(ax, traj_est_list, [r.np_arrays["error_array"] for r in result],
                       plot_mode, min_map=args.plot_colormap_min,
                       max_map=args.plot_colormap_max,
                       title="Error mapped onto trajectory")

    plot_collection = plot.PlotCollection("Multi-robot APE analysis")
    for i in range(len(result)):
        plot_collection.add_figure("raw" + str(i), figs[i])
    plot_collection.add_figure("map", figs[-1])
    if args.plot:
        plot_collection.show()
    if args.save_plot:
        plot_collection.export(args.save_plot,
                               confirm_overwrite=not args.no_warnings)
    if args.serialize_plot:
        logger.debug(SEP)
        plot_collection.serialize(args.serialize_plot,
                                  confirm_overwrite=not args.no_warnings)
Пример #12
0
def run_analysis(traj_ref_path,
                 traj_est_path,
                 segments,
                 save_results,
                 display_plot,
                 save_plots,
                 save_folder,
                 confirm_overwrite=False,
                 dataset_name="",
                 discard_n_start_poses=0,
                 discard_n_end_poses=0):
    """ Run analysis on given trajectories, saves plots on given path:
    :param traj_ref_path: path to the reference (ground truth) trajectory.
    :param traj_est_path: path to the estimated trajectory.
    :param save_results: saves APE, and RPE per segment results.
    :param save_plots: whether to save the plots.
    :param save_folder: where to save the plots.
    :param confirm_overwrite: whether to confirm overwriting plots or not.
    :param dataset_name: optional param, to allow setting the same scale on different plots.
    """
    # Load trajectories.
    from evo.tools import file_interface
    traj_ref = None
    try:
        traj_ref = file_interface.read_euroc_csv_trajectory(
            traj_ref_path)  # TODO make it non-euroc specific.
    except file_interface.FileInterfaceException as e:
        raise Exception(
            "\033[91mMissing ground truth csv! \033[93m {}.".format(e))

    traj_est = None
    try:
        traj_est = file_interface.read_swe_csv_trajectory(traj_est_path)
    except file_interface.FileInterfaceException as e:
        log.info(e)
        raise Exception("\033[91mMissing vio output csv.\033[99m")

    evt.print_purple("Registering trajectories")
    traj_ref, traj_est = sync.associate_trajectories(traj_ref, traj_est)

    evt.print_purple("Aligning trajectories")
    traj_est = trajectory.align_trajectory(
        traj_est,
        traj_ref,
        correct_scale=False,
        discard_n_start_poses=int(discard_n_start_poses),
        discard_n_end_poses=int(discard_n_end_poses))

    num_of_poses = traj_est.num_poses
    traj_est.reduce_to_ids(
        range(int(discard_n_start_poses),
              int(num_of_poses - discard_n_end_poses), 1))
    traj_ref.reduce_to_ids(
        range(int(discard_n_start_poses),
              int(num_of_poses - discard_n_end_poses), 1))

    results = dict()

    evt.print_purple("Calculating APE translation part")
    data = (traj_ref, traj_est)
    ape_metric = metrics.APE(metrics.PoseRelation.translation_part)
    ape_metric.process_data(data)
    ape_result = ape_metric.get_result()
    results["absolute_errors"] = ape_result

    log.info(ape_result.pretty_str(info=True))

    # TODO(Toni): Save RPE computation results rather than the statistics
    # you can compute statistics later...
    evt.print_purple("Calculating RPE translation part for plotting")
    rpe_metric_trans = metrics.RPE(metrics.PoseRelation.translation_part, 1.0,
                                   metrics.Unit.frames, 0.0, False)
    rpe_metric_trans.process_data(data)
    rpe_stats_trans = rpe_metric_trans.get_all_statistics()
    log.info("mean: %f" % rpe_stats_trans["mean"])

    evt.print_purple("Calculating RPE rotation angle for plotting")
    rpe_metric_rot = metrics.RPE(metrics.PoseRelation.rotation_angle_deg, 1.0,
                                 metrics.Unit.frames, 1.0, False)
    rpe_metric_rot.process_data(data)
    rpe_stats_rot = rpe_metric_rot.get_all_statistics()
    log.info("mean: %f" % rpe_stats_rot["mean"])

    results["relative_errors"] = dict()
    # Read segments file
    for segment in segments:
        results["relative_errors"][segment] = dict()
        evt.print_purple("RPE analysis of segment: %d" % segment)
        evt.print_lightpurple("Calculating RPE segment translation part")
        rpe_segment_metric_trans = metrics.RPE(
            metrics.PoseRelation.translation_part, float(segment),
            metrics.Unit.meters, 0.01, True)
        rpe_segment_metric_trans.process_data(data)
        rpe_segment_stats_trans = rpe_segment_metric_trans.get_all_statistics()
        results["relative_errors"][segment][
            "rpe_trans"] = rpe_segment_stats_trans
        # print(rpe_segment_stats_trans)
        # print("mean:", rpe_segment_stats_trans["mean"])

        evt.print_lightpurple("Calculating RPE segment rotation angle")
        rpe_segment_metric_rot = metrics.RPE(
            metrics.PoseRelation.rotation_angle_deg, float(segment),
            metrics.Unit.meters, 0.01, True)
        rpe_segment_metric_rot.process_data(data)
        rpe_segment_stats_rot = rpe_segment_metric_rot.get_all_statistics()
        results["relative_errors"][segment]["rpe_rot"] = rpe_segment_stats_rot
        # print(rpe_segment_stats_rot)
        # print("mean:", rpe_segment_stats_rot["mean"])

    if save_results:
        # Save results file
        results_file = os.path.join(save_folder, 'results.yaml')
        evt.print_green("Saving analysis results to: %s" % results_file)
        with open(results_file, 'w') as outfile:
            if confirm_overwrite:
                if evt.user.check_and_confirm_overwrite(results_file):
                    outfile.write(yaml.dump(results, default_flow_style=False))
                else:
                    log.info("Not overwritting results.")
            else:
                outfile.write(yaml.dump(results, default_flow_style=False))

    # For each segment in segments file
    # Calculate rpe with delta = segment in meters with all-pairs set to True
    # Calculate max, min, rmse, mean, median etc

    # Plot boxplot, or those cumulative figures you see in evo (like demographic plots)
    if display_plot or save_plots:
        evt.print_green("Plotting:")
        log.info(dataset_name)
        plot_collection = plot.PlotCollection("Example")
        # metric values
        fig_1 = plt.figure(figsize=(8, 8))
        ymax = -1
        if dataset_name is not "" and FIX_MAX_Y:
            ymax = Y_MAX_APE_TRANS[dataset_name]

        ape_statistics = ape_metric.get_all_statistics()
        plot.error_array(
            fig_1,
            ape_metric.error,
            statistics=ape_statistics,
            name="APE translation",
            title=""  #str(ape_metric)
            ,
            xlabel="Keyframe index [-]",
            ylabel="APE translation [m]",
            y_min=0.0,
            y_max=ymax)
        plot_collection.add_figure("APE_translation", fig_1)

        # trajectory colormapped with error
        fig_2 = plt.figure(figsize=(8, 8))
        plot_mode = plot.PlotMode.xy
        ax = plot.prepare_axis(fig_2, plot_mode)
        plot.traj(ax, plot_mode, traj_ref, '--', 'gray', 'reference')
        plot.traj_colormap(ax,
                           traj_est,
                           ape_metric.error,
                           plot_mode,
                           min_map=0.0,
                           max_map=math.ceil(ape_statistics['max'] * 10) / 10,
                           title="ATE mapped onto trajectory [m]")
        plot_collection.add_figure("APE_translation_trajectory_error", fig_2)

        # RPE
        ## Trans
        ### metric values
        fig_3 = plt.figure(figsize=(8, 8))
        if dataset_name is not "" and FIX_MAX_Y:
            ymax = Y_MAX_RPE_TRANS[dataset_name]
        plot.error_array(
            fig_3,
            rpe_metric_trans.error,
            statistics=rpe_stats_trans,
            name="RPE translation",
            title=""  #str(rpe_metric_trans)
            ,
            xlabel="Keyframe index [-]",
            ylabel="RPE translation [m]",
            y_max=ymax)
        plot_collection.add_figure("RPE_translation", fig_3)

        ### trajectory colormapped with error
        fig_4 = plt.figure(figsize=(8, 8))
        plot_mode = plot.PlotMode.xy
        ax = plot.prepare_axis(fig_4, plot_mode)
        traj_ref_trans = copy.deepcopy(traj_ref)
        traj_ref_trans.reduce_to_ids(rpe_metric_trans.delta_ids)
        traj_est_trans = copy.deepcopy(traj_est)
        traj_est_trans.reduce_to_ids(rpe_metric_trans.delta_ids)
        plot.traj(ax, plot_mode, traj_ref_trans, '--', 'gray', 'Reference')
        plot.traj_colormap(
            ax,
            traj_est_trans,
            rpe_metric_trans.error,
            plot_mode,
            min_map=0.0,
            max_map=math.ceil(rpe_stats_trans['max'] * 10) / 10,
            title="RPE translation error mapped onto trajectory [m]")
        plot_collection.add_figure("RPE_translation_trajectory_error", fig_4)

        ## Rot
        ### metric values
        fig_5 = plt.figure(figsize=(8, 8))
        if dataset_name is not "" and FIX_MAX_Y:
            ymax = Y_MAX_RPE_ROT[dataset_name]
        plot.error_array(
            fig_5,
            rpe_metric_rot.error,
            statistics=rpe_stats_rot,
            name="RPE rotation error",
            title=""  #str(rpe_metric_rot)
            ,
            xlabel="Keyframe index [-]",
            ylabel="RPE rotation [deg]",
            y_max=ymax)
        plot_collection.add_figure("RPE_rotation", fig_5)

        ### trajectory colormapped with error
        fig_6 = plt.figure(figsize=(8, 8))
        plot_mode = plot.PlotMode.xy
        ax = plot.prepare_axis(fig_6, plot_mode)
        traj_ref_rot = copy.deepcopy(traj_ref)
        traj_ref_rot.reduce_to_ids(rpe_metric_rot.delta_ids)
        traj_est_rot = copy.deepcopy(traj_est)
        traj_est_rot.reduce_to_ids(rpe_metric_rot.delta_ids)
        plot.traj(ax, plot_mode, traj_ref_rot, '--', 'gray', 'Reference')
        plot.traj_colormap(
            ax,
            traj_est_rot,
            rpe_metric_rot.error,
            plot_mode,
            min_map=0.0,
            max_map=math.ceil(rpe_stats_rot['max'] * 10) / 10,
            title="RPE rotation error mapped onto trajectory [deg]")
        plot_collection.add_figure("RPE_rotation_trajectory_error", fig_6)

        if display_plot:
            evt.print_green("Displaying plots.")
            plot_collection.show()

        if save_plots:
            evt.print_green("Saving plots to: ")
            log.info(save_folder)
            # Config output format (pdf, eps, ...) using evo_config...
            plot_collection.export(os.path.join(save_folder, "plots.eps"),
                                   False)
            plot_collection.export(os.path.join(save_folder, "plots.pdf"),
                                   False)
Пример #13
0
for pose_relation in metrics.PoseRelation:
    print("\n------------------------------------------------------------------\n")
    data = (traj_ref, traj_est)
    start = time.clock()

    ape_metric = metrics.APE(pose_relation)
    ape_metric.process_data(data)
    ape_stats = ape_metric.get_all_statistics()

    stop = time.clock()
    ape_time = stop-start
    print("APE statistics w.r.t. " + ape_metric.pose_relation.value + ": ")
    pretty_printer.pprint(ape_stats)
    print("\nelapsed time for running the APE algorithm (seconds):\t", "{0:.6f}".format(ape_time))
    print("elapsed time for trajectory loading and APE (seconds):\t", "{0:.6f}".format(load_time+ape_time))

    if show_plots:
        plot.error_array(ape_metric.error, statistics=ape_stats, name="APE w.r.t. " + ape_metric.pose_relation.value)

if show_plots:
    plt.show()

print("\n------------------------------------------------------------------")
print("------------------------------------------------------------------\n")
print("calling offical TUM ATE script for comparison...")
cmd = ["tum_benchmark_tools/evaluate_ate.py", ref_file, est_file, "--max_difference", str(max_diff), "--verbose"]
time_cmd = timeit(stmt="sp.call("+str(cmd)+")", setup="import subprocess as sp", number=1)

print("\nelapsed time for full TUM ATE script (seconds):\t", "{0:.6f}".format(time_cmd))

Пример #14
0
def plot(args, result, traj_ref, traj_est):
    from evo.tools import plot
    from evo.tools.settings import SETTINGS

    import matplotlib.pyplot as plt
    import numpy as np

    logger.debug(SEP)
    logger.debug("Plotting results... ")
    plot_mode = plot.PlotMode(args.plot_mode)

    # Plot the raw metric values.
    fig1 = plt.figure(figsize=SETTINGS.plot_figsize)
    if "seconds_from_start" in result.np_arrays:
        seconds_from_start = result.np_arrays["seconds_from_start"]
    else:
        seconds_from_start = None

    plot.error_array(
        fig1, result.np_arrays["error_array"],
        x_array=seconds_from_start,
        statistics=result.stats,
        name=result.info["label"],
        title=result.info["title"],
        xlabel="$t$ (s)" if seconds_from_start else "index")

    # Plot the values color-mapped onto the trajectory.
    fig2 = plt.figure(figsize=SETTINGS.plot_figsize)
    ax = plot.prepare_axis(fig2, plot_mode)
    plot.traj(ax, plot_mode, traj_ref, '--', 'black', 'reference',
              alpha=0.0 if SETTINGS.plot_hideref else 0.5)

    if args.plot_colormap_min is None:
        args.plot_colormap_min = result.stats["min"]
    if args.plot_colormap_max is None:
        args.plot_colormap_max = result.stats["max"]
    if args.plot_colormap_max_percentile is not None:
        args.plot_colormap_max = np.percentile(
            result.np_arrays["error_array"],
            args.plot_colormap_max_percentile)

    plot.traj_colormap(
        ax, traj_est, result.np_arrays["error_array"],
        plot_mode,
        min_map=args.plot_colormap_min,
        max_map=args.plot_colormap_max,
        title="Error mapped onto trajectory")
    fig2.axes.append(ax)

    plot_collection = plot.PlotCollection(result.info["title"])
    plot_collection.add_figure("raw", fig1)
    plot_collection.add_figure("map", fig2)
    if args.plot:
        plot_collection.show()
    if args.save_plot:
        plot_collection.export(
            args.save_plot, confirm_overwrite=not args.no_warnings)
    if args.serialize_plot:
        logger.debug(SEP)
        plot_collection.serialize(
            args.serialize_plot, confirm_overwrite=not args.no_warnings)