Real-time hand tracking using MediaPipe and OpenCV
Project description
Hand Tracking
Real-time hand tracking using MediaPipe and OpenCV. Detects hands via webcam and processes 21 hand landmarks per hand in real time.
Demo
| Feature | Status |
|---|---|
| Webcam capture | ✅ |
| Hand detection | ✅ |
| Landmark processing | ✅ |
| Live display window | ✅ |
How It Works
- Webcam frame captured via OpenCV (
cv2.VideoCapture) - Frame converted BGR → RGB for MediaPipe
- MediaPipe Hands model detects up to 2 hands and returns 21 3D landmarks per hand
- Processed frame rendered in an OpenCV window
MediaPipe Hand Landmarks
MediaPipe tracks 21 keypoints per hand:
8 12 16 20
| | | |
7 11 15 19
| | | |
6 10 14 18
| | | |
5 9 13 17
\ | | /
4 | | 4
\| |/
3 3
| |
2 2
| |
1 1
\ /
0 (WRIST)
Landmark indices map to: 0 = Wrist, 1-4 = Thumb, 5-8 = Index, 9-12 = Middle, 13-16 = Ring, 17-20 = Pinky.
Requirements
- Python 3.11+
- Webcam / camera device
- uv (recommended) or pip
Installation
Install as package via pip
pip install git+https://github.com/muhammadsufiyanbaig/hand-tracking.git
Install as package via uv
uv add git+https://github.com/muhammadsufiyanbaig/hand-tracking.git
Local development with uv (Recommended)
git clone https://github.com/muhammadsufiyanbaig/hand-tracking.git
cd hand-tracking
uv sync
Local development with pip
git clone https://github.com/muhammadsufiyanbaig/hand-tracking.git
cd hand-tracking
python -m venv venv
# Windows
venv\Scripts\activate
# macOS / Linux
source venv/bin/activate
pip install -e .
Usage
CLI (after package install)
hand-tracking
Module
python -m hand_tracking
Script (local dev)
# uv
uv run main.py
# activated venv
python main.py
Press Q to quit.
Project Structure
hand-tracking/
├── hand_tracking/
│ ├── __init__.py # Package init, exposes __version__
│ └── __main__.py # Core tracking logic + CLI entry point
├── main.py # Thin shim for direct script execution
├── hand_landmarker.task # MediaPipe hand landmark model (task file)
├── pyproject.toml # Package metadata, dependencies, build config
├── uv.lock # Locked dependency versions
├── .python-version # Pinned Python version (3.11)
└── README.md
Dependencies
| Package | Version | Purpose |
|---|---|---|
mediapipe |
0.10.9 | Hand landmark detection model |
opencv-python |
≥4.13.0 | Webcam capture and image rendering |
Configuration
mpHands.Hands() accepts optional parameters:
| Parameter | Default | Description |
|---|---|---|
static_image_mode |
False |
True for images, False for video stream |
max_num_hands |
2 |
Maximum number of hands to detect |
min_detection_confidence |
0.5 |
Minimum score to consider detection valid |
min_tracking_confidence |
0.5 |
Minimum score to keep tracking (video mode) |
Example with custom config:
hands = mpHands.Hands(
max_num_hands=1,
min_detection_confidence=0.7,
min_tracking_confidence=0.6
)
Extending the Project
Common next steps:
Draw landmarks on frame:
mpDraw = mp.solutions.drawing_utils
if results.multi_hand_landmarks:
for handLms in results.multi_hand_landmarks:
mpDraw.draw_landmarks(img, handLms, mpHands.HAND_CONNECTIONS)
Read a specific landmark (e.g. index fingertip = landmark 8):
if results.multi_hand_landmarks:
for handLms in results.multi_hand_landmarks:
h, w, _ = img.shape
lm = handLms.landmark[8]
cx, cy = int(lm.x * w), int(lm.y * h)
Display FPS:
pTime = 0
# inside loop:
cTime = time.time()
fps = 1 / (cTime - pTime)
pTime = cTime
cv2.putText(img, f"FPS: {int(fps)}", (10, 70),
cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hand_tracking_mp-0.1.0.tar.gz.
File metadata
- Download URL: hand_tracking_mp-0.1.0.tar.gz
- Upload date:
- Size: 5.9 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa16887153cc5317e930aa947bff96cc0376ed3131b8198cb9266c2bd92e8471
|
|
| MD5 |
fea854389ce6e75b62a553275be1b052
|
|
| BLAKE2b-256 |
ee5b1f020a746effd0682a3fc61e8e8f5e2c9ce9f6b4e191ea3fa5269f3eacfd
|
File details
Details for the file hand_tracking_mp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hand_tracking_mp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 3.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
179330ed3b5176fa3715dd52f03c3190950ef16b4b7e2b207767f0cccec402a6
|
|
| MD5 |
8aa2beb9cdfe2372f7ddf2b7f2f5b594
|
|
| BLAKE2b-256 |
d53c85aaa24bb9f8ff2edb2c2d949ef412e8d2847612e0fccd3758a0c0ee0384
|