From 86f7088b4ed89e6af2ffabb946491de81ffba094 Mon Sep 17 00:00:00 2001 From: davidpagnon Date: Tue, 9 Jul 2024 20:54:18 +0200 Subject: [PATCH] option to fill large gaps with nan, last valid value, or zeros --- Pose2Sim/Demo_MultiPerson/Config.toml | 1 + Pose2Sim/Demo_SinglePerson/Config.toml | 1 + Pose2Sim/Pose2Sim.py | 3 ++- Pose2Sim/triangulation.py | 13 +++++++++---- setup.cfg | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Pose2Sim/Demo_MultiPerson/Config.toml b/Pose2Sim/Demo_MultiPerson/Config.toml index f4b5761..2a6f01e 100644 --- a/Pose2Sim/Demo_MultiPerson/Config.toml +++ b/Pose2Sim/Demo_MultiPerson/Config.toml @@ -143,6 +143,7 @@ min_cameras_for_triangulation = 2 interpolation = 'cubic' #linear, slinear, quadratic, cubic, or none # 'none' if you don't want to interpolate missing points interp_if_gap_smaller_than = 10 # do not interpolate bigger gaps +fill_large_gaps_with = 'last_value' # 'last_value', 'nan', or 'zeros' show_interp_indices = true # true or false (lowercase). For each keypoint, return the frames that need to be interpolated handle_LR_swap = false # Better if few cameras (eg less than 4) with risk of limb swapping (eg camera facing sagittal plane), otherwise slightly less accurate and slower undistort_points = false # Better if distorted image (parallel lines curvy on the edge or at least one param > 10^-2), but unnecessary (and slightly slower) if distortions are low diff --git a/Pose2Sim/Demo_SinglePerson/Config.toml b/Pose2Sim/Demo_SinglePerson/Config.toml index ebeec82..4de5aec 100644 --- a/Pose2Sim/Demo_SinglePerson/Config.toml +++ b/Pose2Sim/Demo_SinglePerson/Config.toml @@ -144,6 +144,7 @@ interpolation = 'cubic' #linear, slinear, quadratic, cubic, or none # 'none' if you don't want to interpolate missing points interp_if_gap_smaller_than = 10 # do not interpolate bigger gaps show_interp_indices = true # true or false (lowercase). For each keypoint, return the frames that need to be interpolated +fill_large_gaps_with = 'last_value' # 'last_value', 'nan', or 'zeros' handle_LR_swap = false # Better if few cameras (eg less than 4) with risk of limb swapping (eg camera facing sagittal plane), otherwise slightly less accurate and slower undistort_points = false # Better if distorted image (parallel lines curvy on the edge or at least one param > 10^-2), but unnecessary (and slightly slower) if distortions are low make_c3d = true # save triangulated data in c3d format in addition to trc diff --git a/Pose2Sim/Pose2Sim.py b/Pose2Sim/Pose2Sim.py index d5a9004..d10fcea 100644 --- a/Pose2Sim/Pose2Sim.py +++ b/Pose2Sim/Pose2Sim.py @@ -68,7 +68,7 @@ def setup_logging(session_dir): ''' Create logging file and stream handlers ''' - with open(os.path.join(session_dir, 'logs.txt'), 'a+') as log_f: pass + logging.basicConfig(format='%(message)s', level=logging.INFO, handlers = [logging.handlers.TimedRotatingFileHandler(os.path.join(session_dir, 'logs.txt'), when='D', interval=7), logging.StreamHandler()]) @@ -220,6 +220,7 @@ def calibration(config=None): end = time.time() logging.info(f'\nCalibration took {end-start:.2f} s.') + logging.handlers.close() def poseEstimation(config=None): diff --git a/Pose2Sim/triangulation.py b/Pose2Sim/triangulation.py index 5f0ccce..383772d 100644 --- a/Pose2Sim/triangulation.py +++ b/Pose2Sim/triangulation.py @@ -343,6 +343,7 @@ def recap_triangulate(config_dict, error, nb_cams_excluded, keypoints_names, cam show_interp_indices = config_dict.get('triangulation').get('show_interp_indices') interpolation_kind = config_dict.get('triangulation').get('interpolation') interp_gap_smaller_than = config_dict.get('triangulation').get('interp_if_gap_smaller_than') + fill_large_gaps_with = config_dict.get('triangulation').get('fill_large_gaps_with') make_c3d = config_dict.get('triangulation').get('make_c3d') handle_LR_swap = config_dict.get('triangulation').get('handle_LR_swap') undistort_points = config_dict.get('triangulation').get('undistort_points') @@ -383,7 +384,7 @@ def recap_triangulate(config_dict, error, nb_cams_excluded, keypoints_names, cam logging.info(f'\n--> Mean reprojection error for all points on all frames is {mean_error_px} px, which roughly corresponds to {mean_error_mm} mm. ') logging.info(f'Cameras were excluded if likelihood was below {likelihood_threshold} and if the reprojection error was above {error_threshold_triangulation} px.') if interpolation_kind != 'none': - logging.info(f'Gaps were interpolated with {interpolation_kind} method if smaller than {interp_gap_smaller_than} frames.') + logging.info(f'Gaps were interpolated with {interpolation_kind} method if smaller than {interp_gap_smaller_than} frames. Larger gaps were filled with {["the last valid value" if fill_large_gaps_with == "last_value" else "zeros" if fill_large_gaps_with == "zeros" else "NaNs"][0]}.') logging.info(f'In average, {mean_cam_excluded} cameras had to be excluded to reach these thresholds.') cam_excluded_count[n] = {i: v for i, v in zip(cam_names, cam_excluded_count[n].values())} @@ -733,6 +734,7 @@ def triangulate_all(config_dict): likelihood_threshold = config_dict.get('triangulation').get('likelihood_threshold_triangulation') interpolation_kind = config_dict.get('triangulation').get('interpolation') interp_gap_smaller_than = config_dict.get('triangulation').get('interp_if_gap_smaller_than') + fill_large_gaps_with = config_dict.get('triangulation').get('fill_large_gaps_with') show_interp_indices = config_dict.get('triangulation').get('show_interp_indices') undistort_points = config_dict.get('triangulation').get('undistort_points') make_c3d = config_dict.get('triangulation').get('make_c3d') @@ -961,9 +963,12 @@ def triangulate_all(config_dict): except: logging.info(f'Interpolation was not possible for person {n}. This means that not enough points are available, which is often due to a bad calibration.') # Fill non-interpolated values with last valid one - for n in range(nb_persons_to_detect): - Q_tot[n] = Q_tot[n].ffill(axis=0).bfill(axis=0) - # Q_tot[n].replace(np.nan, 0, inplace=True) + if fill_large_gaps_with == 'last_value': + for n in range(nb_persons_to_detect): + Q_tot[n] = Q_tot[n].ffill(axis=0).bfill(axis=0) + elif fill_large_gaps_with == 'zeros': + for n in range(nb_persons_to_detect): + Q_tot[n].replace(np.nan, 0, inplace=True) # Create TRC file trc_paths = [make_trc(config_dict, Q_tot[n], keypoints_names, f_range, id_person=n) for n in range(len(Q_tot))] diff --git a/setup.cfg b/setup.cfg index 2b225c4..0316440 100644 --- a/setup.cfg +++ b/setup.cfg @@ -49,7 +49,7 @@ install_requires = tensorflow torch #rtmlib - rtmlib@git+ssh://git@github.com/Tau-J/rtmlib + rtmlib@git+https://github.com/Tau-J/rtmlib.git onnxruntime openvino opencv-python