sports2d 0.8.14__tar.gz → 0.8.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sports2d-0.8.14 → sports2d-0.8.16}/PKG-INFO +1 -1
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/Utilities/tests.py +2 -2
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/process.py +40 -17
- {sports2d-0.8.14 → sports2d-0.8.16}/sports2d.egg-info/PKG-INFO +1 -1
- {sports2d-0.8.14 → sports2d-0.8.16}/.github/workflows/continuous-integration.yml +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/.github/workflows/joss_pdf.yml +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/.github/workflows/publish-on-release.yml +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/.gitignore +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/CITATION.cff +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/Demo_plots.png +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/Demo_results.png +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/Demo_terminal.png +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/Person_selection.png +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/Video_tuto_Sports2D_Colab.png +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/joint_convention.png +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/paper.bib +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/paper.md +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/sports2d_blender.gif +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Content/sports2d_opensim.gif +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/LICENSE +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/README.md +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/Demo/Config_demo.toml +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/Demo/demo.mp4 +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/Sports2D.ipynb +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/Sports2D.py +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/Utilities/__init__.py +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/Utilities/common.py +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/Utilities/filter.py +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/Sports2D/__init__.py +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/pyproject.toml +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/setup.cfg +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/sports2d.egg-info/SOURCES.txt +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/sports2d.egg-info/dependency_links.txt +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/sports2d.egg-info/entry_points.txt +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/sports2d.egg-info/requires.txt +0 -0
- {sports2d-0.8.14 → sports2d-0.8.16}/sports2d.egg-info/top_level.txt +0 -0
|
@@ -37,6 +37,7 @@ def test_workflow():
|
|
|
37
37
|
Test the workflow of Sports2D.
|
|
38
38
|
'''
|
|
39
39
|
|
|
40
|
+
from Sports2D import Sports2D
|
|
40
41
|
root_dir = os.path.dirname(os.path.abspath(__file__))
|
|
41
42
|
os.chdir(root_dir)
|
|
42
43
|
|
|
@@ -53,7 +54,6 @@ def test_workflow():
|
|
|
53
54
|
config_dict.get("base").update({"show_realtime_results":False})
|
|
54
55
|
config_dict.get("post-processing").update({"show_graphs":False})
|
|
55
56
|
|
|
56
|
-
from Sports2D import Sports2D
|
|
57
57
|
Sports2D.process(config_dict)
|
|
58
58
|
|
|
59
59
|
|
|
@@ -82,7 +82,7 @@ def test_workflow():
|
|
|
82
82
|
"--pose_model", "body", "--mode", """{'pose_class':'RTMO', 'pose_model':'https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-m_16xb16-600e_body7-640x640-39e78cc4_20231211.zip', 'pose_input_size':[640, 640]}"""]
|
|
83
83
|
subprocess.run(demo_cmd3, check=True, capture_output=True, text=True, encoding='utf-8')
|
|
84
84
|
|
|
85
|
-
# With a time range, inverse kinematics, marker augmentation
|
|
85
|
+
# With a time range, inverse kinematics, marker augmentation
|
|
86
86
|
demo_cmd4 = ["sports2d", "--person_ordering_method", "greatest_displacement", "--show_realtime_results", "False", "--show_graphs", "False",
|
|
87
87
|
"--time_range", "1.2", "2.7",
|
|
88
88
|
"--do_ik", "True", "--use_augmentation", "True",
|
|
@@ -1653,7 +1653,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1653
1653
|
|
|
1654
1654
|
# Process coordinates and compute angles
|
|
1655
1655
|
valid_X, valid_Y, valid_scores = [], [], []
|
|
1656
|
-
valid_X_flipped, valid_angles = [], []
|
|
1656
|
+
valid_X_flipped, valid_angles_flipped, valid_angles = [], [], []
|
|
1657
1657
|
for person_idx in range(len(keypoints)):
|
|
1658
1658
|
if load_trc_px:
|
|
1659
1659
|
person_X = keypoints[person_idx][:,0]
|
|
@@ -1699,7 +1699,17 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1699
1699
|
else:
|
|
1700
1700
|
ang = np.nan
|
|
1701
1701
|
person_angles.append(ang)
|
|
1702
|
+
|
|
1703
|
+
# flip angles on the left side if flip_left_right false
|
|
1704
|
+
if len(visible_side) <= person_idx:
|
|
1705
|
+
visible_side += ['auto'] # set to 'auto' if list too short
|
|
1706
|
+
if visible_side[person_idx] == 'left' and not flip_left_right:
|
|
1707
|
+
person_angles_flipped = list(-np.array(person_angles))
|
|
1708
|
+
else:
|
|
1709
|
+
person_angles_flipped = person_angles.copy()
|
|
1710
|
+
|
|
1702
1711
|
valid_angles.append(person_angles)
|
|
1712
|
+
valid_angles_flipped.append(person_angles_flipped)
|
|
1703
1713
|
valid_X_flipped.append(person_X_flipped)
|
|
1704
1714
|
valid_X.append(person_X)
|
|
1705
1715
|
valid_Y.append(person_Y)
|
|
@@ -1714,7 +1724,8 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1714
1724
|
img = draw_keypts(img, valid_X, valid_Y, valid_scores, cmap_str='RdYlGn')
|
|
1715
1725
|
img = draw_skel(img, valid_X, valid_Y, pose_model)
|
|
1716
1726
|
if calculate_angles:
|
|
1717
|
-
|
|
1727
|
+
|
|
1728
|
+
img = draw_angles(img, valid_X, valid_Y, valid_angles_flipped, valid_X_flipped, new_keypoints_ids, new_keypoints_names, angle_names, display_angle_values_on=display_angle_values_on, colors=colors, fontSize=fontSize, thickness=thickness)
|
|
1718
1729
|
cv2.imshow(f'{video_file} Sports2D', img)
|
|
1719
1730
|
if (cv2.waitKey(1) & 0xFF) == ord('q') or (cv2.waitKey(1) & 0xFF) == 27:
|
|
1720
1731
|
break
|
|
@@ -1936,6 +1947,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1936
1947
|
f'xy_origin: {xy_origin if not xy_origin=="auto" else f"auto (estimation: {[round(c) for c in xy_origin_estim]})"} px.')
|
|
1937
1948
|
|
|
1938
1949
|
# Coordinates in m
|
|
1950
|
+
new_visible_side = []
|
|
1939
1951
|
for i in range(len(trc_data)):
|
|
1940
1952
|
if not np.array(trc_data[i].iloc[:,1:] ==0).all():
|
|
1941
1953
|
# Automatically determine visible side
|
|
@@ -1984,7 +1996,11 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1984
1996
|
if make_c3d:
|
|
1985
1997
|
c3d_path = convert_to_c3d(str(pose_path_person_m_i))
|
|
1986
1998
|
logging.info(f'Pose in meters saved to {pose_path_person_m_i.resolve()}. {"Also saved in c3d format." if make_c3d else ""}')
|
|
1987
|
-
|
|
1999
|
+
else:
|
|
2000
|
+
visible_side_i = 'none'
|
|
2001
|
+
new_visible_side += [visible_side_i]
|
|
2002
|
+
else:
|
|
2003
|
+
new_visible_side = visible_side.copy()
|
|
1988
2004
|
|
|
1989
2005
|
|
|
1990
2006
|
|
|
@@ -2049,7 +2065,11 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
2049
2065
|
for i, idx_person in enumerate(selected_persons):
|
|
2050
2066
|
angles_path_person = angles_output_path.parent / (angles_output_path.stem + f'_person{i:02d}.mot')
|
|
2051
2067
|
all_frames_angles_person = pd.DataFrame(all_frames_angles_homog[:,idx_person,:], columns=angle_names)
|
|
2052
|
-
|
|
2068
|
+
|
|
2069
|
+
# Flip angles for left side when flip_left_right false
|
|
2070
|
+
if new_visible_side[i] == 'left' and not flip_left_right:
|
|
2071
|
+
all_frames_angles_homog[:, idx_person, :] = -all_frames_angles_homog[:, idx_person, :]
|
|
2072
|
+
|
|
2053
2073
|
# Delete person if less than 4 valid frames
|
|
2054
2074
|
angle_nan_count = len(np.where(all_frames_angles_person.sum(axis=1)==0)[0])
|
|
2055
2075
|
if frame_count - frame_range[0] - angle_nan_count <= 4:
|
|
@@ -2151,19 +2171,22 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
2151
2171
|
new_keypoints_ids = list(range(len(new_keypoints_ids)))
|
|
2152
2172
|
|
|
2153
2173
|
# Draw pose and angles
|
|
2174
|
+
if 'first_trim' not in locals():
|
|
2175
|
+
first_trim, last_trim = 0, frame_count-1
|
|
2154
2176
|
for frame_count, (frame, valid_X, valid_X_flipped, valid_Y, valid_scores, valid_angles) in enumerate(zip(frames, all_frames_X_processed, all_frames_X_flipped_processed, all_frames_Y_processed, all_frames_scores_processed, all_frames_angles_processed)):
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2177
|
+
if frame_count >= first_trim and frame_count <= last_trim:
|
|
2178
|
+
img = frame.copy()
|
|
2179
|
+
img = draw_bounding_box(img, valid_X, valid_Y, colors=colors, fontSize=fontSize, thickness=thickness)
|
|
2180
|
+
img = draw_keypts(img, valid_X, valid_Y, valid_scores, cmap_str='RdYlGn')
|
|
2181
|
+
img = draw_skel(img, valid_X, valid_Y, pose_model_with_new_ids)
|
|
2182
|
+
if calculate_angles:
|
|
2183
|
+
img = draw_angles(img, valid_X, valid_Y, valid_angles, valid_X_flipped, new_keypoints_ids, new_keypoints_names, angle_names, display_angle_values_on=display_angle_values_on, colors=colors, fontSize=fontSize, thickness=thickness)
|
|
2184
|
+
|
|
2185
|
+
# Save video or images
|
|
2186
|
+
if save_vid:
|
|
2187
|
+
out_vid.write(img)
|
|
2188
|
+
if save_img:
|
|
2189
|
+
cv2.imwrite(str((img_output_dir / f'{output_dir_name}_{(frame_count+frame_range[0]):06d}.png')), img)
|
|
2167
2190
|
|
|
2168
2191
|
if save_vid:
|
|
2169
2192
|
out_vid.release()
|
|
@@ -2215,7 +2238,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
2215
2238
|
# masses.append(DEFAULT_MASS)
|
|
2216
2239
|
logging.info(f'Less than 4 valid frames. Deleting person.')
|
|
2217
2240
|
else:
|
|
2218
|
-
if
|
|
2241
|
+
if new_visible_side[i] == 'none':
|
|
2219
2242
|
logging.info(f'Skipping marker augmentation and inverse kinematics because visible_side is "none".')
|
|
2220
2243
|
# heights_m.append(DEFAULT_HEIGHT)
|
|
2221
2244
|
# masses.append(DEFAULT_MASS)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|