Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions Pose2Sim/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def bounding_boxes(js_file, margin_percent=0.1, around='extremities'):
return bounding_boxes


def retrieve_calib_params(calib_file):
def retrieve_calib_params(calib_file, json_pose_dirs_names=None):
'''
Compute projection matrices from toml calibration file.

Expand All @@ -273,22 +273,35 @@ def retrieve_calib_params(calib_file):
cal_keys = [c for c in calib.keys()
if c not in ['metadata', 'capture_volume', 'charuco', 'checkerboard']
and isinstance(calib[c],dict)]

if json_pose_dirs_names is None:
pose_keys = cal_keys
else:
pose_keys = [name.replace('_json', '') for name in json_pose_dirs_names]
missing_cams = [cam for cam in pose_keys if cam not in cal_keys]
if missing_cams:
logging.error(f"The following cameras are present in the pose folders but missing in the calibration file: {missing_cams}.")
raise ValueError(f"The following cameras are present in the pose folders but missing in the calibration file: {missing_cams}.")


S, K, dist, optim_K, inv_K, R, R_mat, T = [], [], [], [], [], [], [], []
for c, cam in enumerate(cal_keys):
for cam in list(cal_keys):
if cam not in pose_keys:
continue
S.append(np.array(calib[cam]['size']))
K.append(np.array(calib[cam]['matrix']))
dist.append(np.array(calib[cam]['distortions']))
optim_K.append(cv2.getOptimalNewCameraMatrix(K[c], dist[c], [int(s) for s in S[c]], 1, [int(s) for s in S[c]])[0])
inv_K.append(np.linalg.inv(K[c]))
optim_K.append(cv2.getOptimalNewCameraMatrix(K[-1], dist[-1], [int(s) for s in S[-1]], 1, [int(s) for s in S[-1]])[0])
inv_K.append(np.linalg.inv(K[-1]))
R.append(np.array(calib[cam]['rotation']))
R_mat.append(cv2.Rodrigues(R[c])[0])
R_mat.append(cv2.Rodrigues(R[-1])[0])
T.append(np.array(calib[cam]['translation']))
calib_params = {'S': S, 'K': K, 'dist': dist, 'inv_K': inv_K, 'optim_K': optim_K, 'R': R, 'R_mat': R_mat, 'T': T}

return calib_params


def computeP(calib_file, undistort=False):
def computeP(calib_file, json_pose_dirs_names=None, undistort=False):
'''
Compute projection matrices from toml calibration file.

Expand All @@ -305,8 +318,20 @@ def computeP(calib_file, undistort=False):
cal_keys = [c for c in calib.keys()
if c not in ['metadata', 'capture_volume', 'charuco', 'checkerboard']
and isinstance(calib[c],dict)]

if json_pose_dirs_names is None:
pose_keys = cal_keys
else:
pose_keys = [name.replace('_json', '') for name in json_pose_dirs_names]
missing_cams = [cam for cam in pose_keys if cam not in cal_keys]
if missing_cams:
logging.error(f"The following cameras are present in the pose folders but missing in the calibration file: {missing_cams}.")
raise ValueError(f"The following cameras are present in the pose folders but missing in the calibration file: {missing_cams}.")

P = []
for cam in list(cal_keys):
if cam not in pose_keys:
continue
K = np.array(calib[cam]['matrix'])
if undistort:
S = np.array(calib[cam]['size'])
Expand Down
16 changes: 5 additions & 11 deletions Pose2Sim/personAssociation.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,10 +659,6 @@ def associate_all(config_dict):
pose_dir = os.path.join(project_dir, 'pose')
poseSync_dir = os.path.join(project_dir, 'pose-sync')
poseTracked_dir = os.path.join(project_dir, 'pose-associated')

# projection matrix from toml calibration file
P_all = computeP(calib_file, undistort=undistort_points)
calib_params = retrieve_calib_params(calib_file)

# selection of tracked keypoint id
try: # from skeletons.py
Expand Down Expand Up @@ -709,11 +705,9 @@ def associate_all(config_dict):
f_range = [[0,max([len(j) for j in json_files_names])] if frame_range in ('all', 'auto', []) else frame_range][0]
n_cams = len(json_dirs_names)

# Check that camera number is consistent between calibration file and pose folders
if n_cams != len(P_all):
raise Exception(f'Error: The number of cameras is not consistent:\
Found {len(P_all)} cameras in the calibration file,\
and {n_cams} cameras based on the number of pose folders.')
# projection matrix from toml calibration file
P = computeP(calib_file, json_dirs_names, undistort=undistort_points)
calib_params = retrieve_calib_params(calib_file, json_dirs_names)

if not multi_person:
logging.info('\nSingle-person analysis selected.')
Expand Down Expand Up @@ -744,12 +738,12 @@ def associate_all(config_dict):
personsIDs_comb = persons_combinations(json_files_f)

# choose persons of interest and exclude cameras with bad pose estimation
error_proposals, proposals, Q_kpt = best_persons_and_cameras_combination(config_dict, json_files_f, personsIDs_comb, P_all, tracked_keypoint_id, calib_params)
error_proposals, proposals, Q_kpt = best_persons_and_cameras_combination(config_dict, json_files_f, personsIDs_comb, P, tracked_keypoint_id, calib_params)

if not np.isinf(error_proposals):
error_min_tot.append(np.nanmean(error_proposals))
cameras_off_count = np.count_nonzero([np.isnan(comb) for comb in proposals]) / len(proposals)
cameras_off_tot.append(cameras_off_count)
cameras_off_tot.append(cameras_off_count)

else:
# read data
Expand Down
14 changes: 5 additions & 9 deletions Pose2Sim/triangulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ def triangulate_all(config_dict):
try:
calib_dir = [os.path.join(session_dir, c) for c in os.listdir(session_dir) if os.path.isdir(os.path.join(session_dir, c)) and 'calib' in c.lower()][0]
except:
raise Exception(f'No .toml calibration direcctory found.')
raise Exception(f'No .toml calibration directory found.')
try:
calib_files = glob.glob(os.path.join(calib_dir, '*.toml'))
calib_file = max(calib_files, key=os.path.getctime) # lastly created calibration file
Expand All @@ -707,10 +707,6 @@ def triangulate_all(config_dict):
pose_dir = os.path.join(project_dir, 'pose')
poseSync_dir = os.path.join(project_dir, 'pose-sync')
poseTracked_dir = os.path.join(project_dir, 'pose-associated')

# Projection matrix from toml calibration file
P = computeP(calib_file, undistort=undistort_points)
calib_params = retrieve_calib_params(calib_file)

# Retrieve keypoints from model
try: # from skeletons.py
Expand Down Expand Up @@ -774,10 +770,10 @@ def triangulate_all(config_dict):
# frame range selection
f_range = [[0,min([len(j) for j in json_files_names])] if frame_range in ('all', 'auto', []) else frame_range][0]
frame_nb = f_range[1] - f_range[0]
# Check that camera number is consistent between calibration file and pose folders
if n_cams != len(P):
raise Exception(f'Error: The number of cameras is not consistent: Found {len(P)} cameras in the calibration file, and {n_cams} cameras based on the number of pose folders.')

# Projection matrix from toml calibration file
P = computeP(calib_file, json_dirs_names, undistort=undistort_points)
calib_params = retrieve_calib_params(calib_file, json_dirs_names)

# Triangulation
if multi_person:
Expand Down
Loading