Welcome to Sports2D
+Bienvenue à Sports2D
+Sports2D automatically computes 2D joint positions, as well as joint and segment angles from a video or a webcam.
+ + +Accurate Detection
+RTMPose technology for reliable joint tracking
+Angle Computation
+Automatic joint and segment angle calculation
+Real Measurements
+Convert pixels to meters for accurate analysis
+OpenSim Ready
+Biomechanically accurate inverse kinematics
+⚠️ Important Notes
+-
+
- Angle estimation is only as good as the pose estimation algorithm - it is not perfect +
- Results are acceptable only if persons move in the 2D plane (sagittal or frontal plane) +
- Persons need to be filmed as parallel as possible to the motion plane +
- For 3D research-grade markerless joint kinematics, use Pose2Sim with multiple cameras +
📦 Recent Updates
+-
+
- v0.9: Generate or import calibration file, OpenSim skeleton overlay +
- v0.8: Select only the persons you want to analyze +
- v0.7: MarkerAugmentation and Inverse Kinematics with OpenSim +
- v0.6: Any detector and pose estimation model can be used +
- v0.5: Results in meters rather than pixels +
Installation
+Installation
+Two installation options: Quick install for basic use, or Full install for OpenSim inverse kinematics.
+ +Quick Install
+For basic pose estimation and angle calculation (no inverse kinematics):
+ +1. Check Python Version
+Make sure Python 3.10-3.12 is installed:
+python -V
+ If not installed, check the next section
+ +2. Install Sports2D
+pip install sports2d
+ Alternative - Build from source (for latest changes):
+git clone https://github.com/davidpagnon/sports2d.git
+cd sports2d
+pip install .
+ Full Install (with OpenSim)
+Required for inverse kinematics. Skip if you already have a Pose2Sim environment.
+ +1. Install Anaconda or Miniconda
+Download Miniconda (recommended - lighter version)
+ +2. Create Virtual Environment
+Open an Anaconda prompt:
+conda create -n Sports2D python=3.12 -y
+conda activate Sports2D
+ 3. Install OpenSim
+conda install -c opensim-org opensim -y
+ For other installation methods, see OpenSim documentation
+ +4. Install Sports2D
+pip install sports2d
+ ✅ Installation Complete!
+If you used conda, remember to activate your environment before use:
+conda activate Sports2D
+ 💡 For Existing Pose2Sim Users
+If you already have a Pose2Sim environment:
+conda activate Pose2Sim
+pip install sports2d
+ Run the Demo
+Exécuter la Démo
+Test your installation with the included demo video.
+ +Run Demo Command
+Simply type this command:
+sports2d
+ You should see joint positions and angles displayed in real-time.
+📁 Output Files Created
+Check the folder where you ran the command to find:
+-
+
- Video: Processed with skeleton overlay and angle values +
- Images: Individual processed frames +
- .trc files: Pose coordinates (open with Excel or any spreadsheet software) +
- .mot files: Angle files (open with Excel or any spreadsheet software) +
- Logs: Processing details and statistics +
🎬 About the Demo Video
+The demo is deliberately challenging to demonstrate robustness:
+-
+
- One person walking in the sagittal plane +
- One person doing jumping jacks in the frontal plane, then performing a flip while backlit +
- One tiny person flickering in the background who needs to be ignored +
Visualize in OpenSim (Optional)
+If you installed OpenSim and ran with --do_ik True:
-
+
- Open OpenSim GUI +
- File → Preview experimental data → Open your .trc file +
- File → Open Model → Open the .osim file +
- File → Load Motion → Open the .mot file +
Visualize in Blender (Optional)
+Install the Pose2Sim_Blender add-on for 3D visualization with camera overlay.
+⚠️ Important
+If you used conda, activate your environment first:
+conda activate Sports2D
+sports2d
+ Use Your Own Video or Webcam
+Utiliser Votre Vidéo ou Webcam
+Process a Video File
+Analyze any video file:
+sports2d --video_input path/to/video.mp4
+ Beware that images won't be saved if paths contain non-ASCII characters
+Use Webcam for Real-Time Analysis
+sports2d --video_input webcam
+ If you have multiple cameras, specify which one (0 is default):
+sports2d --video_input webcam --webcam_id 1
+ Analyze Specific Time Range
+Focus on a particular segment (times in seconds):
+sports2d --video_input video.mp4 --time_range 1.2 2.7
+ Batch Processing
+Analyze multiple videos with same settings:
+sports2d --video_input video1.mp4 video2.mp4
+ With different time ranges per video:
+sports2d --video_input video1.mp4 video2.mp4 --time_range 1.2 2.7 0 3.5
+ Slow-Motion Videos
+For videos recorded at high fps but exported at normal speed, specify the slowmo factor:
+sports2d --video_input video.mp4 --slowmo_factor 8
+ For a video recorded at 240 fps and exported to 30 fps, factor = 240/30 = 8
+Select Persons to Analyze
+Sélectionner les Personnes
+When multiple people appear in your video, choose who to track and analyze.
+ +Interactive Selection (Recommended)
+Click to manually select persons to analyze:
+sports2d --person_ordering_method on_click
+ When prompted: slide to a frame and select the desired person
+Automatic Selection
+For unattended processing, Sports2D can automatically select persons:
+| Method | +Description | +
|---|---|
highest_likelihood |
+ Most confident detections | +
largest_size |
+ Closest to camera | +
smallest_size |
+ Furthest from camera | +
greatest_displacement |
+ Most active/moving | +
least_displacement |
+ Least active | +
first_detected |
+ Appears first in video | +
last_detected |
+ Appears last in video | +
sports2d --nb_persons_to_detect 2 --person_ordering_method highest_likelihood
+ ⚠️ Why Order Matters
+Person order is important when:
+-
+
- Converting to meters (first person's height used as reference) +
- Running inverse kinematics (calibration based on first person) +
Convert to Meters
+Convertir en Mètres
+Get real-world measurements instead of pixel coordinates.
+ +⚠️ Important Note
+The Z coordinate (depth) is estimated and should not be overly trusted for accurate depth measurements.
+Method 1: Provide Reference Height (Simple)
+Just tell Sports2D the height of the first person:
+sports2d --first_person_height 1.65 --visible_side auto
+ How it works:
+-
+
- Height in pixels is compared with real height to get pixel-to-meter conversion +
- Floor angle and xy origin automatically estimated from gait +
- Depth (Z) coordinates estimated based on visible side +
- Calibration file automatically saved for reuse +
Visible Side Options:
+| Option | +When to Use | +
|---|---|
auto |
+ Automatically determine - works for sagittal plane motions (left or right based on motion direction) | +
left |
+ Person's left side visible | +
right |
+ Person's right side visible | +
front |
+ Person faces camera | +
back |
+ Person's back to camera | +
none |
+ Keep 2D coordinates (when person turns around) | +
Advanced: Manual Floor & Origin
+Override automatic detection:
+sports2d --first_person_height 1.65 --visible_side left \
+ --floor_angle 0 --xy_origin 0 940
+ Y axis points down. Origin is typically placed under the person's feet.
+Method 2: Use Calibration File
+Use a calibration file from previous runs or from other systems (Pose2Sim, Qualisys, Vicon, OpenCap, FreeMoCap):
+sports2d --calib_file Calib_demo.toml --visible_side auto front none
+ By convention, camera-to-subject distance is set to 10 meters in generated calibration files
+Inverse Kinematics with OpenSim
+Cinématique Inverse avec OpenSim
+OpenSim inverse kinematics provides biomechanically accurate results with joint constraints and consistent bone lengths.
+ +⚠️ Requirements
+-
+
- Full installation with OpenSim required +
- Person must be moving in a single plane for the entire selected time range +
Basic Inverse Kinematics
+sports2d --time_range 1.2 2.7 \
+ --do_ik true --first_person_height 1.65 --visible_side auto
+ With LSTM Marker Augmentation (Recommended)
+Improves motion quality by filling gaps and smoothing trajectories:
+sports2d --time_range 1.2 2.7 \
+ --do_ik true --use_augmentation true \
+ --first_person_height 1.65 --visible_side left
+ Complete Example with All Options
+sports2d --time_range 1.2 2.7 \
+ --do_ik true --use_augmentation true \
+ --first_person_height 1.65 --visible_side left front \
+ --participant_mass 55.0 67.0 \
+ --calib_file Calib_demo.toml
+ Mass has no influence on kinematics (motion), only on kinetics (forces) if you pursue further analysis
+Additional Options
+| Parameter | +Description | +Default | +
|---|---|---|
--feet_on_floor |
+ Offset results so feet touch floor level | +true | +
--use_simple_model |
+ Faster model without muscles/flexible spine (10x speed) | +false | +
--participant_mass |
+ Mass in kg per person | +70 | +
--right_left_symmetry |
+ Enforce equal left/right limb sizes | +true | +
📊 Model Scaling Process
+OpenSim scales the model based on segment lengths, automatically removing outliers:
+-
+
- Removes 10% fastest frames (potential outliers) +
- Removes frames where speed ≈ 0 (person probably out of frame) +
- Removes frames with hip/knee flexion > 45° (imprecise when crouching) +
- Removes 20% most extreme segment values +
- Calculates mean of remaining measurements +
All parameters can be edited in Config.toml file
+🎯 Benefits
+-
+
- Sets joint constraints and angle limits for realistic motion +
- Maintains consistent bone lengths throughout movement +
- Can enforce left/right symmetry +
- Enables further analysis: joint torques, muscle forces, ground reaction forces (with MoCo) +
⚠️ Important
+This will not work on sections where the person is not moving in a single plane. You can split your video into several time ranges if needed.
+Configuration File
+Fichier de Configuration
+For complex analyses, use a configuration file instead of long command lines.
+ +Run with Config File
+sports2d --config Config_demo.toml
+ Python Integration - Full Config
+Load and use a complete TOML configuration file:
+from Sports2D import Sports2D
+from pathlib import Path
+import toml
+
+config_path = Path(Sports2D.__file__).parent / 'Demo' / 'Config_demo.toml'
+config_dict = toml.load(config_path)
+Sports2D.process(config_dict)
+ Python Integration - Partial Config
+Override only specific parameters (others use defaults):
+from Sports2D import Sports2D
+
+config_dict = {
+ 'base': {
+ 'nb_persons_to_detect': 1,
+ 'person_ordering_method': 'greatest_displacement'
+ },
+ 'pose': {
+ 'mode': 'lightweight',
+ 'det_frequency': 50
+ }
+}
+Sports2D.process(config_dict)
+ 📋 Config File Structure
+TOML configuration files are organized into sections:
+-
+
- [base] - General settings (video input, person detection) +
- [pose] - Pose estimation parameters (model, frequency) +
- [process] - Processing options (filtering, interpolation) +
- [opensim] - Inverse kinematics settings +
All Parameters Reference
+Référence Complète
+Complete reference of available parameters. Most have sensible defaults.
+ +📹 Video & General
+| Parameter | +Description | +Default | +
|---|---|---|
video_input |
+ Video path(s) or 'webcam' | +demo video | +
webcam_id |
+ Camera ID for webcam | +0 | +
time_range |
+ Start and end time (seconds) | +whole video | +
result_dir |
+ Output directory | +current dir | +
slowmo_factor |
+ Slow-motion factor (recording fps / export fps) | +1 | +
👥 Person Detection
+| Parameter | +Description | +Default | +
|---|---|---|
nb_persons_to_detect |
+ Number or 'all' | +all | +
person_ordering_method |
+ on_click, highest_likelihood, largest_size, smallest_size, greatest_displacement, least_displacement, first_detected, last_detected | +on_click | +
🎯 Pose Estimation
+| Parameter | +Description | +Default | +
|---|---|---|
pose_model |
+ body_with_feet, whole_body_wrist, whole_body, body | +body_with_feet | +
mode |
+ lightweight, balanced, performance (or custom dict) | +balanced | +
det_frequency |
+ Run detection every N frames (tracking fills gaps) | +1 | +
tracking_mode |
+ sports2d, deepsort | +sports2d | +
backend |
+ auto, cpu, cuda, mps, rocm | +auto | +
📐 Angles
+| Parameter | +Description | +Default | +
|---|---|---|
calculate_angles |
+ Calculate joint/segment angles | +true | +
joint_angles |
+ List of joints to compute | +all standard joints | +
segment_angles |
+ List of segments to compute | +all standard segments | +
display_angle_values_on |
+ body, list, both, or none | +body list | +
flip_left_right |
+ Flip angles when person switches sides | +true | +
📏 Calibration
+| Parameter | +Description | +Default | +
|---|---|---|
to_meters |
+ Convert to real-world measurements | +true | +
first_person_height |
+ Reference height in meters | +1.65 | +
visible_side |
+ auto, left, right, front, back, none | +auto front none | +
floor_angle |
+ Floor angle in degrees or 'auto' | +auto | +
calib_file |
+ Path to calibration file | +none | +
🤸 OpenSim IK
+| Parameter | +Description | +Default | +
|---|---|---|
do_ik |
+ Run inverse kinematics | +false | +
use_augmentation |
+ Use LSTM marker augmentation | +false | +
feet_on_floor |
+ Offset so feet touch floor | +true | +
use_simple_model |
+ Faster model (10x speed) | +false | +
participant_mass |
+ Mass in kg per person | +70 | +
right_left_symmetry |
+ Enforce symmetry | +true | +
🔄 Processing
+| Parameter | +Description | +Default | +
|---|---|---|
interpolate |
+ Fill missing data gaps | +true | +
interp_gap_smaller_than |
+ Max gap size in frames | +10 | +
reject_outliers |
+ Use Hampel filter | +true | +
filter |
+ Apply filtering | +true | +
filter_type |
+ butterworth, kalman, gcv_spline, gaussian, median, loess | +butterworth | +
cut_off_frequency |
+ Butterworth cutoff (Hz) | +3 | +
💾 Output
+| Parameter | +Description | +Default | +
|---|---|---|
save_vid |
+ Save processed video | +true | +
save_img |
+ Save processed images | +true | +
save_pose |
+ Save TRC pose files | +true | +
save_angles |
+ Save MOT angle files | +true | +
show_realtime_results |
+ Display during processing | +true | +
show_graphs |
+ Show plots after | +true | +
📖 Full Documentation
+For complete parameter details: sports2d --help
Example config: Config_Demo.toml
+Performance Optimization
+Optimisation Performance
+Speed up processing for large videos or batch operations.
+ +1. Disable Unnecessary Outputs
+Skip video/image saving and real-time display when you only need the data:
+sports2d --save_vid false --save_img false --show_realtime_results false
+ 2. Use Lightweight Mode
+Lighter pose model for significant speed gains:
+sports2d --mode lightweight
+ 3. Reduce Detection Frequency
+Person detection is slow. Run it every N frames instead of every frame (tracking fills gaps):
+sports2d --det_frequency 50
+ Detection finds people (slow), tracking follows them between detections (fast). Keypoint detection still runs on all frames.
+4. Reuse Pose Estimation
+Load existing pose data to test different conversion or angle parameters:
+sports2d --load_trc_px existing_file_px.trc
+ 5. Use Sports2D Tracker
+Default Sports2D tracker is faster than DeepSort:
+sports2d --tracking_mode sports2d
+ 6. GPU Acceleration (NVIDIA)
+Enable CUDA for dramatic speedups (requires ~6GB additional storage):
+ +Check GPU:
+nvidia-smi
+ Note the CUDA version - this is the latest your driver supports
+Install PyTorch with CUDA:
+pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
+ Adjust cu124 based on your CUDA version. Check pytorch.org for compatible versions
+Install ONNX Runtime GPU:
+pip uninstall onnxruntime
+pip install onnxruntime-gpu
+ Verify:
+python -c "import torch; print(torch.cuda.is_available())"
+python -c "import onnxruntime as ort; print(ort.get_available_providers())"
+ Should print: True and ['CUDAExecutionProvider', ...]
+✅ Maximum Speed Command
+Combine all optimizations:
+sports2d --mode lightweight --det_frequency 50 \
+ --save_vid false --save_img false --show_realtime_results false \
+ --tracking_mode sports2d
+ 💡 Additional Tips
+-
+
- Use
--time_rangeto process only relevant segments
+ - Lower
--input_sizefor faster processing (e.g., 960 540)
+ - GPU acceleration provides 3-5x speedup on NVIDIA GPUs +
Angle Conventions
+Conventions d'Angles
+Understanding how Sports2D measures joint and segment angles.
+ +🦵 Joint Angles
+ +Ankle Dorsiflexion
+Measured between: Heel → Big toe, and Ankle → Knee
+Reference: -90° when foot is aligned with the shank
+Positive = dorsiflexion (toes up), Negative = plantarflexion (toes down)
+Knee Flexion
+Measured between: Hip → Knee → Ankle
+Reference: 0° when shank is aligned with thigh
+Positive = knee bent
+Hip Flexion
+Measured between: Knee → Hip → Shoulder
+Reference: 0° when trunk is aligned with thigh
+Positive = thigh moving forward
+Shoulder Flexion
+Measured between: Hip → Shoulder → Elbow
+Reference: 180° when arm is aligned with trunk
+Less than 180° = arm moving forward
+Elbow Flexion
+Measured between: Wrist → Elbow → Shoulder
+Reference: 0° when forearm is aligned with arm
+Positive = elbow bent
+📏 Segment Angles
+Measured anticlockwise from horizontal (0° = right, 90° = up, 180° = left, 270° = down)
+ +| Segment | +Measured Between | +
|---|---|
| Foot | +Heel → Big toe | +
| Shank | +Ankle → Knee | +
| Thigh | +Hip → Knee | +
| Pelvis | +Left hip → Right hip | +
| Trunk | +Hip midpoint → Shoulder midpoint | +
| Shoulders | +Left shoulder → Right shoulder | +
| Head | +Neck → Top of head | +
| Arm | +Shoulder → Elbow | +
| Forearm | +Elbow → Wrist | +
🎨 Customization
+Select specific angles to calculate:
+sports2d --joint_angles "right knee" "left knee" \
+ --segment_angles "right thigh" "left thigh"
+ Or disable angle calculation entirely:
+sports2d --calculate_angles false
+ ⚠️ Left/Right Flipping
+By default (--flip_left_right true), angles flip when person switches direction. Person is considered to look right if toe keypoint is to the right of heel.
May not work correctly during sprinting. Set to false if you want timeseries to be continuous even when participant switches stance.
📐 Segment Angle Correction
+By default (--correct_segment_angles_with_floor_angle true), segment angles are corrected for camera tilt using detected floor angle.
Set to false if it is actually the floor which is tilted, not the camera.