-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathrun_ik_testing.py
130 lines (106 loc) · 6.31 KB
/
run_ik_testing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!python36
# -*- coding: utf-8 -*-
"""
NCams Toolbox
Copyright 2019-2020 Charles M Greenspon, Anton Sobinov
https://github.com/CMGreenspon/NCams
"""
import os
import matplotlib.pyplot as mpl_pp
from scipy.spatial.transform import Rotation as R
import ncams
def import_kinematics():
# Translate the triangulated data into OSim trc format
BASE_DIR = os.path.join('C://', 'FLIR_cameras', 'PublicExample')
proj_path = os.path.join(BASE_DIR, '2019.12.20_8camsNoMarkers-AS-2019-12-23')
triangulated_path = os.path.join(proj_path, 'triangulated_full_rank_0.9', 'session4')
ik_dir = os.path.join(proj_path, 'inverse_kinematics')
if not os.path.isdir(ik_dir):
os.mkdir(ik_dir)
# load a csv file into a dictionary by specified column names
marker_name_dict = ncams.utils.dic_from_csv('marker_meta.csv', 'sDlcMarker', 'sOpenSimMarker')
triangulated_csv = os.path.join(triangulated_path, 'triangulated_points_4_smoothed.csv')
# rotate the data from the NCams coordinate system
# preview the rotations by loading the model and using 'File->Preview experimental data'
# the right click on the loaded kinematics and 'Transform'. If using our model and our
# calibration, the rotations should be as described below:
r = R.from_euler('zyx', [0, 90, 180], degrees=True)
# scipy.spatial.transform.Rotation.apply returns an ndarray with vertical vectors, so the
# function is changed in the lambda
rot = lambda v: r.apply(v)[0].tolist()
suffixes = ['remote', 'marshmallow', 'wave', 'pen']
frame_ranges = [(103, 140), (260, 360), (510, 650), (1919, 2019)]
for frame_range, suffix in zip(frame_ranges, suffixes):
trc_file = os.path.join(ik_dir, 'triangulated_4_{}.trc'.format(suffix))
# makes an IK config
ik_file = os.path.join(ik_dir, 'full_arm_model_IK_4_{}.xml'.format(suffix))
ik_out_mot_file = os.path.join(ik_dir, 'out_inv_kin_4_{}.mot'.format(suffix))
ncams.inverse_kinematics.triangulated_to_trc(
triangulated_csv, trc_file, marker_name_dict,
data_unit_convert=lambda x: x*100, # dm to mm
rate=50, zero_marker='scapula_anterior', frame_range=frame_range, rotation=rot,
ik_file=ik_file, ik_out_mot_file=ik_out_mot_file)
def filter_joint_angles():
# Translate the triangulated data into OSim trc format
BASE_DIR = os.path.join('C://', 'FLIR_cameras', 'PublicExample')
proj_path = os.path.join(BASE_DIR, '2019.12.20_8camsNoMarkers-AS-2019-12-23')
ik_dir = os.path.join(proj_path, 'inverse_kinematics')
suffixes = ['remote', 'marshmallow', 'wave', 'pen']
for suffix in suffixes:
ik_out_mot_file = os.path.join(ik_dir, 'out_inv_kin_4_{}.mot'.format(suffix))
ik_filtered_mot_file = os.path.join(ik_dir, 'out_inv_kin_4_{}_filtered.mot'.format(suffix))
ncams.inverse_kinematics.smooth_motion(ik_out_mot_file, ik_filtered_mot_file,
median_kernel_size=11)
def make_combined_videos():
# Translate the triangulated data into OSim trc format
BASE_DIR = os.path.join('C://', 'FLIR_cameras', 'PublicExample')
proj_path = os.path.join(BASE_DIR, '2019.12.20_8camsNoMarkers-AS-2019-12-23')
config_path = os.path.join(proj_path, 'config.yaml')
ik_dir = os.path.join(proj_path, 'inverse_kinematics')
triangulated_path = os.path.join(proj_path, 'triangulated_full_rank_0.9', 'session4')
triangulated_csv = os.path.join(triangulated_path, 'triangulated_points_4_smoothed.csv')
suffixes = ['remote', 'marshmallow', 'wave', 'pen']
frame_ranges = [(103, 140), (260, 360), (510, 650), (1919, 2019)]
# estimate manually with an external program, e.g. MPC-HC, easier if recorded more than one loop
# from OpenSim
frame_offsets = [23, 0, 7, 3]
video_path = os.path.join(BASE_DIR, 'exp_session_2019.12.20_videos', '4_cam19335177.mp4')
for frame_range, suffix, frame_offset in zip(frame_ranges, suffixes, frame_offsets):
# Load the motion generated during inverse kinematics and play it.
# To record a video, press a camera button in the top right corner of the viewer. To stop
# recording, press the button again. Save the video path to 'ik_video_path'.
ik_video_path = os.path.join(ik_dir, '4_{}.webm'.format(suffix)) # manually set filename
output_path = os.path.join(ik_dir, '4_{}_19335177_4.mp4'.format(suffix))
ncams.make_triangulation_video(
video_path, triangulated_csv, skeleton_config=config_path,
frame_range=frame_range, output_path=output_path,
thrd_video_path=ik_video_path,
thrd_video_frame_offset=frame_offset, # if the IK movement starts later
third_video_crop_hw=[slice(0, -100), slice(350, -700)], # crops the IK video
figure_dpi=300,
ranges=((-0.33, 3), (-2, 2), (-1.33, 6.74)), # manually set ranges for 3D plot
plot_markers=False, horizontal_subplots=True)
def make_gifs_and_timeseries():
BASE_DIR = os.path.join('C://', 'FLIR_cameras', 'PublicExample')
proj_path = os.path.join(BASE_DIR, '2019.12.20_8camsNoMarkers-AS-2019-12-23')
ik_dir = os.path.join(proj_path, 'inverse_kinematics')
filenames = ['4_marshmallow_19335177_4', '4_pen_19335177_4', '4_remote_19335177_4',
'4_wave_19335177_4']
# filenames = ['4_marshmallow_19335177_4']
for filename in filenames:
video = os.path.join(ik_dir, '{}.mp4'.format(filename))
video_images_dir = os.path.join(ik_dir, '{}'.format(filename))
ncams.image_tools.video_to_images(video, output_directory=ik_dir, output_format='jpeg')
video_images = ncams.utils.get_image_list(path=video_images_dir)
gif = os.path.join(ik_dir, '{}.gif'.format(filename))
ncams.image_tools.images_to_video(video_images, gif, fps=25)
video = os.path.join(ik_dir, '{}_vertical2.mp4'.format(filename))
fig_name = os.path.join(ik_dir, '{}_timeseries.png'.format(filename))
ncams.image_tools.video_to_timeseries(video, fig_name, num_images=5, figure_size=(9, 5),
figure_dpi=200,
crop_hw=[slice(450, -350), slice(2275, -2150)])
if __name__ == '__main__':
# import_kinematics()
# filter_joint_angles()
# make_combined_videos()
make_gifs_and_timeseries()