Skip to content

Repository files navigation

🎮 HeadTracker — Real-Time Head Tracking for Racing Games

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.


📋 Table of Contents


How It Works

┌──────────┐     ┌────────────┐     ┌──────────────┐     ┌──────────────┐     ┌────────────┐
│  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
  1. Webcam captures your face at 30–60 FPS
  2. MediaPipe FaceMesh detects 468 facial landmarks in 3D
  3. OpenCV solvePnP calculates head rotation (yaw, pitch, roll) from 6 key landmarks
  4. Smoothing pipeline reduces jitter using Exponential Moving Average, optional Kalman filter, One-Euro filter, deadzone, and response curves
  5. Virtual gamepad (via vgamepad/ViGEmBus) maps head rotation to the Xbox 360 right joystick
  6. The game sees a normal Xbox controller — no mods, no cheats, no memory injection

Supported Games

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.


Features

  • ✅ 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

Requirements

Hardware

  • A webcam (built-in laptop camera works fine)
  • Windows 10/11

Software

  • Python 3.11 or newer
  • ViGEmBus driver (for virtual gamepad)

Installation Guide

Step 1: Install Python

If you don't have Python installed:

  1. Go to python.org/downloads
  2. Download Python 3.11 or newer
  3. Run the installer
  4. ⚠️ IMPORTANT: Check the box that says "Add Python to PATH"
  5. Click "Install Now"

Step 2: Verify Python

Open a terminal and verify the installation.

Windows CMD:

python --version
pip --version

PowerShell:

python --version
pip --version

You 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".

Step 3: Download HeadTracker

Download or clone this project to a folder on your computer, e.g.:

F:\Coding\Virtual game camera\headtracker\

Step 4: Create Virtual Environment

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 venv

PowerShell:

cd "F:\Coding\Virtual game camera\headtracker"
python -m venv venv

This creates a venv folder inside the project directory.

Step 5: Activate Virtual Environment

Windows CMD:

venv\Scripts\activate

PowerShell:

.\venv\Scripts\Activate.ps1

PowerShell 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>

Step 6: Install Dependencies

With the virtual environment activated:

pip install -r requirements.txt

This installs:

  • opencv-python — webcam capture and image processing
  • mediapipe — face landmark detection (AI model by Google)
  • numpy — numerical computations
  • PyQt5 — desktop GUI framework
  • vgamepad — virtual Xbox 360 controller emulation
  • pynput — mouse movement (fallback mode)

Step 7: Install ViGEmBus Driver

ViGEmBus is a Windows driver that allows software to create virtual game controllers. HeadTracker needs it to create a virtual Xbox 360 controller.

  1. Go to: github.com/nefarius/ViGEmBus/releases
  2. Download the latest ViGEmBus_Setup_x.x.x.exe
  3. Run the installer and follow the prompts
  4. Restart your computer after installation

How to verify ViGEmBus is installed:

# 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.

Step 8: Run HeadTracker

With the virtual environment activated:

python main.py

The HeadTracker GUI will open. Click Start to begin tracking!


What is a Virtual Environment?

A virtual environment (venv) is an isolated Python installation folder.

Why use it?

  • Isolation: HeadTracker's packages won't conflict with other Python projects on your system
  • Clean uninstall: Delete the venv folder to remove all dependencies
  • Reproducibility: Everyone gets the exact same package versions

How to activate/deactivate:

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.


Usage Guide

Quick Start

  1. Launch the app: python main.py
  2. Click ▶ Start
  3. Look straight at the screen
  4. Click ◎ Calibrate — this sets your current position as "center"
  5. Turn your head left/right — watch the camera move!

Controls

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

Sliders

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

Tips

  • 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

Configuration & Presets

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.


Virtual Gamepad Setup

How it works

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

Testing the virtual controller

  1. Open HeadTracker and click Start
  2. Open Windows Game Controllers panel:
    • Press Win + R, type joy.cpl, press Enter
  3. You should see "Xbox 360 Controller for Windows"
  4. Double-click it → go to the Test tab
  5. Move your head and watch the right stick move!

Mouse Mode (Fallback)

If you can't install ViGEmBus or prefer mouse control:

  1. Change Output Mode to "Mouse" in the Advanced section
  2. HeadTracker will move your mouse cursor instead
  3. Useful for games with mouse-look camera control

In-Game Setup

Forza Horizon 5

  1. Open Forza Horizon 5
  2. Go to Settings → Controls → Advanced Controls
  3. Make sure Camera Look is mapped to the right stick
  4. Start HeadTracker and click Start
  5. Calibrate while looking at the screen
  6. Drive and turn your head!

General (Any Game)

  1. Make sure the game recognizes Xbox controllers
  2. Map the camera/look function to the right joystick
  3. 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

Architecture

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 Responsibilities

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

Troubleshooting

Webcam not detected

Symptoms: "ERROR: Could not open webcam!" when pressing Start

Solutions:

  1. Make sure your webcam is plugged in and not used by another app (Zoom, Teams, etc.)
  2. Try a different Camera index in the Advanced section (Camera 0, 1, 2)
  3. Check Windows Settings → Privacy → Camera → make sure camera access is enabled
  4. Try restarting your computer

MediaPipe installation issues

Symptoms: ImportError: No module named 'mediapipe'

Solutions:

pip install --upgrade mediapipe

If that fails on Python 3.12+:

pip install mediapipe --no-deps
pip install flatbuffers protobuf attrs matplotlib opencv-contrib-python

vgamepad / ViGEmBus issues

Symptoms: "Failed to create virtual gamepad" or "vgamepad not installed"

Solutions:

  1. Install ViGEmBus driver from github.com/nefarius/ViGEmBus/releases
  2. Restart your computer after installing ViGEmBus
  3. Run the test command:
    python -c "import vgamepad as vg; g = vg.VX360Gamepad(); print('OK')"
  4. If vgamepad still fails, HeadTracker will automatically fall back to Mouse mode

Controller not detected in game

Symptoms: HeadTracker works but the game doesn't respond

Solutions:

  1. Make sure the game's camera is mapped to the right joystick
  2. Open joy.cpl (Game Controllers) and verify the virtual controller appears
  3. Start HeadTracker before launching the game
  4. Some games only detect controllers connected at startup — restart the game
  5. If using a physical controller too, the game might prioritize it. Check game settings for multi-controller support

Jittery camera movement

Symptoms: Camera shakes or vibrates even when holding still

Solutions:

  1. Increase Smoothing (move the slider left, lower alpha value)
  2. Increase Deadzone (e.g., 3.0–5.0°)
  3. Enable Kalman Filter in the Advanced section
  4. Make sure you have good lighting — poor lighting makes face detection noisy
  5. Position the webcam at eye level, facing you directly
  6. Calibrate while sitting in your natural position

High latency / camera feels laggy

Symptoms: Camera moves noticeably after head movement

Solutions:

  1. Decrease Smoothing (move the slider right, higher alpha value)
  2. Decrease Deadzone to 1.0–2.0°
  3. Decrease Response Curve to 1.0–1.3 (more linear)
  4. Close other CPU-heavy applications
  5. Make sure your webcam is running at 30 FPS minimum

Low FPS

Symptoms: FPS counter shows below 20

Solutions:

  1. Close other applications using the webcam
  2. Reduce webcam resolution in config.py (try 320×240)
  3. Disable Show Face Mesh in Advanced (reduces rendering load)
  4. Close unnecessary background applications
  5. Make sure your laptop is plugged in (not on battery power-saving mode)

Limitations

  • 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

License

This project is free for personal use. Feel free to modify, share, and build upon it.


Built with ❤️ for the racing sim community.

About

Python webcam-based head tracking system for smooth real-time in-game camera control using OpenCV and MediaPipe.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages