few changes to the conversion to c3d
This commit is contained in:
parent
46652a8eaa
commit
db8014c3f5
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,6 +8,7 @@ dist/
|
|||||||
# **/*.mp4
|
# **/*.mp4
|
||||||
**/*.trc
|
**/*.trc
|
||||||
**/*.sto
|
**/*.sto
|
||||||
|
**/*.c3d
|
||||||
|
|
||||||
**/Calib_qualisys.toml
|
**/Calib_qualisys.toml
|
||||||
**/pose-3d/
|
**/pose-3d/
|
||||||
|
@ -164,6 +164,7 @@ make_c3d = false # also save triangulated data in c3d format
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
participant_mass = 70.0 # kg
|
participant_mass = 70.0 # kg
|
||||||
|
make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
[opensim]
|
[opensim]
|
||||||
|
@ -163,10 +163,11 @@
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
# participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
# participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
# participant_mass = 70.0 # kg
|
# participant_mass = 70.0 # kg
|
||||||
|
# make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
# [opensim]
|
# [opensim]
|
||||||
# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
# static_trial = [# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
||||||
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
||||||
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
||||||
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
||||||
|
@ -163,10 +163,11 @@
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
# participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
# participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
# participant_mass = 70.0 # kg
|
# participant_mass = 70.0 # kg
|
||||||
|
# make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
# [opensim]
|
# [opensim]
|
||||||
# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
# static_trial = [# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
||||||
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
||||||
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
||||||
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
||||||
|
@ -163,10 +163,11 @@ display_figures = false # true or false (lowercase)
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
# participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
# participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
# participant_mass = 70.0 # kg
|
# participant_mass = 70.0 # kg
|
||||||
|
# make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
# [opensim]
|
# [opensim]
|
||||||
# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
# static_trial = [# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
||||||
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
||||||
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
||||||
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
||||||
|
@ -163,10 +163,12 @@
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
# participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
# participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
# participant_mass = 70.0 # kg
|
# participant_mass = 70.0 # kg
|
||||||
|
# make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
# make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
# [opensim]
|
# [opensim]
|
||||||
# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
# static_trial = [# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
||||||
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
||||||
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
||||||
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
||||||
|
@ -163,10 +163,11 @@
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
participant_height = 1.21 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
participant_height = 1.21 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
participant_mass = 25.0 # kg
|
participant_mass = 25.0 # kg
|
||||||
|
# make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
# [opensim]
|
# [opensim]
|
||||||
# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
# static_trial = [# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
||||||
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
||||||
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
||||||
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
||||||
|
@ -162,10 +162,11 @@
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
participant_mass = 70.0 # kg
|
participant_mass = 70.0 # kg
|
||||||
|
# make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
# [opensim]
|
# [opensim]
|
||||||
# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
# static_trial = [# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
||||||
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
||||||
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
||||||
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
||||||
|
@ -129,13 +129,13 @@ reorder_trc = true # only checked if multi_person analysis
|
|||||||
# show_interp_indices = true # true or false (lowercase). For each keypoint, return the frames that need to be interpolated
|
# 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
|
# 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
|
# 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 = false # save triangulated data in c3d format in addition to trc
|
make_c3d = true # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
# [filtering]
|
[filtering]
|
||||||
# type = 'butterworth' # butterworth, kalman, gaussian, LOESS, median, butterworth_on_speed
|
# type = 'butterworth' # butterworth, kalman, gaussian, LOESS, median, butterworth_on_speed
|
||||||
# display_figures = false # true or false (lowercase)
|
# display_figures = false # true or false (lowercase)
|
||||||
# make_c3d = false # save triangulated data in c3d format in addition to trc
|
make_c3d = true # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
# [filtering.butterworth]
|
# [filtering.butterworth]
|
||||||
# order = 4
|
# order = 4
|
||||||
@ -159,10 +159,11 @@ reorder_trc = true # only checked if multi_person analysis
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
participant_height = [1.21, 1.72] # m # float if single person, list of float if multi-person (same order as the Static trials)
|
participant_height = [1.21, 1.72] # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
participant_mass = [25.0, 70.0] # kg
|
participant_mass = [25.0, 70.0] # kg
|
||||||
|
make_c3d = true # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
# [opensim]
|
# [opensim]
|
||||||
# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
# static_trial = [# static_trial = ['S00_P00_Participant/S00_P00_T00_StaticTrial']
|
||||||
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
# # If this Config.toml file is at the Trial level, set to true or false (lowercase);
|
||||||
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
# # At the Participant level, specify the name of the static trial folder name, e.g. ['S00_P00_T00_StaticTrial'];
|
||||||
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
# # At the Session level, add participant subdirectory, e.g. ['S00_P00_Participant/S00_P00_T00_StaticTrial', 'S00_P01_Participant/S00_P00_T00_StaticTrial']
|
||||||
|
@ -164,6 +164,7 @@ make_c3d = false # save triangulated data in c3d format in addition to trc
|
|||||||
## Only works on BODY_25 and BODY_25B models
|
## Only works on BODY_25 and BODY_25B models
|
||||||
participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
participant_height = 1.72 # m # float if single person, list of float if multi-person (same order as the Static trials)
|
||||||
participant_mass = 70.0 # kg
|
participant_mass = 70.0 # kg
|
||||||
|
make_c3d = false # save triangulated data in c3d format in addition to trc
|
||||||
|
|
||||||
|
|
||||||
[opensim]
|
[opensim]
|
||||||
|
@ -10,8 +10,6 @@
|
|||||||
Converts c3d files to trc files.
|
Converts c3d files to trc files.
|
||||||
Beware that it only allows you to retrieve 3D points, you won't get analog data nor computed data such as angles or powers with this code.
|
Beware that it only allows you to retrieve 3D points, you won't get analog data nor computed data such as angles or powers with this code.
|
||||||
|
|
||||||
N.B.: First install c3d: `pip install c3d`
|
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
from Pose2Sim.Utilities import c3d_to_trc; c3d_to_trc.c3d_to_trc_func(r'<input_c3d_file>')
|
from Pose2Sim.Utilities import c3d_to_trc; c3d_to_trc.c3d_to_trc_func(r'<input_c3d_file>')
|
||||||
python -m c3d_to_trc -i input_c3d_file
|
python -m c3d_to_trc -i input_c3d_file
|
||||||
|
@ -1,73 +1,126 @@
|
|||||||
"""
|
#! /usr/bin/env python
|
||||||
Extracts marker data from a TRC file and creates a corresponding C3D file.
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
Usage:
|
|
||||||
python trc_to_c3d.py --trc_path <path_to_trc_file> --f <frame_rate>
|
|
||||||
|
|
||||||
--trc_path: Path to the TRC file.
|
'''
|
||||||
--f: Frame rate of the 3D data.
|
##################################################
|
||||||
c3d file will be saved in the same directory as the TRC file with the same name.
|
## Convert trc files to c3d ##
|
||||||
|
##################################################
|
||||||
|
|
||||||
|
Converts trc files to c3d files.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
from Pose2Sim.Utilities import trc_to_c3d; trc_to_c3d.trc_to_c3d_func(r'<input_trc_file>')
|
||||||
|
python -m trc_to_c3d -t <path_to_trc_path>
|
||||||
|
python -m trc_to_c3d --trc_path <path_to_trc_path> --c3d_path <output_c3d_file>
|
||||||
|
'''
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
## INIT
|
||||||
import argparse
|
import argparse
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pandas as pd
|
|
||||||
import c3d
|
import c3d
|
||||||
|
|
||||||
def extract_marker_data(trc_file):
|
|
||||||
with open(trc_file, 'r') as file:
|
## AUTHORSHIP INFORMATION
|
||||||
|
__author__ = "HunMin Kim, David Pagnon"
|
||||||
|
__copyright__ = "Copyright 2021, Pose2Sim"
|
||||||
|
__credits__ = ["HuMin Kim, David Pagnon"]
|
||||||
|
__license__ = "BSD 3-Clause License"
|
||||||
|
__version__ = '0.8'
|
||||||
|
__maintainer__ = "David Pagnon"
|
||||||
|
__email__ = "contact@david-pagnon.com"
|
||||||
|
__status__ = "Development"
|
||||||
|
|
||||||
|
|
||||||
|
## FUNCTIONS
|
||||||
|
def extract_marker_data(trc_path):
|
||||||
|
'''
|
||||||
|
Extract marker names and coordinates from a trc file.
|
||||||
|
|
||||||
|
INPUTS:
|
||||||
|
- trc_path: Path to the trc file
|
||||||
|
|
||||||
|
OUTPUTS:
|
||||||
|
- marker_names: List of marker names
|
||||||
|
- marker_coords: Array of marker coordinates (n_frames, t+3*n_markers)
|
||||||
|
'''
|
||||||
|
|
||||||
|
# marker names
|
||||||
|
with open(trc_path, 'r') as file:
|
||||||
lines = file.readlines()
|
lines = file.readlines()
|
||||||
marker_names_line = lines[3]
|
marker_names_line = lines[3]
|
||||||
marker_names = marker_names_line.strip().split('\t')[2::3]
|
marker_names = marker_names_line.strip().split('\t')[2::3]
|
||||||
|
|
||||||
trc_data = pd.read_csv(trc_file, sep='\t', skiprows=5)
|
# time and marker coordinates
|
||||||
marker_coords = trc_data.iloc[:, 2:].to_numpy().reshape(-1, len(marker_names), 3)
|
trc_data_np = np.genfromtxt(trc_path, skip_header=5, delimiter = '\t')[:,1:]
|
||||||
# marker_coords = np.nan_to_num(marker_coords, nan=0.0)
|
|
||||||
marker_coords *= 1000 # Convert from meters to millimeters
|
|
||||||
|
|
||||||
return marker_names, marker_coords
|
return marker_names, trc_data_np
|
||||||
|
|
||||||
def create_c3d_file(trc_file, marker_names, marker_coords, frame_rate):
|
|
||||||
|
def create_c3d_file(c3d_path, marker_names, trc_data_np):
|
||||||
|
'''
|
||||||
|
Create a c3d file from the data extracted from a trc file.
|
||||||
|
|
||||||
|
INPUTS:
|
||||||
|
- c3d_path: Path to the c3d file
|
||||||
|
- marker_names: List of marker names
|
||||||
|
- trc_data_np: Array of marker coordinates (n_frames, t+3*n_markers)
|
||||||
|
|
||||||
|
OUTPUTS:
|
||||||
|
- c3d file
|
||||||
|
'''
|
||||||
|
|
||||||
|
# retrieve frame rate
|
||||||
|
times = trc_data_np[:,0]
|
||||||
|
frame_rate = round((len(times)-1) / (times[-1] - times[0]))
|
||||||
|
|
||||||
|
# write c3d file
|
||||||
writer = c3d.Writer(point_rate=frame_rate, analog_rate=0, point_scale=1.0, point_units='mm', gen_scale=-1.0)
|
writer = c3d.Writer(point_rate=frame_rate, analog_rate=0, point_scale=1.0, point_units='mm', gen_scale=-1.0)
|
||||||
writer.set_point_labels(marker_names)
|
writer.set_point_labels(marker_names)
|
||||||
|
|
||||||
markers_group = writer.point_group
|
for frame in trc_data_np:
|
||||||
|
residuals = np.full((len(marker_names), 1), 0.0)
|
||||||
for frame in marker_coords:
|
cameras = np.zeros((len(marker_names), 1))
|
||||||
residuals = np.full((frame.shape[0], 1), 0.0)
|
coords = frame[1:].reshape(-1,3)*1000
|
||||||
cameras = np.zeros((frame.shape[0], 1))
|
points = np.hstack((coords, residuals, cameras))
|
||||||
points = np.hstack((frame, residuals, cameras))
|
|
||||||
writer.add_frames([(points, np.array([]))])
|
writer.add_frames([(points, np.array([]))])
|
||||||
|
|
||||||
writer.set_start_frame(1)
|
writer.set_start_frame(0)
|
||||||
writer._set_last_frame(len(marker_coords))
|
writer._set_last_frame(len(trc_data_np)-1)
|
||||||
|
|
||||||
c3d_file_path = trc_file.replace('.trc', '.c3d')
|
with open(c3d_path, 'wb') as handle:
|
||||||
with open(c3d_file_path, 'wb') as handle:
|
|
||||||
writer.write(handle)
|
writer.write(handle)
|
||||||
print(f"Successfully created c3d file.")
|
|
||||||
|
|
||||||
def trc_to_c3d(trc_file, frame_rate):
|
|
||||||
marker_names, marker_coords = extract_marker_data(trc_file)
|
|
||||||
create_c3d_file(trc_file, marker_names, marker_coords, frame_rate)
|
|
||||||
|
|
||||||
def main():
|
def trc_to_c3d_func(*args):
|
||||||
parser = argparse.ArgumentParser(description='Convert TRC files to C3D files.')
|
'''
|
||||||
parser.add_argument('--trc_path', type=str, required=True, help='Path to the TRC file')
|
Converts trc files to c3d files.
|
||||||
parser.add_argument('--f', type=int, required=True, help='Frame rate')
|
|
||||||
|
Usage:
|
||||||
|
from Pose2Sim.Utilities import trc_to_c3d; trc_to_c3d.trc_to_c3d_func(r'<input_trc_file>')
|
||||||
|
python -m trc_to_c3d -t <path_to_trc_path>
|
||||||
|
python -m trc_to_c3d --trc_path <path_to_trc_path> --c3d_path <output_c3d_file>
|
||||||
|
'''
|
||||||
|
|
||||||
args = parser.parse_args()
|
try:
|
||||||
|
trc_path = args[0]['trc_path'] # invoked with argparse
|
||||||
|
if args[0]['c3d_path'] == None:
|
||||||
|
c3d_path = trc_path.replace('.trc', '.c3d')
|
||||||
|
else:
|
||||||
|
c3d_path = args[0]['c3d_path']
|
||||||
|
except:
|
||||||
|
trc_path = args[0] # invoked as a function
|
||||||
|
c3d_path = trc_path.replace('.trc', '.c3d')
|
||||||
|
|
||||||
trc_file = args.trc_path
|
marker_names, trc_data_np = extract_marker_data(trc_path)
|
||||||
frame_rate = args.f
|
create_c3d_file(c3d_path, marker_names, trc_data_np)
|
||||||
|
|
||||||
if not os.path.isfile(trc_file):
|
|
||||||
print(f"Error: {trc_file} does not exist.")
|
|
||||||
return
|
|
||||||
|
|
||||||
trc_to_c3d(trc_file, frame_rate)
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
parser = argparse.ArgumentParser(description='Convert TRC files to C3D files.')
|
||||||
|
parser.add_argument('-t', '--trc_path', type=str, required=True, help='trc input file path')
|
||||||
|
parser.add_argument('-c', '--c3d_path', type=str, required=False, help='c3d output file path')
|
||||||
|
args = vars(parser.parse_args())
|
||||||
|
|
||||||
|
trc_to_c3d_func(args)
|
||||||
|
@ -16,10 +16,8 @@ import json
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import re
|
import re
|
||||||
import cv2
|
import cv2
|
||||||
import os
|
|
||||||
import pandas as pd
|
|
||||||
import c3d
|
import c3d
|
||||||
import glob
|
import sys
|
||||||
|
|
||||||
import matplotlib as mpl
|
import matplotlib as mpl
|
||||||
mpl.use('qt5agg')
|
mpl.use('qt5agg')
|
||||||
@ -27,7 +25,8 @@ mpl.rc('figure', max_open_warning=0)
|
|||||||
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
|
||||||
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
|
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
|
||||||
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QTabWidget, QVBoxLayout
|
from PyQt5.QtWidgets import QMainWindow, QApplication, QWidget, QTabWidget, QVBoxLayout
|
||||||
import sys
|
import warnings
|
||||||
|
warnings.filterwarnings("ignore", category=UserWarning, module="c3d")
|
||||||
|
|
||||||
|
|
||||||
## AUTHORSHIP INFORMATION
|
## AUTHORSHIP INFORMATION
|
||||||
@ -385,6 +384,83 @@ def zup2yup(Q):
|
|||||||
return Q
|
return Q
|
||||||
|
|
||||||
|
|
||||||
|
def extract_trc_data(trc_path):
|
||||||
|
'''
|
||||||
|
Extract marker names and coordinates from a trc file.
|
||||||
|
|
||||||
|
INPUTS:
|
||||||
|
- trc_path: Path to the trc file
|
||||||
|
|
||||||
|
OUTPUTS:
|
||||||
|
- marker_names: List of marker names
|
||||||
|
- marker_coords: Array of marker coordinates (n_frames, t+3*n_markers)
|
||||||
|
'''
|
||||||
|
|
||||||
|
# marker names
|
||||||
|
with open(trc_path, 'r') as file:
|
||||||
|
lines = file.readlines()
|
||||||
|
marker_names_line = lines[3]
|
||||||
|
marker_names = marker_names_line.strip().split('\t')[2::3]
|
||||||
|
|
||||||
|
# time and marker coordinates
|
||||||
|
trc_data_np = np.genfromtxt(trc_path, skip_header=5, delimiter = '\t')[:,1:]
|
||||||
|
|
||||||
|
return marker_names, trc_data_np
|
||||||
|
|
||||||
|
|
||||||
|
def create_c3d_file(c3d_path, marker_names, trc_data_np):
|
||||||
|
'''
|
||||||
|
Create a c3d file from the data extracted from a trc file.
|
||||||
|
|
||||||
|
INPUTS:
|
||||||
|
- c3d_path: Path to the c3d file
|
||||||
|
- marker_names: List of marker names
|
||||||
|
- trc_data_np: Array of marker coordinates (n_frames, t+3*n_markers)
|
||||||
|
|
||||||
|
OUTPUTS:
|
||||||
|
- c3d file
|
||||||
|
'''
|
||||||
|
|
||||||
|
# retrieve frame rate
|
||||||
|
times = trc_data_np[:,0]
|
||||||
|
frame_rate = round((len(times)-1) / (times[-1] - times[0]))
|
||||||
|
|
||||||
|
# write c3d file
|
||||||
|
writer = c3d.Writer(point_rate=frame_rate, analog_rate=0, point_scale=1.0, point_units='mm', gen_scale=-1.0)
|
||||||
|
writer.set_point_labels(marker_names)
|
||||||
|
|
||||||
|
for frame in trc_data_np:
|
||||||
|
residuals = np.full((len(marker_names), 1), 0.0)
|
||||||
|
cameras = np.zeros((len(marker_names), 1))
|
||||||
|
coords = frame[1:].reshape(-1,3)*1000
|
||||||
|
points = np.hstack((coords, residuals, cameras))
|
||||||
|
writer.add_frames([(points, np.array([]))])
|
||||||
|
|
||||||
|
writer.set_start_frame(0)
|
||||||
|
writer._set_last_frame(len(trc_data_np)-1)
|
||||||
|
|
||||||
|
with open(c3d_path, 'wb') as handle:
|
||||||
|
writer.write(handle)
|
||||||
|
|
||||||
|
|
||||||
|
def convert_to_c3d(trc_path):
|
||||||
|
'''
|
||||||
|
Make Visual3D compatible c3d files from a trc path
|
||||||
|
|
||||||
|
INPUT:
|
||||||
|
- trc_path: string, trc file to convert
|
||||||
|
|
||||||
|
OUTPUT:
|
||||||
|
- c3d file
|
||||||
|
'''
|
||||||
|
|
||||||
|
c3d_path = trc_path.replace('.trc', '.c3d')
|
||||||
|
marker_names, trc_data_np = extract_trc_data(trc_path)
|
||||||
|
create_c3d_file(c3d_path, marker_names, trc_data_np)
|
||||||
|
|
||||||
|
return c3d_path
|
||||||
|
|
||||||
|
|
||||||
## CLASSES
|
## CLASSES
|
||||||
class plotWindow():
|
class plotWindow():
|
||||||
'''
|
'''
|
||||||
@ -436,85 +512,3 @@ class plotWindow():
|
|||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
self.app.exec_()
|
self.app.exec_()
|
||||||
|
|
||||||
# Save c3d
|
|
||||||
def trc_to_c3d(project_dir, frame_rate, called_from):
|
|
||||||
'''
|
|
||||||
Converts.trc files to.c3d files
|
|
||||||
INPUT:
|
|
||||||
- project_dir: path to project folder
|
|
||||||
- frame_rate: frame rate of the video
|
|
||||||
- called_from: string that determines which.trc files to convert.
|
|
||||||
'triangulation' for.trc files from triangulation step
|
|
||||||
'filtering' for.trc files from filtering step
|
|
||||||
|
|
||||||
'''
|
|
||||||
# Determine the 3D pose folder
|
|
||||||
pose3d_dir = os.path.join(project_dir, 'pose-3d')
|
|
||||||
|
|
||||||
# Determine the .trc file name to read
|
|
||||||
trc_files = []
|
|
||||||
if called_from == 'triangulation':
|
|
||||||
trc_pattern = "*.trc"
|
|
||||||
trc_files = [os.path.basename(f) for f in glob.glob(os.path.join(pose3d_dir, trc_pattern)) if 'filt' not in f]
|
|
||||||
elif called_from == 'filtering':
|
|
||||||
trc_pattern = "*_filt_*.trc"
|
|
||||||
trc_files = [os.path.basename(f) for f in glob.glob(os.path.join(pose3d_dir, trc_pattern))]
|
|
||||||
else:
|
|
||||||
print("Invalid called_from value.")
|
|
||||||
|
|
||||||
for trc_file in trc_files:
|
|
||||||
# Extract marker names from the 4th row of the TRC file
|
|
||||||
with open(os.path.join(pose3d_dir, trc_file), 'r') as file:
|
|
||||||
lines = file.readlines()
|
|
||||||
marker_names_line = lines[3]
|
|
||||||
marker_names = marker_names_line.strip().split('\t')[2::3]
|
|
||||||
|
|
||||||
# Read the data frame (skiprows=5)
|
|
||||||
trc_data = pd.read_csv(os.path.join(pose3d_dir, trc_file), sep='\t', skiprows=5)
|
|
||||||
|
|
||||||
# Extract marker coordinates
|
|
||||||
marker_coords = trc_data.iloc[:, 2:].to_numpy().reshape(-1, len(marker_names), 3)
|
|
||||||
# marker_coords = np.nan_to_num(marker_coords, nan=0.0)
|
|
||||||
|
|
||||||
scale_factor = 1000
|
|
||||||
marker_coords = marker_coords * scale_factor
|
|
||||||
|
|
||||||
# Create a C3D writer
|
|
||||||
writer = c3d.Writer(point_rate=frame_rate, analog_rate=0, point_scale=1.0, point_units='mm', gen_scale=-1.0)
|
|
||||||
|
|
||||||
# Add marker parameters
|
|
||||||
writer.set_point_labels(marker_names)
|
|
||||||
|
|
||||||
# # Add marker descriptions (optional)
|
|
||||||
# marker_descriptions = [''] * len(marker_names)
|
|
||||||
# writer.point_group.add_param('DESCRIPTIONS', desc='Marker descriptions',
|
|
||||||
# bytes_per_element=-1, dimensions=[len(marker_names)],
|
|
||||||
# bytes=np.array(marker_descriptions, dtype=object))
|
|
||||||
|
|
||||||
# # Set the data start parameter
|
|
||||||
# data_start = writer.header.data_block
|
|
||||||
# writer.point_group.add_param('DATA_START', desc='Data start parameter',
|
|
||||||
# bytes_per_element=2, dimensions=[], bytes=struct.pack('<H', data_start))
|
|
||||||
|
|
||||||
# Create a C3D group for markers
|
|
||||||
markers_group = writer.point_group
|
|
||||||
|
|
||||||
# Add frame data
|
|
||||||
for frame in marker_coords:
|
|
||||||
# Add residual and camera columns
|
|
||||||
residuals = np.full((frame.shape[0], 1), 0.0) # Set residuals to 0.0
|
|
||||||
cameras = np.zeros((frame.shape[0], 1)) # Set cameras to 0
|
|
||||||
points = np.hstack((frame, residuals, cameras))
|
|
||||||
writer.add_frames([(points, np.array([]))])
|
|
||||||
|
|
||||||
# Set the trial start and end frames
|
|
||||||
writer.set_start_frame(1)
|
|
||||||
writer._set_last_frame(len(marker_coords))
|
|
||||||
|
|
||||||
# Write the C3D file
|
|
||||||
c3d_file_path = trc_file.replace('.trc', '.c3d')
|
|
||||||
with open(os.path.join(pose3d_dir, c3d_file_path), 'wb') as handle:
|
|
||||||
writer.write(handle)
|
|
||||||
|
|
||||||
print(f"-->c3d file saved: {c3d_file_path}")
|
|
@ -37,7 +37,7 @@ from filterpy.kalman import KalmanFilter, rts_smoother
|
|||||||
from filterpy.common import Q_discrete_white_noise
|
from filterpy.common import Q_discrete_white_noise
|
||||||
|
|
||||||
from Pose2Sim.common import plotWindow
|
from Pose2Sim.common import plotWindow
|
||||||
from Pose2Sim.common import trc_to_c3d
|
from Pose2Sim.common import convert_to_c3d
|
||||||
|
|
||||||
## AUTHORSHIP INFORMATION
|
## AUTHORSHIP INFORMATION
|
||||||
__author__ = "David Pagnon"
|
__author__ = "David Pagnon"
|
||||||
@ -416,6 +416,7 @@ def recap_filter3d(config, trc_path):
|
|||||||
gaussian_filter_sigma_kernel = int(config.get('filtering').get('gaussian').get('sigma_kernel'))
|
gaussian_filter_sigma_kernel = int(config.get('filtering').get('gaussian').get('sigma_kernel'))
|
||||||
loess_filter_nb_values = config.get('filtering').get('LOESS').get('nb_values_used')
|
loess_filter_nb_values = config.get('filtering').get('LOESS').get('nb_values_used')
|
||||||
median_filter_kernel_size = config.get('filtering').get('median').get('kernel_size')
|
median_filter_kernel_size = config.get('filtering').get('median').get('kernel_size')
|
||||||
|
make_c3d = config.get('filtering').get('make_c3d')
|
||||||
|
|
||||||
# Recap
|
# Recap
|
||||||
filter_mapping_recap = {
|
filter_mapping_recap = {
|
||||||
@ -428,6 +429,8 @@ def recap_filter3d(config, trc_path):
|
|||||||
}
|
}
|
||||||
logging.info(filter_mapping_recap[filter_type])
|
logging.info(filter_mapping_recap[filter_type])
|
||||||
logging.info(f'Filtered 3D coordinates are stored at {trc_path}.\n')
|
logging.info(f'Filtered 3D coordinates are stored at {trc_path}.\n')
|
||||||
|
if make_c3d:
|
||||||
|
logging.info('All filtered trc files have been converted to c3d.')
|
||||||
|
|
||||||
|
|
||||||
def filter_all(config):
|
def filter_all(config):
|
||||||
@ -497,10 +500,11 @@ def filter_all(config):
|
|||||||
# Q_filt = Q_filt.fillna(' ')
|
# Q_filt = Q_filt.fillna(' ')
|
||||||
Q_filt.to_csv(trc_o, sep='\t', index=False, header=None, lineterminator='\n')
|
Q_filt.to_csv(trc_o, sep='\t', index=False, header=None, lineterminator='\n')
|
||||||
|
|
||||||
|
# Save c3d
|
||||||
|
if make_c3d:
|
||||||
|
convert_to_c3d(t_out)
|
||||||
|
|
||||||
# Recap
|
# Recap
|
||||||
recap_filter3d(config, t_out)
|
recap_filter3d(config, t_out)
|
||||||
|
|
||||||
# Save c3d
|
|
||||||
if make_c3d == True:
|
|
||||||
trc_to_c3d(project_dir, frame_rate, called_from='filtering')
|
|
||||||
|
|
||||||
|
@ -23,14 +23,15 @@ OUTPUT:
|
|||||||
## INIT
|
## INIT
|
||||||
import os
|
import os
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from Pose2Sim.MarkerAugmenter import utilsDataman
|
|
||||||
import copy
|
import copy
|
||||||
import tensorflow as tf
|
import tensorflow as tf
|
||||||
from Pose2Sim.MarkerAugmenter.utils import TRC2numpy
|
|
||||||
import json
|
|
||||||
import glob
|
import glob
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from Pose2Sim.MarkerAugmenter import utilsDataman
|
||||||
|
from Pose2Sim.MarkerAugmenter.utils import TRC2numpy
|
||||||
|
from Pose2Sim.common import convert_to_c3d
|
||||||
|
|
||||||
|
|
||||||
## AUTHORSHIP INFORMATION
|
## AUTHORSHIP INFORMATION
|
||||||
__author__ = "Antoine Falisse, adapted by HunMin Kim"
|
__author__ = "Antoine Falisse, adapted by HunMin Kim"
|
||||||
@ -65,7 +66,6 @@ def augmentTRC(config_dict):
|
|||||||
project_dir = config_dict.get('project').get('project_dir')
|
project_dir = config_dict.get('project').get('project_dir')
|
||||||
pathInputTRCFile = os.path.realpath(os.path.join(project_dir, 'pose-3d'))
|
pathInputTRCFile = os.path.realpath(os.path.join(project_dir, 'pose-3d'))
|
||||||
pathOutputTRCFile = os.path.realpath(os.path.join(project_dir, 'pose-3d'))
|
pathOutputTRCFile = os.path.realpath(os.path.join(project_dir, 'pose-3d'))
|
||||||
pose_model = config_dict.get('pose').get('pose_model')
|
|
||||||
subject_height = config_dict.get('markerAugmentation').get('participant_height')
|
subject_height = config_dict.get('markerAugmentation').get('participant_height')
|
||||||
if subject_height is None or subject_height == 0 or subject_height==0:
|
if subject_height is None or subject_height == 0 or subject_height==0:
|
||||||
raise ValueError("Subject height is not set or invalid in the config file.")
|
raise ValueError("Subject height is not set or invalid in the config file.")
|
||||||
@ -73,6 +73,7 @@ def augmentTRC(config_dict):
|
|||||||
if not type(subject_height) == list:
|
if not type(subject_height) == list:
|
||||||
subject_height = [subject_height]
|
subject_height = [subject_height]
|
||||||
subject_mass = [subject_mass]
|
subject_mass = [subject_mass]
|
||||||
|
make_c3d = config_dict.get('markerAugmentation').get('make_c3d')
|
||||||
augmenterDir = os.path.dirname(utilsDataman.__file__)
|
augmenterDir = os.path.dirname(utilsDataman.__file__)
|
||||||
augmenterModelName = 'LSTM'
|
augmenterModelName = 'LSTM'
|
||||||
augmenter_model = 'v0.3'
|
augmenter_model = 'v0.3'
|
||||||
@ -151,8 +152,6 @@ def augmentTRC(config_dict):
|
|||||||
trc_data_data = trc_data[:,1:]
|
trc_data_data = trc_data[:,1:]
|
||||||
|
|
||||||
# Step 2: Normalize with reference marker position.
|
# Step 2: Normalize with reference marker position.
|
||||||
with open(os.path.join(augmenterModelDir, "metadata.json"), 'r') as f:
|
|
||||||
metadata = json.load(f)
|
|
||||||
referenceMarker_data = midhip_data # instead of trc_file.marker(referenceMarker) # change by HunMin
|
referenceMarker_data = midhip_data # instead of trc_file.marker(referenceMarker) # change by HunMin
|
||||||
norm_trc_data_data = np.zeros((trc_data_data.shape[0],
|
norm_trc_data_data = np.zeros((trc_data_data.shape[0],
|
||||||
trc_data_data.shape[1]))
|
trc_data_data.shape[1]))
|
||||||
@ -245,7 +244,15 @@ def augmentTRC(config_dict):
|
|||||||
# %% Return augmented .trc file
|
# %% Return augmented .trc file
|
||||||
trc_file.write(pathOutputTRCFile)
|
trc_file.write(pathOutputTRCFile)
|
||||||
|
|
||||||
logging.info(f'Augmented marker coordinates are stored at {pathOutputTRCFile}.\n')
|
logging.info(f'Augmented marker coordinates are stored at {pathOutputTRCFile}.')
|
||||||
|
|
||||||
|
# Save c3d
|
||||||
|
if make_c3d:
|
||||||
|
print(pathOutputTRCFile)
|
||||||
|
convert_to_c3d(pathOutputTRCFile)
|
||||||
|
logging.info(f'Augmented trc files have been converted to c3d.')
|
||||||
|
|
||||||
|
logging.info('\n')
|
||||||
|
|
||||||
return min_y_pos
|
return min_y_pos
|
||||||
|
|
||||||
|
@ -50,8 +50,7 @@ from anytree.importer import DictImporter
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from Pose2Sim.common import retrieve_calib_params, computeP, weighted_triangulation, \
|
from Pose2Sim.common import retrieve_calib_params, computeP, weighted_triangulation, \
|
||||||
reprojection, euclidean_distance, sort_stringlist_by_last_number, zup2yup
|
reprojection, euclidean_distance, sort_stringlist_by_last_number, zup2yup, convert_to_c3d
|
||||||
from Pose2Sim.common import trc_to_c3d
|
|
||||||
from Pose2Sim.skeletons import *
|
from Pose2Sim.skeletons import *
|
||||||
|
|
||||||
|
|
||||||
@ -312,7 +311,7 @@ def recap_triangulate(config, error, nb_cams_excluded, keypoints_names, cam_excl
|
|||||||
# if batch
|
# if batch
|
||||||
session_dir = os.path.realpath(os.path.join(project_dir, '..', '..'))
|
session_dir = os.path.realpath(os.path.join(project_dir, '..', '..'))
|
||||||
# if single trial
|
# if single trial
|
||||||
session_dir = os.getcwd() if not 'Config.toml' in session_dir else session_dir
|
session_dir = os.getcwd() if not 'Config.toml' in os.listdir(session_dir) else session_dir
|
||||||
calib_dir = [os.path.join(session_dir, c) for c in os.listdir(session_dir) if 'calib' in c.lower()][0]
|
calib_dir = [os.path.join(session_dir, c) for c in os.listdir(session_dir) if 'calib' in c.lower()][0]
|
||||||
calib_file = glob.glob(os.path.join(calib_dir, '*.toml'))[0] # lastly created calibration file
|
calib_file = glob.glob(os.path.join(calib_dir, '*.toml'))[0] # lastly created calibration file
|
||||||
calib = toml.load(calib_file)
|
calib = toml.load(calib_file)
|
||||||
@ -322,6 +321,7 @@ def recap_triangulate(config, error, nb_cams_excluded, keypoints_names, cam_excl
|
|||||||
likelihood_threshold = config.get('triangulation').get('likelihood_threshold_triangulation')
|
likelihood_threshold = config.get('triangulation').get('likelihood_threshold_triangulation')
|
||||||
show_interp_indices = config.get('triangulation').get('show_interp_indices')
|
show_interp_indices = config.get('triangulation').get('show_interp_indices')
|
||||||
interpolation_kind = config.get('triangulation').get('interpolation')
|
interpolation_kind = config.get('triangulation').get('interpolation')
|
||||||
|
make_c3d = config.get('triangulation').get('make_c3d')
|
||||||
handle_LR_swap = config.get('triangulation').get('handle_LR_swap')
|
handle_LR_swap = config.get('triangulation').get('handle_LR_swap')
|
||||||
undistort_points = config.get('triangulation').get('undistort_points')
|
undistort_points = config.get('triangulation').get('undistort_points')
|
||||||
|
|
||||||
@ -374,8 +374,11 @@ def recap_triangulate(config, error, nb_cams_excluded, keypoints_names, cam_excl
|
|||||||
str_cam_excluded_count += f'Camera {k}: {int(np.round(v*100))}%, '
|
str_cam_excluded_count += f'Camera {k}: {int(np.round(v*100))}%, '
|
||||||
logging.info(str_cam_excluded_count)
|
logging.info(str_cam_excluded_count)
|
||||||
logging.info(f'\n3D coordinates are stored at {trc_path[n]}.')
|
logging.info(f'\n3D coordinates are stored at {trc_path[n]}.')
|
||||||
|
|
||||||
logging.info(f'\n\nLimb swapping was {"handled" if handle_LR_swap else "not handled"}.')
|
logging.info('\n\n')
|
||||||
|
if make_c3d:
|
||||||
|
logging.info('All trc files have been converted to c3d.')
|
||||||
|
logging.info(f'Limb swapping was {"handled" if handle_LR_swap else "not handled"}.')
|
||||||
logging.info(f'Lens distortions were {"taken into account" if undistort_points else "not taken into account"}.')
|
logging.info(f'Lens distortions were {"taken into account" if undistort_points else "not taken into account"}.')
|
||||||
|
|
||||||
|
|
||||||
@ -693,7 +696,7 @@ def triangulate_all(config):
|
|||||||
# if batch
|
# if batch
|
||||||
session_dir = os.path.realpath(os.path.join(project_dir, '..', '..'))
|
session_dir = os.path.realpath(os.path.join(project_dir, '..', '..'))
|
||||||
# if single trial
|
# if single trial
|
||||||
session_dir = os.getcwd() if not 'Config.toml' in session_dir else session_dir
|
session_dir = os.getcwd() if not 'Config.toml' in os.listdir(session_dir) else session_dir
|
||||||
multi_person = config.get('project').get('multi_person')
|
multi_person = config.get('project').get('multi_person')
|
||||||
pose_model = config.get('pose').get('pose_model')
|
pose_model = config.get('pose').get('pose_model')
|
||||||
frame_range = config.get('project').get('frame_range')
|
frame_range = config.get('project').get('frame_range')
|
||||||
@ -705,7 +708,7 @@ def triangulate_all(config):
|
|||||||
undistort_points = config.get('triangulation').get('undistort_points')
|
undistort_points = config.get('triangulation').get('undistort_points')
|
||||||
make_c3d = config.get('triangulation').get('make_c3d')
|
make_c3d = config.get('triangulation').get('make_c3d')
|
||||||
frame_rate = config.get('project').get('frame_rate')
|
frame_rate = config.get('project').get('frame_rate')
|
||||||
|
|
||||||
calib_dir = [os.path.join(session_dir, c) for c in os.listdir(session_dir) if 'calib' in c.lower()][0]
|
calib_dir = [os.path.join(session_dir, c) for c in os.listdir(session_dir) if 'calib' in c.lower()][0]
|
||||||
try:
|
try:
|
||||||
calib_file = glob.glob(os.path.join(calib_dir, '*.toml'))[0] # lastly created calibration file
|
calib_file = glob.glob(os.path.join(calib_dir, '*.toml'))[0] # lastly created calibration file
|
||||||
@ -909,23 +912,25 @@ def triangulate_all(config):
|
|||||||
|
|
||||||
# Create TRC file
|
# Create TRC file
|
||||||
trc_paths = [make_trc(config, Q_tot[n], keypoints_names, f_range, id_person=n) for n in range(len(Q_tot))]
|
trc_paths = [make_trc(config, Q_tot[n], keypoints_names, f_range, id_person=n) for n in range(len(Q_tot))]
|
||||||
|
if make_c3d:
|
||||||
|
c3d_paths = [convert_to_c3d(t) for t in trc_paths]
|
||||||
|
|
||||||
# Reorder TRC files
|
# Reorder TRC files
|
||||||
if multi_person and reorder_trc and len(trc_paths)>1:
|
if multi_person and reorder_trc and len(trc_paths)>1:
|
||||||
trc_id = retrieve_right_trc_order(trc_paths)
|
trc_id = retrieve_right_trc_order(trc_paths)
|
||||||
[os.rename(t, t+'.old') for t in trc_paths]
|
[os.rename(t, t+'.old') for t in trc_paths]
|
||||||
[os.rename(t+'.old', trc_paths[i]) for i, t in zip(trc_id,trc_paths)]
|
[os.rename(t+'.old', trc_paths[i]) for i, t in zip(trc_id,trc_paths)]
|
||||||
|
if make_c3d:
|
||||||
|
[os.rename(c, c+'.old') for c in c3d_paths]
|
||||||
|
[os.rename(c+'.old', c3d_paths[i]) for i, c in zip(trc_id,c3d_paths)]
|
||||||
error_tot = [error_tot[i] for i in trc_id]
|
error_tot = [error_tot[i] for i in trc_id]
|
||||||
nb_cams_excluded_tot = [nb_cams_excluded_tot[i] for i in trc_id]
|
nb_cams_excluded_tot = [nb_cams_excluded_tot[i] for i in trc_id]
|
||||||
cam_excluded_count = [cam_excluded_count[i] for i in trc_id]
|
cam_excluded_count = [cam_excluded_count[i] for i in trc_id]
|
||||||
interp_frames = [interp_frames[i] for i in trc_id]
|
interp_frames = [interp_frames[i] for i in trc_id]
|
||||||
non_interp_frames = [non_interp_frames[i] for i in trc_id]
|
non_interp_frames = [non_interp_frames[i] for i in trc_id]
|
||||||
|
|
||||||
logging.info('\nThe trc files have been renamed to match the order of the static sequences.')
|
logging.info('\nThe trc and c3d files have been renamed to match the order of the static sequences.')
|
||||||
|
|
||||||
|
|
||||||
# Recap message
|
# Recap message
|
||||||
recap_triangulate(config, error_tot, nb_cams_excluded_tot, keypoints_names, cam_excluded_count, interp_frames, non_interp_frames, trc_paths)
|
recap_triangulate(config, error_tot, nb_cams_excluded_tot, keypoints_names, cam_excluded_count, interp_frames, non_interp_frames, trc_paths)
|
||||||
|
|
||||||
# Save c3d
|
|
||||||
if make_c3d == True:
|
|
||||||
trc_to_c3d(project_dir, frame_rate, called_from='triangulation')
|
|
||||||
|
Loading…
Reference in New Issue
Block a user