kinemotion

Kinemotion

PyPI version Python Version License: MIT

Tests Quality Gate Status Coverage OpenSSF Best Practices

Ruff Type checked with pyright pre-commit

A video-based kinematic analysis tool for athletic performance. Analyzes vertical jump videos to estimate key performance metrics using MediaPipe pose tracking and advanced kinematics.

Supported jump types:

Features

Core Features

Drop Jump Analysis

Counter Movement Jump (CMJ) Analysis

Squat Jump (SJ) Analysis

⚠️ Validation Status

Current Status: Pre-validation (not validated against force plates or motion capture systems)

What This Tool IS Suitable For

✅ Training monitoring - Track relative changes within the same athlete over time ✅ Educational purposes - Learn about jump biomechanics and video analysis ✅ Exploratory analysis - Initial investigation before formal testing ✅ Proof-of-concept research - Demonstrate feasibility of video-based methods

What This Tool IS NOT Suitable For

❌ Research publications - As a validated measurement instrument ❌ Clinical decision-making - Injury assessment, return-to-play decisions ❌ Talent identification - Absolute performance comparisons between athletes ❌ Legal/insurance assessments - Any context requiring validated measurements ❌ High-stakes testing - Draft combines, professional athlete evaluation

Known Limitations

If you need validated measurements for research or clinical use, consider:

For detailed validation status and roadmap, see docs/validation-status.md.

Setup

System Requirements

All Platforms:

Platform-Specific:

Windows

Required system dependencies:

Recommended for mobile video support:

macOS

Required system dependencies:

Recommended for mobile video support:

brew install ffmpeg

Linux (Ubuntu/Debian)

Recommended system libraries:

sudo apt-get update
sudo apt-get install -y \
    libgl1 \           # OpenGL library for OpenCV
    libglib2.0-0 \     # GLib library for MediaPipe
    libgomp1 \         # OpenMP library for multi-threading
    ffmpeg             # Video codec support and metadata extraction

Note: ffmpeg provides the ffprobe tool for video metadata extraction (rotation, aspect ratio). Kinemotion works without it, but mobile/rotated videos may not process correctly. A warning will be shown if ffprobe is not available.

Installation Methods

pip install kinemotion

From Source (Development)

Step 1: Install asdf plugins (if not already installed):

asdf plugin add python
asdf plugin add uv

Step 2: Install versions specified in .tool-versions:

asdf install

Step 3: Install project dependencies using uv:

uv sync

This will install all dependencies and make the kinemotion command available.

Usage

Kinemotion supports two jump types with intelligent auto-tuning that automatically optimizes parameters based on video characteristics.

Analyzing Drop Jumps

Analyzes reactive strength and ground contact time:

# Automatic parameter tuning based on video characteristics
kinemotion dropjump-analyze video.mp4

Analyzing CMJ

Analyzes jump height and biomechanics:

# No drop height needed (floor level)
kinemotion cmj-analyze video.mp4

# With triple extension visualization
kinemotion cmj-analyze video.mp4 --output debug.mp4

Analyzing Squat Jump (SJ)

Analyzes pure concentric power production:

# Mass is required for power/force calculations
kinemotion sj-analyze video.mp4 --mass 75.0

# Complete analysis with all outputs
kinemotion sj-analyze video.mp4 --mass 75.0 \
  --output debug.mp4 \
  --json-output results.json \
  --verbose

Common Options (All Jump Types)

# Save metrics to JSON
kinemotion cmj-analyze video.mp4 --json-output results.json

# Generate debug video
kinemotion cmj-analyze video.mp4 --output debug.mp4

# Complete analysis with all outputs
kinemotion cmj-analyze video.mp4 \
  --output debug.mp4 \
  --json-output results.json \
  --verbose

Quality Presets

# Fast (50% faster, good for batch)
kinemotion cmj-analyze video.mp4 --quality fast

# Balanced (default)
kinemotion cmj-analyze video.mp4 --quality balanced

# Accurate (research-grade)
kinemotion cmj-analyze video.mp4 --quality accurate --verbose

Batch Processing

Process multiple videos in parallel:

# Drop jumps
kinemotion dropjump-analyze videos/*.mp4 --batch --workers 4

# CMJ with output directories
kinemotion cmj-analyze videos/*.mp4 --batch --workers 4 \
  --json-output-dir results/ \
  --csv-summary summary.csv

Quality Assessment

All analysis outputs include automatic quality assessment in the metadata section to help you know when to trust results:

{
  "data": {
    "jump_height_m": 0.352,
    "flight_time_ms": 534.2
  },
  "metadata": {
    "quality": {
      "confidence": "high",
      "quality_score": 87.3,
      "quality_indicators": {
        "avg_visibility": 0.89,
        "min_visibility": 0.82,
        "tracking_stable": true,
        "phase_detection_clear": true,
        "outliers_detected": 2,
        "outlier_percentage": 1.5,
        "position_variance": 0.0008,
        "fps": 60.0
      },
      "warnings": []
    }
  }
}

Confidence Levels:

Common Warnings:

Filtering by Quality:

# Only use high-confidence results
metrics = process_cmj_video("video.mp4")
if metrics.quality_assessment is not None and metrics.quality_assessment.confidence == "high":
    print(f"Reliable jump height: {metrics.jump_height:.3f}m")
elif metrics.quality_assessment is not None:
    print(f"Low quality - warnings: {metrics.quality_assessment.warnings}")

Python API

Use kinemotion as a library for automated pipelines and custom analysis.

Drop Jump API

from kinemotion import process_dropjump_video

# Process a single video
metrics = process_dropjump_video(
    video_path="athlete_jump.mp4",
    quality="balanced",
    verbose=True
)

# Access results
print(f"Jump height: {metrics.jump_height:.3f} m")
print(f"Ground contact time: {metrics.ground_contact_time * 1000:.1f} ms")
print(f"Flight time: {metrics.flight_time * 1000:.1f} ms")

Bulk Video Processing

# Drop jump bulk processing
from kinemotion import DropJumpVideoConfig, process_dropjump_videos_bulk

configs = [
    DropJumpVideoConfig("video1.mp4", quality="balanced"),
    DropJumpVideoConfig("video2.mp4", quality="accurate"),
]

results = process_dropjump_videos_bulk(configs, max_workers=4)

# CMJ bulk processing
from kinemotion import CMJVideoConfig, process_cmj_videos_bulk

cmj_configs = [
    CMJVideoConfig("cmj1.mp4"),
    CMJVideoConfig("cmj2.mp4", quality="accurate"),
]

cmj_results = process_cmj_videos_bulk(cmj_configs, max_workers=4)

for result in cmj_results:
    if result.success:
        print(f"{result.video_path}: {result.metrics.jump_height*100:.1f}cm")

See examples/bulk/README.md for comprehensive API documentation.

CMJ-Specific Features

# Triple extension angles available in metrics
metrics = process_cmj_video("video.mp4", output_video="debug.mp4")

# Debug video shows:
# - Skeleton overlay (foot→shin→femur→trunk)
# - Joint angles (ankle, knee, hip, trunk)
# - Phase-coded visualization

Squat Jump (SJ) API

from kinemotion import process_sj_video

# Mass is required for power/force calculations
metrics = process_sj_video(
    video_path="athlete_sj.mp4",
    mass_kg=75.0,  # Required: athlete body mass
    quality="balanced",
    verbose=True
)

# Access results
print(f"Jump height: {metrics.jump_height:.3f}m")
print(f"Squat hold: {metrics.squat_hold_duration*1000:.1f}ms")
print(f"Concentric: {metrics.concentric_duration*1000:.1f}ms")

# Power/force (only available if mass provided)
if metrics.peak_power:
    print(f"Peak power: {metrics.peak_power:.0f}W")
    print(f"Mean power: {metrics.mean_power:.0f}W")
    print(f"Peak force: {metrics.peak_force:.0f}N")

CSV Export Example

# See examples/bulk/ for complete CSV export examples
from kinemotion import process_cmj_video
import csv

# ... process videos ...
with open("results.csv", "w", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["Video", "GCT (ms)", "Flight (ms)", "Jump (m)"])

    for r in results:
        if r.success and r.metrics:
            writer.writerow([
                Path(r.video_path).name,
                f"{r.metrics.ground_contact_time * 1000:.1f}" if r.metrics.ground_contact_time else "N/A",
                f"{r.metrics.flight_time * 1000:.1f}" if r.metrics.flight_time else "N/A",
                f"{r.metrics.jump_height:.3f}" if r.metrics.jump_height else "N/A",
            ])

See examples/bulk/README.md for comprehensive API documentation and more examples.

Configuration Options

Intelligent Auto-Tuning

Kinemotion automatically optimizes parameters based on your video:

Parameters

All parameters are optional. Kinemotion uses intelligent auto-tuning to select optimal settings based on video characteristics.

Expert Overrides (Rarely Needed)

For advanced users who need manual control:

📖 For detailed parameter explanations, see docs/reference/parameters.md

Note: Most users never need expert parameters - auto-tuning handles optimization automatically!

Output Format

Drop Jump JSON Output

{
  "data": {
    "ground_contact_time_ms": 245.67,
    "flight_time_ms": 456.78,
    "jump_height_m": 0.339,
    "jump_height_kinematic_m": 0.339,
    "jump_height_trajectory_normalized": 0.0845,
    "contact_start_frame": 45,
    "contact_end_frame": 67,
    "flight_start_frame": 68,
    "flight_end_frame": 95,
    "peak_height_frame": 82,
    "contact_start_frame_precise": 45.234,
    "contact_end_frame_precise": 67.891,
    "flight_start_frame_precise": 68.123,
    "flight_end_frame_precise": 94.567
  },
  "metadata": {
    "quality": { },
    "processing_info": { }
  }
}

Data Fields:

Note: Integer frame indices are provided for visualization in debug videos. Precise fractional frames are used for all timing calculations and provide sub-frame accuracy (±10ms at 30fps).

CMJ JSON Output

{
  "data": {
    "jump_height_m": 0.352,
    "flight_time_ms": 534.2,
    "countermovement_depth_m": 0.285,
    "eccentric_duration_ms": 612.5,
    "concentric_duration_ms": 321.8,
    "total_movement_time_ms": 934.3,
    "peak_eccentric_velocity_m_s": -2.145,
    "peak_concentric_velocity_m_s": 3.789,
    "transition_time_ms": 125.4,
    "standing_start_frame": 12.5,
    "lowest_point_frame": 45.2,
    "takeoff_frame": 67.8,
    "landing_frame": 102.3,
    "tracking_method": "foot"
  },
  "metadata": {
    "quality": { },
    "processing_info": { }
  }
}

Data Fields:

Debug Video

The debug video includes:

Troubleshooting

Poor Tracking Quality

Symptoms: Erratic landmark positions, missing detections, incorrect contact states

Solutions:

  1. Check video quality: Ensure the athlete is clearly visible in profile view
  2. Increase smoothing: Use --smoothing-window 7 or higher
  3. Adjust detection confidence: Try --detection-confidence 0.6 or --tracking-confidence 0.6
  4. Generate debug video: Use --output to visualize what’s being tracked

No Pose Detected

Symptoms: “No frames processed” error or all null landmarks

Solutions:

  1. Verify video format: OpenCV must be able to read the video
  2. Check framing: Ensure full body is visible in side view
  3. Lower confidence thresholds: Try --detection-confidence 0.3 --tracking-confidence 0.3
  4. Test video playback: Verify video opens correctly with standard video players

Incorrect Contact Detection

Symptoms: Wrong ground contact times, flight phases not detected

Solutions:

  1. Generate debug video: Visualize contact states to diagnose the issue
  2. Adjust velocity threshold:
    • If missing contacts: decrease to --velocity-threshold 0.01
    • If false contacts: increase to --velocity-threshold 0.03
  3. Adjust minimum frames: --min-contact-frames 5 for longer required contact
  4. Check visibility: Lower --visibility-threshold 0.3 if feet are partially obscured

Jump Height Seems Wrong

Symptoms: Unrealistic jump height values

Solutions:

  1. Check video quality: Ensure video frame rate is adequate (30fps or higher recommended)
  2. Verify flight time detection: Check flight_start_frame and flight_end_frame in JSON
  3. Compare measurements: JSON output includes both jump_height_m (primary) and jump_height_kinematic_m (kinematic-only)
  4. Check for drop jump detection: If doing a drop jump, ensure first phase is elevated enough (>5% of frame height)

Video Codec Issues

Symptoms: Cannot write debug video or corrupted output

Solutions:

  1. Install additional codecs: Ensure OpenCV has proper video codec support
  2. Try different output format: Use .avi extension instead of .mp4
  3. Check output path: Ensure write permissions for output directory

How It Works

  1. Pose Tracking: MediaPipe extracts 2D pose landmarks (foot points: ankles, heels, foot indices) from each frame
  2. Position Calculation: Averages ankle, heel, and foot index positions to determine foot location
  3. Smoothing: Savitzky-Golay filter reduces tracking jitter while preserving motion dynamics
  4. Contact Detection: Analyzes vertical position velocity to identify ground contact vs. flight phases
  5. Phase Identification: Finds continuous ground contact and flight periods
    • Automatically detects drop jumps vs regular jumps
    • For drop jumps: identifies box → drop → ground contact → jump sequence
  6. Sub-Frame Interpolation: Estimates exact transition times between frames
    • Uses Savitzky-Golay derivative for smooth velocity calculation
    • Linear interpolation of velocity to find threshold crossings
    • Achieves sub-millisecond timing precision (at 30fps: ±10ms vs ±33ms)
    • Reduces timing error by 60-70% for contact and flight measurements
    • Smoother velocity curves eliminate false threshold crossings
  7. Trajectory Curvature Analysis: Refines transitions using acceleration patterns
    • Computes second derivative (acceleration) from position trajectory
    • Detects landing impact by acceleration spike
    • Identifies takeoff by acceleration change patterns
    • Provides independent validation and refinement of velocity-based detection
  8. Metric Calculation:
    • Ground contact time = contact phase duration (using fractional frames)
    • Flight time = flight phase duration (using fractional frames)
    • Jump height = kinematic estimate from flight time: (g × t²) / 8

Development

Code Quality Standards

This project enforces strict code quality standards:

Development Commands

# Run the tool
uv run kinemotion dropjump-analyze <video_path>

# Run all tests
uv run pytest

# Run tests with verbose output
uv run pytest -v

# Format code
uv run black src/

# Lint code
uv run ruff check

# Auto-fix linting issues
uv run ruff check --fix

# Type check
uv run pyright

# Run all checks
uv run ruff check && uv run pyright && uv run pytest

Contributing

Before committing code, ensure all checks pass:

  1. Format with Black
  2. Fix linting issues with ruff
  3. Ensure type safety with pyright
  4. Run all tests with pytest

See CONTRIBUTING.md for contribution guidelines and requirements, or CLAUDE.md for detailed development guidelines.

Limitations

Future Enhancements

License

MIT License - feel free to use for personal experiments and research.