Turn your head in real life → camera moves in-game
HeadTracker is a production-quality, open-source head tracking system that uses your normal webcam to control the in-game camera in racing games like Forza Horizon 5, Assetto Corsa, Euro Truck Simulator 2, and iRacing.
No special hardware required. No game file modifications. Just plug in your webcam and go.
- How It Works
- Supported Games
- Features
- Requirements
- Installation Guide
- What is a Virtual Environment?
- Usage Guide
- Configuration & Presets
- Virtual Gamepad Setup
- In-Game Setup
- Architecture
- Troubleshooting
- Limitations
- License
┌──────────┐ ┌────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐
│ Webcam │────▶│ MediaPipe │────▶│ solvePnP │────▶│ Smoothing │────▶│ Virtual │
│ Input │ │ FaceMesh │ │ Pose Est. │ │ Pipeline │ │ Gamepad │
└──────────┘ └────────────┘ └──────────────┘ └──────────────┘ └────────────┘
30-60 FPS 468 landmarks yaw/pitch/roll EMA + Kalman Xbox 360
video feed 3D face mesh in degrees + deadzone right stick
- Webcam captures your face at 30–60 FPS
- MediaPipe FaceMesh detects 468 facial landmarks in 3D
- OpenCV solvePnP calculates head rotation (yaw, pitch, roll) from 6 key landmarks
- Smoothing pipeline reduces jitter using Exponential Moving Average, optional Kalman filter, One-Euro filter, deadzone, and response curves
- Virtual gamepad (via vgamepad/ViGEmBus) maps head rotation to the Xbox 360 right joystick
- The game sees a normal Xbox controller — no mods, no cheats, no memory injection
| Game | Preset Included | Camera Control |
|---|---|---|
| Forza Horizon 5 | ✅ | Right stick camera |
| Assetto Corsa | ✅ | Right stick camera |
| Euro Truck Simulator 2 | ✅ | Right stick camera |
| iRacing | ✅ | Right stick camera |
| Any game with controller camera | ✅ | Configure sensitivity |
HeadTracker works with any game that supports Xbox 360 controller input for camera control. The presets above are just optimized starting points.
- ✅ Real-time head tracking via normal webcam
- ✅ Proper head pose estimation (solvePnP, not just nose position)
- ✅ Proportional camera movement (small head turn = small camera turn)
- ✅ Smooth return to center when you look back
- ✅ Exponential Moving Average smoothing
- ✅ Optional Kalman filter
- ✅ One-Euro adaptive filter (less lag during fast movement)
- ✅ Adjustable deadzone (ignores tiny movements)
- ✅ Nonlinear response curve (fine control near center)
- ✅ Virtual Xbox 360 gamepad output
- ✅ Mouse output mode (fallback)
- ✅ Clean PyQt5 GUI with dark theme
- ✅ Live webcam preview with face mesh overlay
- ✅ Real-time telemetry (yaw, pitch, FPS, joystick values)
- ✅ Calibration system (set neutral head position)
- ✅ Game-specific presets
- ✅ Axis inversion
- ✅ Threaded webcam capture (low latency)
- ✅ Works 100% externally — no game modification
- A webcam (built-in laptop camera works fine)
- Windows 10/11
- Python 3.11 or newer
- ViGEmBus driver (for virtual gamepad)
If you don't have Python installed:
- Go to python.org/downloads
- Download Python 3.11 or newer
- Run the installer
⚠️ IMPORTANT: Check the box that says "Add Python to PATH"- Click "Install Now"
Open a terminal and verify the installation.
Windows CMD:
python --version
pip --versionPowerShell:
python --version
pip --versionYou should see something like:
Python 3.11.x
pip 23.x.x
If you see an error, Python is not in your PATH. Reinstall Python and make sure to check "Add Python to PATH".
Download or clone this project to a folder on your computer, e.g.:
F:\Coding\Virtual game camera\headtracker\
A virtual environment keeps HeadTracker's dependencies separate from your other Python projects.
Windows CMD:
cd /d "F:\Coding\Virtual game camera\headtracker"
python -m venv venvPowerShell:
cd "F:\Coding\Virtual game camera\headtracker"
python -m venv venvThis creates a venv folder inside the project directory.
Windows CMD:
venv\Scripts\activatePowerShell:
.\venv\Scripts\Activate.ps1PowerShell execution policy error? Run this first:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
When activated, you'll see (venv) at the start of your command prompt:
(venv) F:\Coding\Virtual game camera\headtracker>
With the virtual environment activated:
pip install -r requirements.txtThis installs:
opencv-python— webcam capture and image processingmediapipe— face landmark detection (AI model by Google)numpy— numerical computationsPyQt5— desktop GUI frameworkvgamepad— virtual Xbox 360 controller emulationpynput— mouse movement (fallback mode)
ViGEmBus is a Windows driver that allows software to create virtual game controllers. HeadTracker needs it to create a virtual Xbox 360 controller.
- Go to: github.com/nefarius/ViGEmBus/releases
- Download the latest
ViGEmBus_Setup_x.x.x.exe - Run the installer and follow the prompts
- Restart your computer after installation
# In PowerShell, run this quick test:
python -c "import vgamepad as vg; g = vg.VX360Gamepad(); print('Virtual gamepad created successfully!')"If you see "Virtual gamepad created successfully!" — you're good to go.
With the virtual environment activated:
python main.pyThe HeadTracker GUI will open. Click Start to begin tracking!
A virtual environment (venv) is an isolated Python installation folder.
- Isolation: HeadTracker's packages won't conflict with other Python projects on your system
- Clean uninstall: Delete the
venvfolder to remove all dependencies - Reproducibility: Everyone gets the exact same package versions
| Action | CMD | PowerShell |
|---|---|---|
| Activate | venv\Scripts\activate |
.\venv\Scripts\Activate.ps1 |
| Deactivate | deactivate |
deactivate |
You must activate the venv every time you open a new terminal to run HeadTracker.
- Launch the app:
python main.py - Click ▶ Start
- Look straight at the screen
- Click ◎ Calibrate — this sets your current position as "center"
- Turn your head left/right — watch the camera move!
| Button | What it does |
|---|---|
| ▶ Start | Opens webcam and starts tracking |
| ■ Stop | Stops tracking and releases webcam |
| ◎ Calibrate | Sets current head position as center |
| ⊕ Recenter | Resets smoothing and centers joystick |
| Slider | Range | What it does |
|---|---|---|
| Sensitivity (Yaw) | 0.10–3.00 | How much the camera moves for a given head turn |
| Sensitivity (Pitch) | 0.10–3.00 | Same for up/down |
| Smoothing | 0.05–0.95 | Lower = smoother (more lag). Higher = more responsive (more jitter) |
| Deadzone | 0.0°–10.0° | Ignores head movements smaller than this |
| Response Curve | 0.50–3.00 | >1 = fine control near center. 1 = linear |
| Max Range | 10°–90° | Maximum head turn angle |
- Start with the Forza Horizon 5 preset
- Calibrate when sitting in your normal position
- If the camera jitters, lower the smoothing slider
- If the camera feels laggy, raise the smoothing slider
- Use deadzone to ignore small involuntary movements
HeadTracker includes optimized presets for popular games:
| Preset | Sensitivity | Deadzone | Smoothing | Curve | Range |
|---|---|---|---|---|---|
| Default | 1.0 / 1.0 | 2.0° | 0.40 | 1.50 | 30° |
| Forza Horizon 5 | 1.3 / 0.8 | 3.0° | 0.35 | 1.80 | 35° |
| Assetto Corsa | 1.5 / 1.0 | 2.5° | 0.30 | 1.60 | 40° |
| Euro Truck Sim 2 | 1.8 / 1.2 | 2.0° | 0.30 | 1.40 | 50° |
| iRacing | 1.2 / 0.7 | 1.5° | 0.25 | 1.30 | 30° |
| High Sensitivity | 2.0 / 1.5 | 1.0° | 0.50 | 1.20 | 25° |
| Low Sensitivity | 0.6 / 0.4 | 4.0° | 0.20 | 2.00 | 45° |
Select a preset from the dropdown menu in the top-right corner of the GUI.
HeadTracker creates a virtual Xbox 360 controller on your system using the ViGEmBus driver. This controller appears as a real gamepad to Windows and all games.
Head rotation is mapped to the right joystick of this virtual controller:
- Head left → Right stick left → Camera looks left
- Head right → Right stick right → Camera looks right
- Head up → Right stick up → Camera looks up
- Head down → Right stick down → Camera looks down
- Open HeadTracker and click Start
- Open Windows Game Controllers panel:
- Press
Win + R, typejoy.cpl, press Enter
- Press
- You should see "Xbox 360 Controller for Windows"
- Double-click it → go to the Test tab
- Move your head and watch the right stick move!
If you can't install ViGEmBus or prefer mouse control:
- Change Output Mode to "Mouse" in the Advanced section
- HeadTracker will move your mouse cursor instead
- Useful for games with mouse-look camera control
- Open Forza Horizon 5
- Go to Settings → Controls → Advanced Controls
- Make sure Camera Look is mapped to the right stick
- Start HeadTracker and click Start
- Calibrate while looking at the screen
- Drive and turn your head!
- Make sure the game recognizes Xbox controllers
- Map the camera/look function to the right joystick
- If using both a physical controller and HeadTracker simultaneously, some games may need you to use the physical controller for driving and HeadTracker for camera
headtracker/
├── main.py # Entry point — launches GUI, checks dependencies
├── config.py # All configuration constants, presets, save/load
├── camera.py # Threaded webcam capture (30-60 FPS)
├── tracker.py # MediaPipe FaceMesh face landmark detection
├── pose_estimator.py # cv2.solvePnP → yaw/pitch/roll estimation
├── smoothing.py # EMA, Kalman, One-Euro, deadzone, response curve
├── controller_output.py # vgamepad (Xbox) & pynput (mouse) output
├── gui.py # PyQt5 desktop GUI with dark theme
├── requirements.txt # Python dependencies
└── README.md # This file
| Module | Role |
|---|---|
camera.py |
Runs webcam in a background thread for non-blocking capture |
tracker.py |
Detects 468 facial landmarks using Google's MediaPipe FaceMesh |
pose_estimator.py |
Uses 6 key landmarks + solvePnP to calculate 3D head rotation |
smoothing.py |
Chains EMA → One-Euro → deadzone → response curve → clamp |
controller_output.py |
Maps [-1, +1] normalized values to joystick range [-32768, 32767] |
gui.py |
Real-time preview, telemetry, sliders, and controls |
config.py |
Centralized settings — no magic numbers in the codebase |
Symptoms: "ERROR: Could not open webcam!" when pressing Start
Solutions:
- Make sure your webcam is plugged in and not used by another app (Zoom, Teams, etc.)
- Try a different Camera index in the Advanced section (Camera 0, 1, 2)
- Check Windows Settings → Privacy → Camera → make sure camera access is enabled
- Try restarting your computer
Symptoms: ImportError: No module named 'mediapipe'
Solutions:
pip install --upgrade mediapipeIf that fails on Python 3.12+:
pip install mediapipe --no-deps
pip install flatbuffers protobuf attrs matplotlib opencv-contrib-pythonSymptoms: "Failed to create virtual gamepad" or "vgamepad not installed"
Solutions:
- Install ViGEmBus driver from github.com/nefarius/ViGEmBus/releases
- Restart your computer after installing ViGEmBus
- Run the test command:
python -c "import vgamepad as vg; g = vg.VX360Gamepad(); print('OK')" - If vgamepad still fails, HeadTracker will automatically fall back to Mouse mode
Symptoms: HeadTracker works but the game doesn't respond
Solutions:
- Make sure the game's camera is mapped to the right joystick
- Open
joy.cpl(Game Controllers) and verify the virtual controller appears - Start HeadTracker before launching the game
- Some games only detect controllers connected at startup — restart the game
- If using a physical controller too, the game might prioritize it. Check game settings for multi-controller support
Symptoms: Camera shakes or vibrates even when holding still
Solutions:
- Increase Smoothing (move the slider left, lower alpha value)
- Increase Deadzone (e.g., 3.0–5.0°)
- Enable Kalman Filter in the Advanced section
- Make sure you have good lighting — poor lighting makes face detection noisy
- Position the webcam at eye level, facing you directly
- Calibrate while sitting in your natural position
Symptoms: Camera moves noticeably after head movement
Solutions:
- Decrease Smoothing (move the slider right, higher alpha value)
- Decrease Deadzone to 1.0–2.0°
- Decrease Response Curve to 1.0–1.3 (more linear)
- Close other CPU-heavy applications
- Make sure your webcam is running at 30 FPS minimum
Symptoms: FPS counter shows below 20
Solutions:
- Close other applications using the webcam
- Reduce webcam resolution in
config.py(try 320×240) - Disable Show Face Mesh in Advanced (reduces rendering load)
- Close unnecessary background applications
- Make sure your laptop is plugged in (not on battery power-saving mode)
- Single face only — tracks only one person
- Requires decent lighting — very dark environments reduce accuracy
- CPU-based — uses ~10-20% CPU on a modern processor
- Webcam quality matters — a better webcam gives smoother tracking
- Windows only — ViGEmBus/vgamepad only works on Windows (mouse mode works cross-platform)
- Not a replacement for TrackIR — this is a free, webcam-based alternative. Dedicated hardware will always be more precise
This project is free for personal use. Feel free to modify, share, and build upon it.
Built with ❤️ for the racing sim community.