Production-ready backend system for golf swing video analysis using OpenCV, MediaPipe, and Gemini AI.
✅ Video Processing
✅ Pose Detection
✅ Biomechanical Analysis
✅ Swing Phase Detection
✅ Fault Detection
✅ Scoring & Benchmarking
✅ AI Coaching (Gemini AI)
cd c:\Users\dipro\golf_video
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Linux/Mac
pip install -r requirements.txt
copy .env.example .env
Edit .env and add your OpenAI API key:
OPENAI_API_KEY=sk-your-key-here
Directories are auto-created on startup:
data/uploads/ - Uploaded videosdata/outputs/ - Analysis resultsdata/cache/ - Cached datapython main.py
Or with uvicorn:
uvicorn main:app --reload --host 0.0.0.0 --port 8000
API will be available at: http://localhost:8000
Interactive API docs: http://localhost:8000/docs
POST /api/v1/upload
Content-Type: multipart/form-data
file: video.mp4
Response:
{
"job_id": "abc-123-def",
"filename": "video.mp4",
"status": "uploaded"
}
POST /api/v1/analyze?job_id=abc-123-def&language=en&include_coaching=true
Response:
{
"job_id": "abc-123-def",
"status": "processing",
"message": "Analysis started"
}
GET /api/v1/status/{job_id}
Response:
{
"job_id": "abc-123-def",
"status": "completed",
"progress": "100%",
"completed_at": "2026-01-27T10:30:00"
}
GET /api/v1/report/{job_id}
Response: Complete analysis JSON with:
POST /api/v1/compare?job_id_1=abc-123&job_id_2=def-456
golf_video/
├── main.py # FastAPI application entry
├── requirements.txt # Python dependencies
├── .env.example # Environment template
│
├── core/ # Core configuration
│ ├── __init__.py
│ └── config.py # Settings & config
│
├── models/ # Pydantic data models
│ ├── __init__.py
│ ├── video.py # Video metadata
│ ├── pose.py # Pose landmarks
│ ├── biomechanics.py # Biomechanical data
│ ├── swing_phase.py # Swing phases
│ ├── faults.py # Fault detection
│ ├── scoring.py # Scoring models
│ └── analysis.py # Request/response
│
├── video/ # Video processing
│ ├── __init__.py
│ └── processor.py # VideoProcessor class
│
├── pose/ # Pose detection
│ ├── __init__.py
│ └── detector.py # PoseDetector class
│
├── biomechanics/ # Biomechanical analysis
│ ├── __init__.py
│ ├── analyzer.py # BiomechanicsAnalyzer
│ └── utils.py # Math utilities
│
├── swing_phase/ # Phase detection
│ ├── __init__.py
│ └── detector.py # SwingPhaseDetector
│
├── fault_detection/ # Fault detection
│ ├── __init__.py
│ └── detector.py # FaultDetector
│
├── scoring/ # Scoring system
│ ├── __init__.py
│ └── scorer.py # SwingScorer
│
├── ai/ # Gemini AI integration
│ ├── __init__.py
│ └── coaching.py # CoachingAI
│
├── analysis/ # Main pipeline
│ ├── __init__.py
│ └── pipeline.py # AnalysisPipeline
│
└── api/ # FastAPI routes
├── __init__.py
└── routes.py # API endpoints
Edit core/config.py or .env to customize:
MAX_VIDEO_SIZE_MB - Maximum file size (default: 100MB)MAX_VIDEO_DURATION_SEC - Maximum duration (default: 10s)TARGET_FPS - Target frame rate (default: 30)TARGET_HEIGHT - Target resolution (default: 720p)MEDIAPIPE_MODEL_COMPLEXITY - 0, 1, or 2 (default: 2)MEDIAPIPE_MIN_DETECTION_CONFIDENCE - Detection threshold (default: 0.5)MEDIAPIPE_MIN_TRACKING_CONFIDENCE - Tracking threshold (default: 0.5)pytest
black .
flake8 .
Set in .env:
DEBUG=True
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
Replace in-memory storage with Redis/Database:
# In api/routes.py
import redis
job_results = redis.Redis(host='localhost', port=6379, db=0)
DEBUG=False
USE_GPU=True # If GPU available
USE_GPU=True if CUDA availableFRAME_SKIP for faster processingMEDIAPIPE_MODEL_COMPLEXITY for speedpip install mediapipe --no-cache-dir
pip install opencv-python-headless
Check CUDA installation and set USE_GPU=False
{
"job_id": "abc-123",
"status": "completed",
"video_metadata": {
"filename": "golf_swing.mp4",
"duration_sec": 5.2,
"fps": 30,
"total_frames": 156
},
"scores": {
"overall_score": 72.5,
"tempo_score": 85.0,
"power_score": 68.0,
"balance_score": 75.0,
"consistency_score": 70.0,
"skill_level": "intermediate"
},
"detected_faults": {
"total_faults": 2,
"critical_faults": [
{
"fault_type": "early_extension",
"severity": 0.72,
"description": "Hips thrusting forward during downswing"
}
]
},
"coaching_feedback": {
"overall_summary": "Your swing shows good tempo and balance. Focus on preventing early extension for more consistent contact.",
"key_strengths": [
"Excellent tempo ratio of 3.2:1",
"Good balance throughout swing",
"Strong rotation mechanics"
],
"improvement_areas": [
"Reduce early extension in downswing",
"Maintain posture through impact",
"Improve weight transfer"
],
"coaching_tips": [
"Practice wall drill to maintain spine angle",
"Focus on sitting into the shot",
"Keep your head behind the ball at impact"
],
"drill_recommendations": [
"Wall drill for posture",
"Step drill for weight transfer",
"Slow motion swings"
]
}
}
MIT License
For issues and questions, please open an issue on GitHub.
Built for Golfers 🏌️ | Powered by AI 🤖
Production-ready backend system for golf swing video analysis using OpenCV, MediaPipe, and Gemini AI.
✅ Video Processing
✅ Pose Detection
✅ Biomechanical Analysis
✅ Swing Phase Detection
✅ Fault Detection
✅ Scoring & Benchmarking
✅ AI Coaching (Gemini AI)
cd c:\Users\dipro\golf_video
python -m venv venv
venv\Scripts\activate # Windows
# source venv/bin/activate # Linux/Mac
pip install -r requirements.txt
copy .env.example .env
Edit .env and add your OpenAI API key:
OPENAI_API_KEY=sk-your-key-here
Directories are auto-created on startup:
data/uploads/ - Uploaded videosdata/outputs/ - Analysis resultsdata/cache/ - Cached datapython main.py
Or with uvicorn:
uvicorn main:app --reload --host 0.0.0.0 --port 8000
API will be available at: http://localhost:8000
Interactive API docs: http://localhost:8000/docs
POST /api/v1/upload
Content-Type: multipart/form-data
file: video.mp4
Response:
{
"job_id": "abc-123-def",
"filename": "video.mp4",
"status": "uploaded"
}
POST /api/v1/analyze?job_id=abc-123-def&language=en&include_coaching=true
Response:
{
"job_id": "abc-123-def",
"status": "processing",
"message": "Analysis started"
}
GET /api/v1/status/{job_id}
Response:
{
"job_id": "abc-123-def",
"status": "completed",
"progress": "100%",
"completed_at": "2026-01-27T10:30:00"
}
GET /api/v1/report/{job_id}
Response: Complete analysis JSON with:
POST /api/v1/compare?job_id_1=abc-123&job_id_2=def-456
golf_video/
├── main.py # FastAPI application entry
├── requirements.txt # Python dependencies
├── .env.example # Environment template
│
├── core/ # Core configuration
│ ├── __init__.py
│ └── config.py # Settings & config
│
├── models/ # Pydantic data models
│ ├── __init__.py
│ ├── video.py # Video metadata
│ ├── pose.py # Pose landmarks
│ ├── biomechanics.py # Biomechanical data
│ ├── swing_phase.py # Swing phases
│ ├── faults.py # Fault detection
│ ├── scoring.py # Scoring models
│ └── analysis.py # Request/response
│
├── video/ # Video processing
│ ├── __init__.py
│ └── processor.py # VideoProcessor class
│
├── pose/ # Pose detection
│ ├── __init__.py
│ └── detector.py # PoseDetector class
│
├── biomechanics/ # Biomechanical analysis
│ ├── __init__.py
│ ├── analyzer.py # BiomechanicsAnalyzer
│ └── utils.py # Math utilities
│
├── swing_phase/ # Phase detection
│ ├── __init__.py
│ └── detector.py # SwingPhaseDetector
│
├── fault_detection/ # Fault detection
│ ├── __init__.py
│ └── detector.py # FaultDetector
│
├── scoring/ # Scoring system
│ ├── __init__.py
│ └── scorer.py # SwingScorer
│
├── ai/ # Gemini AI integration
│ ├── __init__.py
│ └── coaching.py # CoachingAI
│
├── analysis/ # Main pipeline
│ ├── __init__.py
│ └── pipeline.py # AnalysisPipeline
│
└── api/ # FastAPI routes
├── __init__.py
└── routes.py # API endpoints
Edit core/config.py or .env to customize:
MAX_VIDEO_SIZE_MB - Maximum file size (default: 100MB)MAX_VIDEO_DURATION_SEC - Maximum duration (default: 10s)TARGET_FPS - Target frame rate (default: 30)TARGET_HEIGHT - Target resolution (default: 720p)MEDIAPIPE_MODEL_COMPLEXITY - 0, 1, or 2 (default: 2)MEDIAPIPE_MIN_DETECTION_CONFIDENCE - Detection threshold (default: 0.5)MEDIAPIPE_MIN_TRACKING_CONFIDENCE - Tracking threshold (default: 0.5)pytest
black .
flake8 .
Set in .env:
DEBUG=True
gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
Replace in-memory storage with Redis/Database:
# In api/routes.py
import redis
job_results = redis.Redis(host='localhost', port=6379, db=0)
DEBUG=False
USE_GPU=True # If GPU available
USE_GPU=True if CUDA availableFRAME_SKIP for faster processingMEDIAPIPE_MODEL_COMPLEXITY for speedpip install mediapipe --no-cache-dir
pip install opencv-python-headless
Check CUDA installation and set USE_GPU=False
{
"job_id": "abc-123",
"status": "completed",
"video_metadata": {
"filename": "golf_swing.mp4",
"duration_sec": 5.2,
"fps": 30,
"total_frames": 156
},
"scores": {
"overall_score": 72.5,
"tempo_score": 85.0,
"power_score": 68.0,
"balance_score": 75.0,
"consistency_score": 70.0,
"skill_level": "intermediate"
},
"detected_faults": {
"total_faults": 2,
"critical_faults": [
{
"fault_type": "early_extension",
"severity": 0.72,
"description": "Hips thrusting forward during downswing"
}
]
},
"coaching_feedback": {
"overall_summary": "Your swing shows good tempo and balance. Focus on preventing early extension for more consistent contact.",
"key_strengths": [
"Excellent tempo ratio of 3.2:1",
"Good balance throughout swing",
"Strong rotation mechanics"
],
"improvement_areas": [
"Reduce early extension in downswing",
"Maintain posture through impact",
"Improve weight transfer"
],
"coaching_tips": [
"Practice wall drill to maintain spine angle",
"Focus on sitting into the shot",
"Keep your head behind the ball at impact"
],
"drill_recommendations": [
"Wall drill for posture",
"Step drill for weight transfer",
"Slow motion swings"
]
}
}
MIT License
For issues and questions, please open an issue on GitHub.
Built for Golfers 🏌️ | Powered by AI 🤖