sports2d 0.8.6__tar.gz → 0.8.7__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.
Files changed (36) hide show
  1. {sports2d-0.8.6 → sports2d-0.8.7}/PKG-INFO +3 -2
  2. {sports2d-0.8.6 → sports2d-0.8.7}/README.md +2 -1
  3. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/Demo/Config_demo.toml +1 -0
  4. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/Sports2D.py +3 -1
  5. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/process.py +30 -9
  6. {sports2d-0.8.6 → sports2d-0.8.7}/sports2d.egg-info/PKG-INFO +3 -2
  7. {sports2d-0.8.6 → sports2d-0.8.7}/.github/workflows/continuous-integration.yml +0 -0
  8. {sports2d-0.8.6 → sports2d-0.8.7}/.github/workflows/joss_pdf.yml +0 -0
  9. {sports2d-0.8.6 → sports2d-0.8.7}/.github/workflows/publish-on-release.yml +0 -0
  10. {sports2d-0.8.6 → sports2d-0.8.7}/.gitignore +0 -0
  11. {sports2d-0.8.6 → sports2d-0.8.7}/CITATION.cff +0 -0
  12. {sports2d-0.8.6 → sports2d-0.8.7}/Content/Demo_plots.png +0 -0
  13. {sports2d-0.8.6 → sports2d-0.8.7}/Content/Demo_results.png +0 -0
  14. {sports2d-0.8.6 → sports2d-0.8.7}/Content/Demo_terminal.png +0 -0
  15. {sports2d-0.8.6 → sports2d-0.8.7}/Content/Person_selection.png +0 -0
  16. {sports2d-0.8.6 → sports2d-0.8.7}/Content/Video_tuto_Sports2D_Colab.png +0 -0
  17. {sports2d-0.8.6 → sports2d-0.8.7}/Content/joint_convention.png +0 -0
  18. {sports2d-0.8.6 → sports2d-0.8.7}/Content/paper.bib +0 -0
  19. {sports2d-0.8.6 → sports2d-0.8.7}/Content/paper.md +0 -0
  20. {sports2d-0.8.6 → sports2d-0.8.7}/Content/sports2d_blender.gif +0 -0
  21. {sports2d-0.8.6 → sports2d-0.8.7}/Content/sports2d_opensim.gif +0 -0
  22. {sports2d-0.8.6 → sports2d-0.8.7}/LICENSE +0 -0
  23. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/Demo/demo.mp4 +0 -0
  24. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/Sports2D.ipynb +0 -0
  25. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/Utilities/__init__.py +0 -0
  26. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/Utilities/common.py +0 -0
  27. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/Utilities/filter.py +0 -0
  28. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/Utilities/tests.py +0 -0
  29. {sports2d-0.8.6 → sports2d-0.8.7}/Sports2D/__init__.py +0 -0
  30. {sports2d-0.8.6 → sports2d-0.8.7}/pyproject.toml +0 -0
  31. {sports2d-0.8.6 → sports2d-0.8.7}/setup.cfg +0 -0
  32. {sports2d-0.8.6 → sports2d-0.8.7}/sports2d.egg-info/SOURCES.txt +0 -0
  33. {sports2d-0.8.6 → sports2d-0.8.7}/sports2d.egg-info/dependency_links.txt +0 -0
  34. {sports2d-0.8.6 → sports2d-0.8.7}/sports2d.egg-info/entry_points.txt +0 -0
  35. {sports2d-0.8.6 → sports2d-0.8.7}/sports2d.egg-info/requires.txt +0 -0
  36. {sports2d-0.8.6 → sports2d-0.8.7}/sports2d.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sports2d
3
- Version: 0.8.6
3
+ Version: 0.8.7
4
4
  Summary: Compute 2D human pose and angles from a video or a webcam.
5
5
  Author-email: David Pagnon <contact@david-pagnon.com>
6
6
  Maintainer-email: David Pagnon <contact@david-pagnon.com>
@@ -473,7 +473,7 @@ sports2d --help
473
473
  'calculate_angles': ["c", "calculate joint and segment angles. true if not specified"],
474
474
  'save_angles': ["A", "save angles as mot files. true if not specified"],
475
475
  'slowmo_factor': ["", "slow-motion factor. For a video recorded at 240 fps and exported to 30 fps, it would be 240/30 = 8. 1 if not specified"],
476
- 'pose_model': ["p", "only body_with_feet is available for now. body_with_feet if not specified"],
476
+ 'pose_model': ["p", "body_with_feet, whole_body_wrist, whole_body, or body. body_with_feet if not specified"],
477
477
  'mode': ["m", 'light, balanced, performance, or a """{dictionary within triple quote}""". balanced if not specified. Use a dictionary to specify your own detection and/or pose estimation models (more about in the documentation).'],
478
478
  'det_frequency': ["f", "run person detection only every N frames, and inbetween track previously detected bounding boxes. keypoint detection is still run on all frames.\n\
479
479
  Equal to or greater than 1, can be as high as you want in simple uncrowded cases. Much faster, but might be less accurate. 1 if not specified: detection runs on all frames"],
@@ -487,6 +487,7 @@ sports2d --help
487
487
  'save_calib': ["", "save calibration file. true if not specified"],
488
488
  'do_ik': ["", "do inverse kinematics. false if not specified"],
489
489
  'use_augmentation': ["", "Use LSTM marker augmentation. false if not specified"],
490
+ 'feet_on_floor': ["", "offset marker augmentation results so that feet are at floor level. true if not specified"],
490
491
  'use_contacts_muscles': ["", "Use model with contact spheres and muscles. false if not specified"],
491
492
  'participant_mass': ["", "mass of the participant in kg or none. Defaults to 70 if not provided. No influence on kinematics (motion), only on kinetics (forces)"],
492
493
  'close_to_zero_speed_m': ["","Sum for all keypoints: about 50 px/frame or 0.2 m/frame"],
@@ -430,7 +430,7 @@ sports2d --help
430
430
  'calculate_angles': ["c", "calculate joint and segment angles. true if not specified"],
431
431
  'save_angles': ["A", "save angles as mot files. true if not specified"],
432
432
  'slowmo_factor': ["", "slow-motion factor. For a video recorded at 240 fps and exported to 30 fps, it would be 240/30 = 8. 1 if not specified"],
433
- 'pose_model': ["p", "only body_with_feet is available for now. body_with_feet if not specified"],
433
+ 'pose_model': ["p", "body_with_feet, whole_body_wrist, whole_body, or body. body_with_feet if not specified"],
434
434
  'mode': ["m", 'light, balanced, performance, or a """{dictionary within triple quote}""". balanced if not specified. Use a dictionary to specify your own detection and/or pose estimation models (more about in the documentation).'],
435
435
  'det_frequency': ["f", "run person detection only every N frames, and inbetween track previously detected bounding boxes. keypoint detection is still run on all frames.\n\
436
436
  Equal to or greater than 1, can be as high as you want in simple uncrowded cases. Much faster, but might be less accurate. 1 if not specified: detection runs on all frames"],
@@ -444,6 +444,7 @@ sports2d --help
444
444
  'save_calib': ["", "save calibration file. true if not specified"],
445
445
  'do_ik': ["", "do inverse kinematics. false if not specified"],
446
446
  'use_augmentation': ["", "Use LSTM marker augmentation. false if not specified"],
447
+ 'feet_on_floor': ["", "offset marker augmentation results so that feet are at floor level. true if not specified"],
447
448
  'use_contacts_muscles': ["", "Use model with contact spheres and muscles. false if not specified"],
448
449
  'participant_mass': ["", "mass of the participant in kg or none. Defaults to 70 if not provided. No influence on kinematics (motion), only on kinetics (forces)"],
449
450
  'close_to_zero_speed_m': ["","Sum for all keypoints: about 50 px/frame or 0.2 m/frame"],
@@ -151,6 +151,7 @@ filter_type = 'butterworth' # butterworth, gaussian, LOESS, median
151
151
  [kinematics]
152
152
  do_ik = false # Do scaling and inverse kinematics?
153
153
  use_augmentation = false # true or false (lowercase) # Set to true if you want to use the model with augmented markers
154
+ feet_on_floor = false # true or false (lowercase) # Set to false if you want to use the model with feet not on the floor (e.g. running, jumping, etc.)
154
155
  use_contacts_muscles = true # true or false (lowercase) # If true, contact spheres and muscles are added to the model
155
156
  participant_mass = [55.0, 67.0] # kg # defaults to 70 if not provided. No influence on kinematics (motion), only on kinetics (forces)
156
157
  right_left_symmetry = true # true or false (lowercase) # Set to false only if you have good reasons to think the participant is not symmetrical (e.g. prosthetic limb)
@@ -205,6 +205,7 @@ DEFAULT_CONFIG = {'base': {'video_input': ['demo.mp4'],
205
205
  },
206
206
  'kinematics':{'do_ik': False,
207
207
  'use_augmentation': False,
208
+ 'feet_on_floor': False,
208
209
  'use_contacts_muscles': True,
209
210
  'participant_mass': [55.0, 67.0],
210
211
  'right_left_symmetry': True,
@@ -244,7 +245,7 @@ CONFIG_HELP = {'config': ["C", "path to a toml configuration file"],
244
245
  'calculate_angles': ["c", "calculate joint and segment angles. true if not specified"],
245
246
  'save_angles': ["A", "save angles as mot files. true if not specified"],
246
247
  'slowmo_factor': ["", "slow-motion factor. For a video recorded at 240 fps and exported to 30 fps, it would be 240/30 = 8. 1 if not specified"],
247
- 'pose_model': ["p", "only body_with_feet is available for now. body_with_feet if not specified"],
248
+ 'pose_model': ["p", "body_with_feet, whole_body_wrist, whole_body, or body. body_with_feet if not specified"],
248
249
  'mode': ["m", 'light, balanced, performance, or a """{dictionary within triple quote}""". balanced if not specified. Use a dictionary to specify your own detection and/or pose estimation models (more about in the documentation).'],
249
250
  'det_frequency': ["f", "run person detection only every N frames, and inbetween track previously detected bounding boxes. keypoint detection is still run on all frames.\n\
250
251
  Equal to or greater than 1, can be as high as you want in simple uncrowded cases. Much faster, but might be less accurate. 1 if not specified: detection runs on all frames"],
@@ -258,6 +259,7 @@ CONFIG_HELP = {'config': ["C", "path to a toml configuration file"],
258
259
  'save_calib': ["", "save calibration file. true if not specified"],
259
260
  'do_ik': ["", "do inverse kinematics. false if not specified"],
260
261
  'use_augmentation': ["", "Use LSTM marker augmentation. false if not specified"],
262
+ 'feet_on_floor': ["", "offset marker augmentation results so that feet are at floor level. true if not specified"],
261
263
  'use_contacts_muscles': ["", "Use model with contact spheres and muscles. false if not specified"],
262
264
  'participant_mass': ["", "mass of the participant in kg or none. Defaults to 70 if not provided. No influence on kinematics (motion), only on kinetics (forces)"],
263
265
  'close_to_zero_speed_m': ["","Sum for all keypoints: about 50 px/frame or 0.2 m/frame"],
@@ -66,6 +66,7 @@ import itertools as it
66
66
  from tqdm import tqdm
67
67
  from collections import defaultdict
68
68
  from anytree import RenderTree
69
+ from anytree.importer import DictImporter
69
70
 
70
71
  import numpy as np
71
72
  import pandas as pd
@@ -1380,6 +1381,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
1380
1381
  use_augmentation = config_dict.get('kinematics').get('use_augmentation')
1381
1382
  participant_masses = config_dict.get('kinematics').get('participant_mass')
1382
1383
  participant_masses = participant_masses if isinstance(participant_masses, list) else [participant_masses]
1384
+ feet_on_floor = config_dict.get('kinematics').get('feet_on_floor')
1383
1385
  fastest_frames_to_remove_percent = config_dict.get('kinematics').get('fastest_frames_to_remove_percent')
1384
1386
  large_hip_knee_angles = config_dict.get('kinematics').get('large_hip_knee_angles')
1385
1387
  trimmed_extrema_percent = config_dict.get('kinematics').get('trimmed_extrema_percent')
@@ -1426,15 +1428,12 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
1426
1428
  cv2.setWindowProperty(f'{video_file} Sports2D', cv2.WND_PROP_ASPECT_RATIO, cv2.WINDOW_FULLSCREEN)
1427
1429
 
1428
1430
  # Select the appropriate model based on the model_type
1431
+ logging.info('\nEstimating pose...')
1429
1432
  if pose_model.upper() in ('HALPE_26', 'BODY_WITH_FEET'):
1430
1433
  model_name = 'HALPE_26'
1431
1434
  ModelClass = BodyWithFeet # 26 keypoints(halpe26)
1432
1435
  logging.info(f"Using HALPE_26 model (body and feet) for pose estimation.")
1433
- elif pose_model.upper() == 'WHOLE_BODY_WRIST':
1434
- model_name = 'COCO_133_WRIST'
1435
- ModelClass = Wholebody
1436
- logging.info(f"Using COCO_133 model (body, feet, 2 hand points) for pose estimation.")
1437
- elif pose_model.upper() in ('COCO_133', 'WHOLE_BODY'):
1436
+ elif pose_model.upper() in ('COCO_133', 'WHOLE_BODY', 'WHOLE_BODY_WRIST'):
1438
1437
  model_name = 'COCO_133'
1439
1438
  ModelClass = Wholebody
1440
1439
  logging.info(f"Using COCO_133 model (body, feet, hands, and face) for pose estimation.")
@@ -1442,10 +1441,32 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
1442
1441
  model_name = 'COCO_17'
1443
1442
  ModelClass = Body
1444
1443
  logging.info(f"Using COCO_17 model (body) for pose estimation.")
1444
+ elif pose_model.upper() =='HAND':
1445
+ model_name = 'HAND_21'
1446
+ ModelClass = Hand
1447
+ logging.info(f"Using HAND_21 model for pose estimation.")
1448
+ elif pose_model.upper() =='FACE':
1449
+ model_name = 'FACE_106'
1450
+ logging.info(f"Using FACE_106 model for pose estimation.")
1451
+ elif pose_model.upper() =='ANIMAL':
1452
+ model_name = 'ANIMAL2D_17'
1453
+ logging.info(f"Using ANIMAL2D_17 model for pose estimation.")
1445
1454
  else:
1446
- raise ValueError(f"Invalid model_type: {model_name}. Must be 'HALPE_26', 'COCO_133', or 'COCO_17'. Use another network (MMPose, DeepLabCut, OpenPose, AlphaPose, BlazePose...) and convert the output files if you need another model. See documentation.")
1455
+ model_name = pose_model.upper()
1456
+ logging.info(f"Using model {model_name} for pose estimation.")
1447
1457
  pose_model_name = pose_model
1448
- pose_model = eval(model_name)
1458
+ try:
1459
+ pose_model = eval(model_name)
1460
+ except:
1461
+ try: # from Config.toml
1462
+ pose_model = DictImporter().import_(config_dict.get('pose').get(pose_model))
1463
+ if pose_model.id == 'None':
1464
+ pose_model.id = None
1465
+ except:
1466
+ raise NameError(f'{pose_model} not found in skeletons.py nor in Config.toml')
1467
+
1468
+ # Select device and backend
1469
+ backend, device = setup_backend_device(backend=backend, device=device)
1449
1470
 
1450
1471
  # Manually select the models if mode is a dictionary rather than 'lightweight', 'balanced', or 'performance'
1451
1472
  if not mode in ['lightweight', 'balanced', 'performance']:
@@ -2127,7 +2148,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
2127
2148
 
2128
2149
  # Delete person if less than 4 valid frames
2129
2150
  pose_path_person = pose_output_path.parent / (pose_output_path.stem + f'_person{i:02d}.trc')
2130
- all_frames_X_person = pd.DataFrame(all_frames_X_homog[:,i,:], columns=keypoints_names)
2151
+ all_frames_X_person = pd.DataFrame(all_frames_X_homog[:,i,:], columns=new_keypoints_names)
2131
2152
  pose_nan_count = len(np.where(all_frames_X_person.sum(axis=1)==0)[0])
2132
2153
  if frame_count - frame_range[0] - pose_nan_count <= 4:
2133
2154
  # heights_m.append(DEFAULT_HEIGHT)
@@ -2151,7 +2172,7 @@ def process_fun(config_dict, video_file, time_range, frame_rate, result_dir):
2151
2172
  Pose2Sim_config_dict['project']['participant_height'] = heights_m
2152
2173
  Pose2Sim_config_dict['project']['participant_mass'] = masses
2153
2174
  Pose2Sim_config_dict['project']['frame_range'] = 'all'
2154
- Pose2Sim_config_dict['markerAugmentation']['feet_on_floor'] = False
2175
+ Pose2Sim_config_dict['markerAugmentation']['feet_on_floor'] = feet_on_floor
2155
2176
  Pose2Sim_config_dict['pose']['pose_model'] = pose_model_name.upper()
2156
2177
  Pose2Sim_config_dict = to_dict(Pose2Sim_config_dict)
2157
2178
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sports2d
3
- Version: 0.8.6
3
+ Version: 0.8.7
4
4
  Summary: Compute 2D human pose and angles from a video or a webcam.
5
5
  Author-email: David Pagnon <contact@david-pagnon.com>
6
6
  Maintainer-email: David Pagnon <contact@david-pagnon.com>
@@ -473,7 +473,7 @@ sports2d --help
473
473
  'calculate_angles': ["c", "calculate joint and segment angles. true if not specified"],
474
474
  'save_angles': ["A", "save angles as mot files. true if not specified"],
475
475
  'slowmo_factor': ["", "slow-motion factor. For a video recorded at 240 fps and exported to 30 fps, it would be 240/30 = 8. 1 if not specified"],
476
- 'pose_model': ["p", "only body_with_feet is available for now. body_with_feet if not specified"],
476
+ 'pose_model': ["p", "body_with_feet, whole_body_wrist, whole_body, or body. body_with_feet if not specified"],
477
477
  'mode': ["m", 'light, balanced, performance, or a """{dictionary within triple quote}""". balanced if not specified. Use a dictionary to specify your own detection and/or pose estimation models (more about in the documentation).'],
478
478
  'det_frequency': ["f", "run person detection only every N frames, and inbetween track previously detected bounding boxes. keypoint detection is still run on all frames.\n\
479
479
  Equal to or greater than 1, can be as high as you want in simple uncrowded cases. Much faster, but might be less accurate. 1 if not specified: detection runs on all frames"],
@@ -487,6 +487,7 @@ sports2d --help
487
487
  'save_calib': ["", "save calibration file. true if not specified"],
488
488
  'do_ik': ["", "do inverse kinematics. false if not specified"],
489
489
  'use_augmentation': ["", "Use LSTM marker augmentation. false if not specified"],
490
+ 'feet_on_floor': ["", "offset marker augmentation results so that feet are at floor level. true if not specified"],
490
491
  'use_contacts_muscles': ["", "Use model with contact spheres and muscles. false if not specified"],
491
492
  'participant_mass': ["", "mass of the participant in kg or none. Defaults to 70 if not provided. No influence on kinematics (motion), only on kinetics (forces)"],
492
493
  'close_to_zero_speed_m': ["","Sum for all keypoints: about 50 px/frame or 0.2 m/frame"],
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes