This small program opens your webcam, detects up to 2 hands, and draws a hand landmark skeleton so you can see tracking quality in real time. It also tracks pinch counters for each hand separately.
It supports both MediaPipe APIs:
- Older API:
mp.solutions.hands - Newer API:
mp.tasks.vision.HandLandmarker(used on Python 3.13+ builds wheremp.solutionsis unavailable)
hand_skeleton_component.py: entrypoint (CLI run target)gesture_config.py: runtime config + argument parsingcamera_utils.py: camera backend probing/open helpershand_skeleton_app.py: hand-tracking app logic, gesture state, renderingmini_game.py: Ping Pong game mode logicsign_mode.py: Sign Language learner/practice mode controllersign_curriculum.py: built-in words/sentences for sign lessons
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtpython hand_skeleton_component.pyOn newer MediaPipe builds, the first run auto-downloads the hand model file to:
/Users/vaibhavkrishali/Desktop/musicGestures/models/hand_landmarker.taskIf auto-download fails, download it manually:
mkdir -p /Users/vaibhavkrishali/Desktop/musicGestures/models
curl -L "https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task" \
-o /Users/vaibhavkrishali/Desktop/musicGestures/models/hand_landmarker.taskOptional arguments:
python hand_skeleton_component.py --camera 0 --camera-backend avfoundation --target-fps 60 --capture-width 960 --capture-height 540 --inference-interval 1 --inference-scale 0.6 --max-hands 2 --min-det-confidence 0.5 --min-track-confidence 0.5If you already have a model file downloaded:
python hand_skeleton_component.py --model-path /absolute/path/to/hand_landmarker.taskTry this preset:
python hand_skeleton_component.py --camera-backend avfoundation --target-fps 60 --capture-width 960 --capture-height 540 --inference-interval 1 --inference-scale 0.6Notes:
- The app now requests 60 FPS from the camera.
- Actual FPS depends on your camera + lighting + CPU load.
- The app uses a threaded inference worker by default for smoother rendering.
- The overlay shows processing FPS, inference FPS, camera FPS, and acceleration mode.
- For higher smoothness on slower CPUs, increase
--inference-interval(e.g.3or4). - For faster inference, lower
--inference-scale(e.g.0.5). - To force CPU path: add
--cpu-only - To disable threaded worker: add
--single-thread
qorEsc: quitn: toggle landmark ID labels (0..20)c: toggle counters/HUD overlay1: toggle Ping Pong game mode on/off2: switch game toTwo Playermode3: switch game toBotmode4: toggleSign Languagemode on/off[ / ]: decrease/increase sign confidence threshold- / +: decrease/increase sign hold framesr: reset Ping Pong score (when game mode is active)
The display is fixed to selfie-style mirror mode so your left hand appears on the left side of the screen.
The app includes a basic pong-style game in game mode:
- Left paddle and right paddle move only vertically.
- Power-ups spawn from center and move toward left/right sides with weighted-random fairness.
- Paddle-touch pickup model:
- touching a power-up with your paddle activates it for that side.
- missed power-ups leave the court and are lost.
- Power-ups implemented:
Speed Ball: next hit from that side launches a very fast shot.Paddle Size: paddle grows for ~5 seconds.Shield: one-time wall save; missed ball reflects instead of conceding.Chaos Orb: next hit adds a random directional chaos offset.
Two Playermode:- waits for two tracked hands before starting.
- shows detected hand combination (right/left counts) before kickoff.
- left-most visible hand controls left paddle; right-most controls right paddle.
Botmode:- one visible hand controls left paddle.
- right paddle is controlled by a bot.
Press 4 to enter Sign Language mode.
Learner ModePractice Mode
Buttons can be clicked using:
- hand pinch click (
index + thumbat cursor position) - mouse click fallback
Press 4 again to exit Sign mode back to plain view.
Includes three levels:
Level 1: Alphabet drill (single letter with reference image)Level 2: Word building (letter-by-letter progression with reference image)Level 3: Sentence building (word-style flow with spaces auto-skipped)
Each letter has a blank above it. Correct answer turns blank into a tick and advances.
- Uses sentence prompts
- No reference image shown
- Per-letter feedback:
- wrong stable sign -> cross
- correct stable sign -> tick and advance
Sign template images are loaded from:
assets/signs/alphabet
See details and naming rules in:
assets/signs/alphabet/README.md
The matcher currently supports static letters:
A-IandK-Y(motion lettersJandZare excluded in v1)
The sign recognizer now supports multi-sample fine-tuning per letter.
- In Sign mode, perform the target sign and click
Use This Gesture. - Each capture is appended as a new sample for that letter.
- Samples are saved to
assets/signs/alphabet/custom_templates.jsonand reused next run. - During matching, the app uses nearest-neighbor averaging across top samples for stronger stability.
Recommended workflow:
- Capture 5-15 samples per difficult letter in different wrist angles.
- Tune confidence with
[ / ]. - Tune temporal stability with
- / +. - Re-test in Practice mode and add more samples for commonly confused letters.
Useful CLI options for sign tuning:
python hand_skeleton_component.py \
--sign-hold-frames 10 \
--sign-confidence-threshold 5.5 \
--sign-max-custom-samples 30For each detected hand (Left Hand / Right Hand), the app increments counters for:
Index-ThumbpinchMiddle-ThumbpinchRing-ThumbpinchPinky-Thumbpinch
Each counter increments once per pinch event (it waits for release before counting the next pinch).
Each hand has its own knob state and counters.
- Activate knob mode by pinching
thumb + index + middleon that hand. - While pinched, rotate your hand/fingers to generate:
CW(clockwise) stepsCCW(counter-clockwise) steps
- The overlay shows, per hand:
ValueCWCCW- current state (
Hold,CW,CCW,Idle)
- Use bright, even lighting.
- Keep your hands fully inside the camera frame.
- Avoid motion blur (move slightly slower if needed).
- If hands are lost during fast movement, keep
--disable-recovery-full-resoff (default); recovery mode re-runs inference at full resolution when tracking drops.
If you see camera access has been denied or not authorized to capture video:
tccutil reset Camera com.apple.TerminalThen:
- Open System Settings -> Privacy & Security -> Camera
- Enable camera access for your terminal app (Terminal, iTerm, Warp, etc.)
- Quit and reopen the terminal app
You can probe available camera indices:
python hand_skeleton_component.py --list-cameras --camera-backend avfoundationThen run with the detected index:
python hand_skeleton_component.py --camera 0 --camera-backend avfoundation