sports2d 0.5.4__tar.gz → 0.5.6__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.5.4 → sports2d-0.5.6}/PKG-INFO +3 -2
- {sports2d-0.5.4 → sports2d-0.5.6}/README.md +2 -1
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/Demo/Config_demo.toml +1 -1
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/process.py +56 -35
- {sports2d-0.5.4 → sports2d-0.5.6}/setup.cfg +1 -1
- {sports2d-0.5.4 → sports2d-0.5.6}/sports2d.egg-info/PKG-INFO +3 -2
- {sports2d-0.5.4 → sports2d-0.5.6}/LICENSE +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/Demo/demo.mp4 +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/Sports2D.py +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/Utilities/__init__.py +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/Utilities/common.py +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/Utilities/filter.py +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/Utilities/skeletons.py +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/Utilities/tests.py +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/Sports2D/__init__.py +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/pyproject.toml +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/setup.py +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/sports2d.egg-info/SOURCES.txt +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/sports2d.egg-info/dependency_links.txt +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/sports2d.egg-info/entry_points.txt +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/sports2d.egg-info/not-zip-safe +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/sports2d.egg-info/requires.txt +0 -0
- {sports2d-0.5.4 → sports2d-0.5.6}/sports2d.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sports2d
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.6
|
|
4
4
|
Summary: Detect pose and compute 2D joint angles from a video.
|
|
5
5
|
Home-page: https://github.com/davidpagnon/Sports2D
|
|
6
6
|
Author: David Pagnon
|
|
@@ -233,9 +233,10 @@ Note that it does not take distortions into account, and that it will be less ac
|
|
|
233
233
|
### Too slow for you?
|
|
234
234
|
|
|
235
235
|
**Quick fixes:**
|
|
236
|
-
- Use
|
|
236
|
+
- Use ` --save_vid false --save_img false --show_realtime_results false`: Will not save images or videos, and will not display the results in real time.
|
|
237
237
|
- Use `--mode lightweight`: Will use a lighter version of RTMPose, which is faster but less accurate.
|
|
238
238
|
- Use `--det_frequency 50`: Will detect poses only every 50 frames, and track keypoints in between, which is faster.
|
|
239
|
+
- Use `--multiperson false`: Can be used if one single person is present in the video. Otherwise, persons' IDs may be mixed up.
|
|
239
240
|
- Use `--load_trc <path_to_file_px.trc>`: Will use pose estimation results from a file. Useful if you want to use different parameters for pixel to meter conversion or angle calculation without running detection and pose estimation all over.
|
|
240
241
|
|
|
241
242
|
<br>
|
|
@@ -193,9 +193,10 @@ Note that it does not take distortions into account, and that it will be less ac
|
|
|
193
193
|
### Too slow for you?
|
|
194
194
|
|
|
195
195
|
**Quick fixes:**
|
|
196
|
-
- Use
|
|
196
|
+
- Use ` --save_vid false --save_img false --show_realtime_results false`: Will not save images or videos, and will not display the results in real time.
|
|
197
197
|
- Use `--mode lightweight`: Will use a lighter version of RTMPose, which is faster but less accurate.
|
|
198
198
|
- Use `--det_frequency 50`: Will detect poses only every 50 frames, and track keypoints in between, which is faster.
|
|
199
|
+
- Use `--multiperson false`: Can be used if one single person is present in the video. Otherwise, persons' IDs may be mixed up.
|
|
199
200
|
- Use `--load_trc <path_to_file_px.trc>`: Will use pose estimation results from a file. Useful if you want to use different parameters for pixel to meter conversion or angle calculation without running detection and pose estimation all over.
|
|
200
201
|
|
|
201
202
|
<br>
|
|
@@ -21,7 +21,7 @@ compare = false # Not implemented yet
|
|
|
21
21
|
|
|
22
22
|
# Video parameters
|
|
23
23
|
time_range = [] # [] for the whole video, or [start_time, end_time] (in seconds), or [[start_time1, end_time1], [start_time2, end_time2], ...]
|
|
24
|
-
video_dir = '' # If empty,
|
|
24
|
+
video_dir = '' # If empty, video dir is current dir
|
|
25
25
|
|
|
26
26
|
# Webcam parameters
|
|
27
27
|
webcam_id = 0 # your webcam id (0 is default)
|
|
@@ -1101,7 +1101,7 @@ def get_personID_with_highest_scores(all_frames_scores):
|
|
|
1101
1101
|
return person_id
|
|
1102
1102
|
|
|
1103
1103
|
|
|
1104
|
-
def compute_floor_line(trc_data, keypoint_names = ['LBigToe', 'RBigToe'],
|
|
1104
|
+
def compute_floor_line(trc_data, keypoint_names = ['LBigToe', 'RBigToe'], toe_speed_below = 1.0, tot_speed_above=2.0):
|
|
1105
1105
|
'''
|
|
1106
1106
|
Compute the floor line equation and angle
|
|
1107
1107
|
from the feet keypoints when they have zero speed.
|
|
@@ -1111,19 +1111,23 @@ def compute_floor_line(trc_data, keypoint_names = ['LBigToe', 'RBigToe'], speed_
|
|
|
1111
1111
|
INPUTS:
|
|
1112
1112
|
- trc_data: pd.DataFrame. The trc data
|
|
1113
1113
|
- keypoint_names: list of str. The names of the keypoints to use
|
|
1114
|
-
-
|
|
1114
|
+
- toe_speed_below: float. The speed threshold (px/frame) below which the keypoints are considered as not moving
|
|
1115
1115
|
|
|
1116
1116
|
OUTPUT:
|
|
1117
1117
|
- angle: float. The angle of the floor line in radians
|
|
1118
1118
|
- xy_origin: list. The origin of the floor line
|
|
1119
1119
|
'''
|
|
1120
1120
|
|
|
1121
|
+
# Remove frames where the person is mostly not moving (outlier)
|
|
1122
|
+
av_speeds = np.nanmean([np.insert(np.linalg.norm(trc_data[kpt].diff(), axis=1)[1:],0,0) for kpt in trc_data.columns.unique()[1:]], axis=0)
|
|
1123
|
+
trc_data = trc_data[av_speeds>tot_speed_above]
|
|
1124
|
+
|
|
1121
1125
|
# Retrieve zero-speed coordinates for the foot
|
|
1122
1126
|
low_speeds_X, low_speeds_Y = [], []
|
|
1123
1127
|
for kpt in keypoint_names:
|
|
1124
1128
|
speeds = np.linalg.norm(trc_data[kpt].diff(), axis=1)
|
|
1125
1129
|
|
|
1126
|
-
low_speed_frames = trc_data[speeds<
|
|
1130
|
+
low_speed_frames = trc_data[speeds<toe_speed_below].index
|
|
1127
1131
|
low_speeds_coords = trc_data[kpt].loc[low_speed_frames]
|
|
1128
1132
|
low_speeds_coords = low_speeds_coords[low_speeds_coords!=0]
|
|
1129
1133
|
|
|
@@ -1416,7 +1420,6 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1416
1420
|
gaussian_filter_kernel = config_dict.get('post-processing').get('gaussian').get('sigma_kernel')
|
|
1417
1421
|
loess_filter_kernel = config_dict.get('post-processing').get('loess').get('nb_values_used')
|
|
1418
1422
|
median_filter_kernel = config_dict.get('post-processing').get('median').get('kernel_size')
|
|
1419
|
-
butterworth_filter_cutoff /= slowmo_factor
|
|
1420
1423
|
filter_options = [do_filter, filter_type,
|
|
1421
1424
|
butterworth_filter_order, butterworth_filter_cutoff, frame_rate,
|
|
1422
1425
|
gaussian_filter_kernel, loess_filter_kernel, median_filter_kernel]
|
|
@@ -1453,6 +1456,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1453
1456
|
logging.warning('Webcam input: the framerate may vary. If results are filtered, Sports2D will use the average framerate as input.')
|
|
1454
1457
|
else:
|
|
1455
1458
|
cap, out_vid, cam_width, cam_height, fps = setup_video(video_file_path, save_vid, vid_output_path)
|
|
1459
|
+
fps *= slowmo_factor
|
|
1456
1460
|
start_time = get_start_time_ffmpeg(video_file_path)
|
|
1457
1461
|
frame_range = [int((time_range[0]-start_time) * frame_rate), int((time_range[1]-start_time) * frame_rate)] if time_range else [0, int(cap.get(cv2.CAP_PROP_FRAME_COUNT))]
|
|
1458
1462
|
frame_iterator = tqdm(range(*frame_range)) # use a progress bar
|
|
@@ -1466,7 +1470,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1466
1470
|
if load_trc:
|
|
1467
1471
|
if not '_px' in str(load_trc):
|
|
1468
1472
|
logging.error(f'\n{load_trc} file needs to be in px, not in meters.')
|
|
1469
|
-
logging.info(f'\nUsing a pose file instead of running pose tracking {load_trc}.')
|
|
1473
|
+
logging.info(f'\nUsing a pose file instead of running pose estimation and tracking: {load_trc}.')
|
|
1470
1474
|
# Load pose file in px
|
|
1471
1475
|
Q_coords, _, _, keypoints_names, _ = read_trc(load_trc)
|
|
1472
1476
|
keypoints_ids = [i for i in range(len(keypoints_names))]
|
|
@@ -1501,7 +1505,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1501
1505
|
frame_count = 0
|
|
1502
1506
|
while cap.isOpened():
|
|
1503
1507
|
# Skip to the starting frame
|
|
1504
|
-
if frame_count < frame_range[0]:
|
|
1508
|
+
if frame_count < frame_range[0] and not load_trc:
|
|
1505
1509
|
cap.read()
|
|
1506
1510
|
frame_count += 1
|
|
1507
1511
|
continue
|
|
@@ -1528,6 +1532,8 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1528
1532
|
|
|
1529
1533
|
# Retrieve pose or Estimate pose and track people
|
|
1530
1534
|
if load_trc:
|
|
1535
|
+
if frame_nb >= len(keypoints_all):
|
|
1536
|
+
break
|
|
1531
1537
|
keypoints = keypoints_all[frame_nb]
|
|
1532
1538
|
scores = scores_all[frame_nb]
|
|
1533
1539
|
else:
|
|
@@ -1545,18 +1551,23 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1545
1551
|
valid_X, valid_Y, valid_scores = [], [], []
|
|
1546
1552
|
valid_X_flipped, valid_angles = [], []
|
|
1547
1553
|
for person_idx in range(len(keypoints)):
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1554
|
+
if load_trc:
|
|
1555
|
+
person_X = keypoints[person_idx][:,0]
|
|
1556
|
+
person_Y = keypoints[person_idx][:,1]
|
|
1557
|
+
person_scores = scores[person_idx]
|
|
1558
|
+
else:
|
|
1559
|
+
# Retrieve keypoints and scores for the person, remove low-confidence keypoints
|
|
1560
|
+
person_X, person_Y = np.where(scores[person_idx][:, np.newaxis] < keypoint_likelihood_threshold, np.nan, keypoints[person_idx]).T
|
|
1561
|
+
person_scores = np.where(scores[person_idx] < keypoint_likelihood_threshold, np.nan, scores[person_idx])
|
|
1562
|
+
|
|
1563
|
+
# Skip person if the fraction of valid detected keypoints is too low
|
|
1564
|
+
enough_good_keypoints = len(person_scores[~np.isnan(person_scores)]) >= len(person_scores) * keypoint_number_threshold
|
|
1565
|
+
scores_of_good_keypoints = person_scores[~np.isnan(person_scores)]
|
|
1566
|
+
average_score_of_remaining_keypoints_is_enough = (np.nanmean(scores_of_good_keypoints) if len(scores_of_good_keypoints)>0 else 0) >= average_likelihood_threshold
|
|
1567
|
+
if not enough_good_keypoints or not average_score_of_remaining_keypoints_is_enough:
|
|
1568
|
+
person_X = np.full_like(person_X, np.nan)
|
|
1569
|
+
person_Y = np.full_like(person_Y, np.nan)
|
|
1570
|
+
person_scores = np.full_like(person_scores, np.nan)
|
|
1560
1571
|
valid_X.append(person_X)
|
|
1561
1572
|
valid_Y.append(person_Y)
|
|
1562
1573
|
valid_scores.append(person_scores)
|
|
@@ -1632,9 +1643,10 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1632
1643
|
all_frames_scores = make_homogeneous(all_frames_scores)
|
|
1633
1644
|
|
|
1634
1645
|
frame_range = [0,frame_count] if video_file == 'webcam' else frame_range
|
|
1635
|
-
all_frames_time = pd.Series(np.linspace(frame_range[0]/fps
|
|
1646
|
+
all_frames_time = pd.Series(np.linspace(frame_range[0]/fps, frame_range[1]/fps, frame_count+1), name='time')
|
|
1636
1647
|
if not multiperson:
|
|
1637
|
-
|
|
1648
|
+
calib_on_person_id = get_personID_with_highest_scores(all_frames_scores)
|
|
1649
|
+
detected_persons = [calib_on_person_id]
|
|
1638
1650
|
else:
|
|
1639
1651
|
detected_persons = range(all_frames_X_homog.shape[1])
|
|
1640
1652
|
|
|
@@ -1685,15 +1697,13 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1685
1697
|
else:
|
|
1686
1698
|
filter_type = filter_options[1]
|
|
1687
1699
|
if filter_type == 'butterworth':
|
|
1700
|
+
cutoff = filter_options[3]
|
|
1688
1701
|
if video_file == 'webcam':
|
|
1689
|
-
cutoff = filter_options[3]
|
|
1690
1702
|
if cutoff / (fps / 2) >= 1:
|
|
1691
1703
|
cutoff_old = cutoff
|
|
1692
1704
|
cutoff = fps/(2+0.001)
|
|
1693
1705
|
args = f'\n{cutoff_old:.1f} Hz cut-off framerate too large for a real-time framerate of {fps:.1f} Hz. Using a cut-off framerate of {cutoff:.1f} Hz instead.'
|
|
1694
1706
|
filter_options[3] = cutoff
|
|
1695
|
-
else:
|
|
1696
|
-
args = ''
|
|
1697
1707
|
args = f'Butterworth filter, {filter_options[2]}th order, {filter_options[3]} Hz.'
|
|
1698
1708
|
filter_options[4] = fps
|
|
1699
1709
|
if filter_type == 'gaussian':
|
|
@@ -1730,38 +1740,44 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1730
1740
|
|
|
1731
1741
|
else:
|
|
1732
1742
|
# Compute calibration parameters
|
|
1743
|
+
if not multiperson:
|
|
1744
|
+
selected_person_id = calib_on_person_id
|
|
1745
|
+
calib_on_person_id = 0
|
|
1733
1746
|
height_px = compute_height(trc_data[calib_on_person_id].iloc[:,1:], keypoints_names,
|
|
1734
1747
|
fastest_frames_to_remove_percent=fastest_frames_to_remove_percent, close_to_zero_speed=close_to_zero_speed_px, large_hip_knee_angles=large_hip_knee_angles, trimmed_extrema_percent=trimmed_extrema_percent)
|
|
1735
1748
|
|
|
1736
1749
|
if floor_angle == 'auto' or xy_origin == 'auto':
|
|
1737
1750
|
# estimated from the line formed by the toes when they are on the ground (where speed = 0)
|
|
1738
|
-
|
|
1751
|
+
toe_speed_below = 1 # m/s (below which the foot is considered to be stationary)
|
|
1752
|
+
px_per_m = height_px/person_height_m
|
|
1753
|
+
toe_speed_below_px_frame = toe_speed_below * px_per_m / fps
|
|
1754
|
+
floor_angle_estim, xy_origin_estim = compute_floor_line(trc_data[calib_on_person_id], keypoint_names=['LBigToe', 'RBigToe'], toe_speed_below=toe_speed_below_px_frame)
|
|
1739
1755
|
if not floor_angle == 'auto':
|
|
1740
1756
|
floor_angle_estim = floor_angle
|
|
1741
|
-
floor_angle_estim = -floor_angle_estim # Y points downwards
|
|
1742
1757
|
if xy_origin == 'auto':
|
|
1743
1758
|
cx, cy = xy_origin_estim
|
|
1744
1759
|
else:
|
|
1745
1760
|
cx, cy = xy_origin
|
|
1746
1761
|
logging.info(f'Using height of person #{calib_on_person_id} ({person_height_m}m) to convert coordinates in meters. '
|
|
1747
|
-
f'Floor angle: {np.degrees(
|
|
1748
|
-
f'xy_origin: {xy_origin if not xy_origin=="auto" else f"auto (estimation: {[round(c
|
|
1762
|
+
f'Floor angle: {np.degrees(floor_angle_estim) if not floor_angle=="auto" else f"auto (estimation: {round(np.degrees(floor_angle_estim),2)}°)"}, '
|
|
1763
|
+
f'xy_origin: {xy_origin if not xy_origin=="auto" else f"auto (estimation: {[round(c) for c in xy_origin_estim]})"}.')
|
|
1749
1764
|
|
|
1750
1765
|
# Coordinates in m
|
|
1751
1766
|
for i in range(len(trc_data)):
|
|
1752
1767
|
if not np.array(trc_data[i].iloc[:,1:] ==0).all():
|
|
1753
|
-
trc_data_m_i = pd.concat([convert_px_to_meters(trc_data[i][kpt_name], person_height_m, height_px, cx, cy, floor_angle_estim) for kpt_name in keypoints_names], axis=1)
|
|
1768
|
+
trc_data_m_i = pd.concat([convert_px_to_meters(trc_data[i][kpt_name], person_height_m, height_px, cx, cy, -floor_angle_estim) for kpt_name in keypoints_names], axis=1)
|
|
1754
1769
|
trc_data_m_i.insert(0, 't', all_frames_time)
|
|
1755
|
-
trc_data_unfiltered_m_i = pd.concat([convert_px_to_meters(trc_data_unfiltered[i][kpt_name], person_height_m, height_px, cx, cy, floor_angle_estim) for kpt_name in keypoints_names], axis=1)
|
|
1770
|
+
trc_data_unfiltered_m_i = pd.concat([convert_px_to_meters(trc_data_unfiltered[i][kpt_name], person_height_m, height_px, cx, cy, -floor_angle_estim) for kpt_name in keypoints_names], axis=1)
|
|
1756
1771
|
trc_data_unfiltered_m_i.insert(0, 't', all_frames_time)
|
|
1757
1772
|
|
|
1758
1773
|
if to_meters and show_plots:
|
|
1759
1774
|
pose_plots(trc_data_unfiltered_m_i, trc_data_m_i, i)
|
|
1760
1775
|
|
|
1761
1776
|
# Write to trc file
|
|
1762
|
-
|
|
1777
|
+
idx_path = selected_person_id if not multiperson and not calib_file else i
|
|
1778
|
+
pose_path_person_m_i = (pose_output_path.parent / (pose_output_path_m.stem + f'_person{idx_path:02d}.trc'))
|
|
1763
1779
|
make_trc_with_trc_data(trc_data_m_i, pose_path_person_m_i)
|
|
1764
|
-
logging.info(f'Person {
|
|
1780
|
+
logging.info(f'Person {idx_path}: Pose in meters saved to {pose_path_person_m_i.resolve()}.')
|
|
1765
1781
|
|
|
1766
1782
|
|
|
1767
1783
|
|
|
@@ -1815,6 +1831,13 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1815
1831
|
if save_angles and calculate_angles:
|
|
1816
1832
|
logging.info('\nPost-processing angles:')
|
|
1817
1833
|
all_frames_angles = make_homogeneous(all_frames_angles)
|
|
1834
|
+
|
|
1835
|
+
# unwrap angles
|
|
1836
|
+
# all_frames_angles = np.unwrap(all_frames_angles, axis=0, period=180) # This give all nan values -> need to mask nans
|
|
1837
|
+
for i in range(all_frames_angles.shape[1]): # for each person
|
|
1838
|
+
for j in range(all_frames_angles.shape[2]): # for each angle
|
|
1839
|
+
valid_mask = ~np.isnan(all_frames_angles[:, i, j])
|
|
1840
|
+
all_frames_angles[valid_mask, i, j] = np.unwrap(all_frames_angles[valid_mask, i, j], period=180)
|
|
1818
1841
|
|
|
1819
1842
|
# Process angles for each person
|
|
1820
1843
|
for i in detected_persons:
|
|
@@ -1846,16 +1869,14 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
|
|
|
1846
1869
|
else:
|
|
1847
1870
|
filter_type = filter_options[1]
|
|
1848
1871
|
if filter_type == 'butterworth':
|
|
1872
|
+
cutoff = filter_options[3]
|
|
1849
1873
|
if video_file == 'webcam':
|
|
1850
|
-
cutoff = filter_options[3]
|
|
1851
1874
|
if cutoff / (fps / 2) >= 1:
|
|
1852
1875
|
cutoff_old = cutoff
|
|
1853
1876
|
cutoff = fps/(2+0.001)
|
|
1854
1877
|
args = f'\n{cutoff_old:.1f} Hz cut-off framerate too large for a real-time framerate of {fps:.1f} Hz. Using a cut-off framerate of {cutoff:.1f} Hz instead.'
|
|
1855
1878
|
filter_options[3] = cutoff
|
|
1856
|
-
|
|
1857
|
-
args = ''
|
|
1858
|
-
args = f'Butterworth filter, {filter_options[2]}th order, {filter_options[3]} Hz. ' + args
|
|
1879
|
+
args = f'Butterworth filter, {filter_options[2]}th order, {filter_options[3]} Hz.'
|
|
1859
1880
|
filter_options[4] = fps
|
|
1860
1881
|
if filter_type == 'gaussian':
|
|
1861
1882
|
args = f'Gaussian filter, Sigma kernel {filter_options[5]}.'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sports2d
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.6
|
|
4
4
|
Summary: Detect pose and compute 2D joint angles from a video.
|
|
5
5
|
Home-page: https://github.com/davidpagnon/Sports2D
|
|
6
6
|
Author: David Pagnon
|
|
@@ -233,9 +233,10 @@ Note that it does not take distortions into account, and that it will be less ac
|
|
|
233
233
|
### Too slow for you?
|
|
234
234
|
|
|
235
235
|
**Quick fixes:**
|
|
236
|
-
- Use
|
|
236
|
+
- Use ` --save_vid false --save_img false --show_realtime_results false`: Will not save images or videos, and will not display the results in real time.
|
|
237
237
|
- Use `--mode lightweight`: Will use a lighter version of RTMPose, which is faster but less accurate.
|
|
238
238
|
- Use `--det_frequency 50`: Will detect poses only every 50 frames, and track keypoints in between, which is faster.
|
|
239
|
+
- Use `--multiperson false`: Can be used if one single person is present in the video. Otherwise, persons' IDs may be mixed up.
|
|
239
240
|
- Use `--load_trc <path_to_file_px.trc>`: Will use pose estimation results from a file. Useful if you want to use different parameters for pixel to meter conversion or angle calculation without running detection and pose estimation all over.
|
|
240
241
|
|
|
241
242
|
<br>
|
|
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
|