option to fill large gaps with nan, last valid value, or zeros

This commit is contained in:
davidpagnon 2024-07-09 20:54:18 +02:00
parent 7a3bcf76be
commit 86f7088b4e
5 changed files with 14 additions and 6 deletions

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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
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)
# Q_tot[n].replace(np.nan, 0, inplace=True)
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))]

View File

@ -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