A professional multi-camera video analysis application for bike fitting and biomechanical analysis. Features AI-powered pose detection, real-time angle measurements, zoom/pan controls, and synchronized multi-view recording.
- Up to 4 cameras simultaneously in a 2x2 grid layout
- Flexible quadrant system - enable/disable individual camera positions
- Custom camera names - label cameras (e.g., "Side View", "Front View")
- Persistent layouts - camera positions saved between sessions
- Video file playback - load and analyze recorded sessions
- Real-time pose estimation using MediaPipe
- 33 body landmarks with automatic tracking
- Cycling-specific angles: knee, hip, ankle, elbow, shoulder, back
- Live angle display overlaid on video feed
- Pause and adjust - freeze frame and manually correct joint positions
- Persistent adjustments - manual corrections track with live video
- Synchronized recording from all active cameras
- Automatic organization by athlete/bike/date
- Angle data export - JSON file with per-frame angle measurements
- Frame buffer - pause live cameras and scrub through last 10 seconds
- Video controls - play, pause, speed adjustment (0.25x-1x), loop
- Timeline scrubbing - slider to jump to any frame
- Dynamic zoom - 1.0x to 4.0x in 0.25x increments
- Click-and-drag panning when zoomed in
- Per-camera zoom state - independent zoom for each view
- Reset to default - click zoom level to return to 1.0x
- Athlete profiles - organize recordings by athlete
- Multiple bikes per athlete - separate fits for different setups
- Change session on-the-fly - switch athlete/bike without restart
- Auto-created directories - structured file organization
- Settings persistence - camera names and positions saved
- Clone the repository:
git clone https://github.com/andrefecto/framelab.git
cd framelab- Create virtual environment:
python3 -m venv venv-
Activate virtual environment:
- macOS/Linux:
source venv/bin/activate - Windows:
venv\Scripts\activate
- macOS/Linux:
-
Install dependencies:
pip install -r requirements.txt- Run the application:
python main.py- Set default directory - choose or create folder for athlete data
- Create/select athlete - enter athlete name or pick existing
- Create/select bike - enter bike name or pick existing
- Configure cameras - application auto-detects connected cameras
- Start analyzing - cameras display in quadrant layout
-
Rename cameras: File → Camera Names
- Give each camera a friendly name (e.g., "Side Camera")
- Names appear in dropdowns and video filenames
-
Assign to quadrants: Use dropdown in each quadrant
- Select camera from list
- Choose "(None)" to clear quadrant
- Drag between quadrants to rearrange
-
Enable/disable quadrants: View → Configure Quadrants
- Toggle checkboxes to show/hide quadrants
- Layout automatically adjusts
- Enable pose detection: View → Toggle Pose Detection
- Click Record button in any camera's control bar
- Ride naturally - pose and angles tracked in real-time
- Click Stop when finished
- Files saved automatically:
- Video:
YYYY-MM-DD_HH-MM-SS_CameraName.mp4 - Angles:
YYYY-MM-DD_HH-MM-SS_CameraName_angles.json
- Video:
- Pause the camera (live cameras only)
- Click on any joint/landmark
- Drag to correct position
- Angles recalculate in real-time
- Resume - adjustments track with live pose
- Pause camera to freeze current frame
- Use << >> buttons to step frame-by-frame
- Drag timeline slider to jump to specific frame
- Buffer holds last 10 seconds (~300 frames)
- Pose detection re-runs on each frame
- Click + button to zoom in (up to 4.0x)
- Click zoom level to reset to 1.0x
- Click - button to zoom out
- Click and drag on video to pan when zoomed
- Works on live and recorded video
- Select quadrant and choose "Load Video..."
- Browse to recorded video file
- Use playback controls:
- Play/Pause
- Loop toggle
- Speed (0.25x, 0.5x, 0.75x, 1x)
- Timeline scrubber
- Enable pose detection to analyze recorded footage
framelab/
├── main.py # Application entry point
├── camera/
│ ├── camera.py # Camera class with capture, recording, pose
│ └── detection.py # Camera detection utilities
├── pose/
│ ├── estimator.py # MediaPipe pose estimation
│ └── renderer.py # Angle calculation and visualization
├── gui/
│ ├── layout.py # Main window layout and camera grid
│ ├── quadrants.py # Quadrant management
│ ├── startup.py # Startup workflow (athlete/bike selection)
│ ├── dialogs.py # File dialogs
│ ├── pose_editor.py # Manual pose adjustment
│ └── state.py # Global application state
├── athlete/
│ └── manager.py # Athlete/bike directory management
├── utils/
│ ├── logger.py # Logging configuration
│ └── settings.py # Settings persistence
└── requirements.txt # Python dependencies
- Python: 3.9-3.12 (MediaPipe compatibility)
- OS: Windows 10+, macOS 10.14+, Linux (Ubuntu 18.04+)
- RAM: 4GB minimum, 8GB+ recommended
- Camera: USB webcams (720p minimum, 1080p recommended)
- GPU: Any modern GPU (DearPyGUI uses GPU acceleration)
- DearPyGUI - GPU-accelerated Python UI framework
- MediaPipe - Google's pose estimation library
- OpenCV - Computer vision and video I/O
- NumPy - Numerical computing
See requirements.txt for complete list with versions.
Automatically created in project root. Stores:
- Default athlete data directory
- Camera friendly names (by camera ID)
- Camera quadrant positions (by camera ID)
Example:
{
"default_directory": "/Users/name/bike_data",
"camera_names": {
"0": "Side Camera",
"1": "Front Camera"
},
"camera_positions": {
"0": 0,
"1": 1
}
}Recordings are automatically organized:
{default_directory}/
└── {athlete_name}/
└── {bike_name}/
├── 2025-11-11_13-45-30_Side_Camera.mp4
├── 2025-11-11_13-45-30_Side_Camera_angles.json
├── 2025-11-11_13-47-15_Front_Camera.mp4
└── 2025-11-11_13-47-15_Front_Camera_angles.json
The application calculates and displays these cycling-specific angles:
- Knee Angle - angle at knee joint during pedal stroke
- Hip Angle - hip flexion angle
- Ankle Angle - ankle dorsiflexion/plantarflexion
- Elbow Angle - arm bend at elbow
- Shoulder Angle - shoulder position relative to torso
- Back Angle - torso angle relative to horizontal
Angles are displayed in degrees directly on the video feed.
Currently none - all controls via UI buttons. Future versions may add shortcuts.
- Not detected: Check system camera permissions
- Black screen: Wait 2-3 frames for initialization
- Wrong camera selected: Use dropdown to switch cameras
- Poor tracking: Ensure good lighting and full body in frame
- Inaccurate: Improve lighting, minimize background clutter
- Missing landmarks: Ensure full body visible in frame
- Can't click points: Pose detection must be enabled and camera paused
- Files not saving: Check disk space and directory permissions
- Video choppy: Reduce number of active cameras
- Angles missing: Enable pose detection before recording
- Low FPS: Reduce number of active cameras or disable pose detection
- High CPU usage: Normal with multiple cameras and pose detection
- Memory issues: Close other applications, reduce frame buffer size
- Maximum 4 cameras simultaneously (2x2 grid)
- Frame buffer limited to last 10 seconds for live cameras
- Pose detection requires clear view of body
- Manual adjustments only available when paused (live cameras)
- Video files cannot be renamed from within app
- Synchronize playback across multiple loaded videos
- Export comparison reports (PDF/CSV)
- Custom angle definitions
- Measurement overlays (distances, not just angles)
- Keyboard shortcuts
- Dark/light theme toggle
- Save pose adjustments to separate file
- Batch processing of recorded videos
- Drag Coefficient Calculations
- Automatic bike measurements
Contributions welcome! To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/YourFeature) - Commit your changes (
git commit -m 'Add YourFeature') - Push to branch (
git push origin feature/YourFeature) - Open a Pull Request
Please follow existing code style and add appropriate logging.
GPL-3.0 License - see LICENSE file for details.
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
- DearPyGUI - Modern GPU-accelerated Python UI
- MediaPipe - Real-time pose estimation by Google
- OpenCV - Computer vision foundation
- Cycling and bike fitting community for feedback
- Issues: GitHub Issues
- Discussions: GitHub Discussions
If you find this project useful and would like to support its development, consider making a donation:
- GitHub Sponsors: Sponsor this project
- PayPal: paypal.me/AndreFecteau
- Buy Me a Coffee: buymeacoffee.com/andrefecto
Your support helps maintain and improve this free and open-source tool for the cycling community!
Built for bike fitters, coaches, and cyclists who want professional-grade analysis tools without subscription fees.
If this project helps you, please give it a ⭐ on GitHub!