04 · COMPUTER VISION · REAL-TIME · HCI
EmotionGesture AI
Repository codename · GestureSense AI
A real-time multi-modal vision suite running off a single webcam: eight hand gestures, finger counting from zero to ten across two hands, and seven-class emotion detection — all rendered live without the flicker that usually ruins these demos.
01 — THE PROBLEM
Real-time computer vision demos usually fail in the same two places, and neither one is about model accuracy.
First, flicker. Classifying each frame independently means a single bad frame flips the label, so the output jitters between answers even when the user's hand is perfectly still.
Second, stalling. Emotion models are far slower than hand tracking. Running everything in one loop means the whole pipeline runs at the speed of its slowest component, and the frame rate collapses.
The interesting work here was structural rather than a question of model selection — getting several components of very different speeds to share one camera feed and still feel instant.
02 — ARCHITECTURE
┌─────────────────────┐
Webcam ──▶ VideoStream │ (background thread) │
└─────────┬──────────┘
│ latest frame
┌─────────▼──────────┐
│ GestureSensePipeline │
└─────────┬──────────┘
┌─────────┬─────────┼─────────┬─────────┐
▼ ▼ ▼ ▼ ▼
Hand Finger Gesture Emotion FPS
tracking count engine worker meter
1€ filter geometry stabiliser threaded sliding
└─────────┴─────────┴─────────┴─────────┘
│ FrameResult (typed)
Overlay / Streamlit dashboard03 — BUILD LOG
The decisions that shaped the system, and why each one was made.
-
Capture moved to its own thread
VideoStreamreads the camera on a background thread and the pipeline always pulls the most recent frame. Processing can never block capture, and a slow frame is dropped rather than queued into steadily growing latency. -
A temporal stabiliser to kill flicker
Gesture classification is smoothed across frames before it is displayed, so a single misread frame cannot flip the visible label. This is the difference between a demo that looks broken and one that looks solid.
-
A 1€ filter per hand
Landmark coordinates are smoothed with a per-hand 1€ filter, chosen specifically because it suppresses jitter while a hand is still without adding perceptible lag when it moves quickly — the failure mode of a simple moving average.
-
Emotion detection on its own worker
The slowest component runs threaded and off the critical path, so hand tracking keeps its frame rate regardless. DeepFace is the default backend; FER is supported behind an
--emotion ferflag but left opt-in, since its PyPI packaging pins a brokenffmpeg==1.4. -
One typed result object
Every component writes into a single typed
FrameResult, which the OpenCV overlay and the Streamlit dashboard both consume. Adding a new output surface means reading one struct, not rewiring the pipeline. -
Built like a product, not a notebook
SOLID module boundaries, typed configuration, structured logging and a pytest suite — plus a documented upgrade path from the current rule-based gesture engine to a trained YOLOv8 model, so the rules are a deliberate starting point rather than a ceiling.
04 — WALKTHROUGH
Running it end to end.
-
Install
pip install -r requirements.txt -
Run the dashboard
The Streamlit control panel shows FPS, current gesture, finger count, emotion and confidence breakdown, with live camera, hand and face status indicators. Camera selection and backend switching live in the sidebar.
streamlit run app.py -
Or run the annotated preview
The OpenCV window draws landmarks, bounding boxes and labels straight onto the video feed.
python main.py -
Switch the emotion backend
Optional — requires installing
fermanually first.python main.py --emotion fer -
Run the tests
pytest
05 — STACK