CoolFace
Apppublic

Tanishq14/gesture-recognition

sourceHugging Facemitupdated 4mo agoView on Hugging Face
0likes
App README

๐ŸคŸ Gesture to Language โ€” Real-Time Hand Gesture Recognition System

Convert hand gestures to natural language sentences in real time using deep learning, MediaPipe, and LLM post-processing.

Live Demo โ†’ [huggingface.co/spaces/Tanishq14/gesture-recognition](https://huggingface.co/spaces/Tanishq14/gesture-recognition)


Demo

## Demo Video Click to Open Video

![Project Demo](demo.mp4)*


Overview

A complete end-to-end real-time hand gesture recognition system built for accessibility. The user signs gestures in front of a webcam, the system recognizes them as words, and an LLM converts the word sequence into a grammatically correct spoken sentence.

The system runs at real-time speed with zero-lag landmark overlay โ€” MediaPipe runs entirely in the browser, while ONNX Runtime handles model inference on the server without any TensorFlow dependency.


Architecture

Browser (MediaPipe JS)
        โ”‚
        โ”‚  63 normalized landmark floats (not raw frames)
        โ”‚
        โ–ผ
FastAPI WebSocket Server
        โ”‚
        โ”œโ”€โ”€ Rolling 20-frame buffer
        โ”œโ”€โ”€ 1D CNN (ONNX Runtime) inference
        โ”œโ”€โ”€ Stability filter (3 consecutive same predictions)
        โ”œโ”€โ”€ Cooldown logic (1 second between words)
        โ”‚
        โ–ผ
Word Buffer โ†’ Groq LLaMA 3.1 (with conversation history)
        โ”‚
        โ–ผ
Sentence + Voice Output (Web Speech API)

Tech Stack

LayerTechnologyWhy
Gesture detectionMediaPipe Hands (JS)Runs in browser โ€” zero network lag for landmarks
Model formatONNX RuntimeNo TensorFlow at runtime โ€” faster, lighter deployment
BackendFastAPI + WebSocketPersistent connection handles 15fps landmark stream
LLMGroq LLaMA 3.1 8BFree tier, ~300ms inference, conversation-aware
VoiceWeb Speech APIBuilt into browser โ€” no external TTS service needed
DeploymentHugging Face SpacesFree forever, no cold starts, ML-native platform

Model Comparison

Three architectures were trained and benchmarked on the same self-collected dataset:

ModelVal AccuracyInference TimeParametersSelected
1D CNN97.9%~12ms~45Kโœ…
LSTM98.2%~28ms~180KโŒ
GRU97.4%~22ms~135KโŒ

Why CNN was selected over LSTM despite lower accuracy: LSTM had marginally higher validation accuracy but CNN had 4x fewer parameters and 2.3x faster inference. For a real-time system running at 15fps, inference latency matters more than a sub-1% accuracy difference. CNN also converged in fewer epochs with less overfitting.


Gesture Vocabulary (31 gestures)

CategoryGestures
GreetingsHELLO, YES, NO, PLEASE, SORRY, OK, WAIT, THANKS
CommandsSTOP, START, NEXT, PREVIOUS, SELECT, CANCEL, HELP
PronounsME, YOU
ActivitiesCOME, GO, WORK, EAT, SLEEP, DRINK
EmotionsHAPPY, SAD, GOOD, BAD
NeedsWATER, FOOD, HOME, TIME
ControlSEND, CLEAR, DELETE

Key Engineering Decisions

MediaPipe moved to browser Originally MediaPipe ran server-side. Every frame was encoded as JPEG, sent over WebSocket, decoded, and processed. This caused visible lag. Moving MediaPipe to JavaScript means landmarks are drawn instantly with zero network delay. The server now receives 63 pre-normalized floats instead of full JPEG frames โ€” drastically reducing bandwidth and server load.

ONNX Runtime instead of TensorFlow Model was trained in TensorFlow on Google Colab and exported via tf2onnx. The server runs inference using ONNX Runtime which has no TensorFlow dependency, installs in seconds, and runs faster on CPU.

Stability filter for flickering Similar gestures (e.g. HELLO and STOP) produced alternating predictions. A stability buffer requires the model to predict the same word 3 consecutive times before confirming it โ€” eliminating false positives without affecting responsiveness.

Landmark normalization must match training All landmarks are normalized relative to the wrist (landmark 0) and scaled by the distance to landmark 9 (middle finger MCP). This makes predictions invariant to hand size and camera distance. The exact same normalization function is used in both training and inference โ€” any deviation breaks the model.

Frame flip matching Training data was collected with cv2.flip(frame, 1). MediaPipe JS gives unflipped coordinates. The JavaScript normalization function mirrors x-coordinates (x = 1 - x) before normalizing to match the training coordinate space exactly.


Project Structure

gesture_recognition/
โ”œโ”€โ”€ main.py           โ€” FastAPI routes, WebSocket, Groq endpoint
โ”œโ”€โ”€ config.py         โ€” all constants (sequence length, thresholds)
โ”œโ”€โ”€ landmarks.py      โ€” landmark normalization (must match training)
โ”œโ”€โ”€ model_utils.py    โ€” ONNX model loading and inference
โ”œโ”€โ”€ session.py        โ€” per-connection state (frame buffer, word buffer)
โ”œโ”€โ”€ index.html        โ€” frontend (MediaPipe JS, canvas, WebSocket client)
โ”œโ”€โ”€ Dockerfile        โ€” container config for HF Spaces deployment
โ”œโ”€โ”€ requirements.txt  โ€” server dependencies only (no TensorFlow)
โ”œโ”€โ”€ models/
โ”‚   โ”œโ”€โ”€ cnn_model.onnx
โ”‚   โ””โ”€โ”€ label_encoder.pkl
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ collect_data.py   โ€” data collection script
    โ””โ”€โ”€ inference.py      โ€” local inference script (development only)

Running Locally

1. Clone the repository

bash
git clone https://github.com/Tanishq14/gesture-recognition.git
cd gesture-recognition

2. Install dependencies

bash
pip install -r requirements.txt

3. Set up environment variables

Create a .env file in the project root:

GROQ_API_KEY=your_groq_api_key_here

Get a free Groq API key at console.groq.com

4. Start the server

bash
uvicorn main:app --host 0.0.0.0 --port 8000 --reload

5. Open the app

Visit http://localhost:8000 in your browser. Allow webcam access when prompted.


How It Works

  1. 1.Browser captures webcam feed and runs MediaPipe Hands locally
  2. 2.On detecting the right hand, landmarks are normalized using extractLandmarks() โ€” 63 floats
  3. 3.Normalized landmarks are sent to the FastAPI server over WebSocket at 15fps
  4. 4.Server appends landmarks to a rolling 20-frame buffer (deque)
  5. 5.When buffer is full, ONNX Runtime runs inference โ€” returns predicted gesture and confidence
  6. 6.Stability filter checks if the same gesture was predicted 3 times consecutively
  7. 7.If stable and cooldown has passed (1 second), the word is added to the word buffer
  8. 8.User clicks SEND โ€” word buffer is sent to Groq LLaMA with conversation history as context
  9. 9.Groq returns a grammatically correct sentence
  10. 10.Sentence is displayed and read aloud via Web Speech API

Limitations and Future Work

  • โ€”Right hand only โ€” left hand support requires mirroring x-coordinates during training
  • โ€”31 gesture vocabulary โ€” expanding requires new data collection and retraining
  • โ€”Transition frames between gestures can occasionally cause mispredictions
  • โ€”Model trained on single user โ€” performance may vary across different hand sizes and skin tones

Dependencies

fastapi          โ€” async web framework
uvicorn          โ€” ASGI server with WebSocket support
onnxruntime      โ€” model inference without TensorFlow
opencv-python-headless โ€” frame processing (server side)
groq             โ€” LLaMA 3.1 API client
python-dotenv    โ€” environment variable management
scikit-learn     โ€” label encoder (saved with sklearn)

Author

Tanishq Gupta BTech Student | AI/ML Enthusiast

GitHub ยท Hugging Face


Built as a complete end-to-end ML engineering project โ€” from data collection and model training to WebSocket backend and cloud deployment. Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference