Projects

Project Details

sEMG Gesture Decoder 2025

Live causal streaming demo showing filtered EMG channels, predicted gesture, latency, and running accuracy

Project Overview

A real-time hand gesture classifier that decodes surface electromyography (sEMG) signals as they arrive, predicting the intended gesture from muscle activity with roughly 1 ms of processing latency per window. The system is built around a causal streaming pipeline, so predictions are produced from only the samples seen so far — the constraint that matters for real-world prosthetic and human–computer interface control.

It trains and evaluates on the public Ninapro DB2 dataset, recorded from a 12-channel Delsys Trigno sensor array sampled at 2 kHz. Models are trained per subject (within-subject / personalized), reflecting how a wearable would be calibrated to an individual user.


Processing Pipeline

Raw signal to prediction

  • Ingestion:

    Loads per-subject Ninapro DB2 .mat files and organizes the 12-channel, 2 kHz EMG stream with its gesture labels.
  • Filtering:

    Applies a causal IIR filter that maintains state across windows (scipy sosfilt / lfilter), deliberately avoiding non-causal offline methods like filtfilt that peek at future samples.
  • Windowing & features:

    Segments the stream into overlapping windows (200 ms window, 50 ms step) and caches the extracted features for fast, repeatable training runs.
  • Classification:

    Feeds features to a trained SVM (RBF kernel) to emit a gesture prediction per window, with per-window latency benchmarked against a 50 ms real-time budget.

Key Features

Real-Time Design

  • Causal streaming, no future-sample leakage
  • Stateful filtering across windows
  • ~1 ms/window, well under a 50 ms budget
  • Per-window latency benchmarking

Engineering

  • Pure-function core, separate from I/O scripts
  • Cached windows/features for fast reruns
  • pytest coverage on signal processing
  • Live visualization of stream + predictions

Technical Details

Dataset

Ninapro DB2 — surface EMG from a 12-channel Delsys Trigno array at 2 kHz, covering a broad set of hand and wrist gestures. The dataset is not redistributed; the per-subject .mat files are downloaded independently.

Causal vs. Offline Filtering

A central design point is the distinction between non-causal offline processing (filtfilt, which uses future samples for zero-phase filtering) and causal streaming (sosfilt + lfilter with maintained state). Only the causal path is valid for live control, and the pipeline is built to honor that constraint.

Model

Within-subject SVM with an RBF kernel serves as the demonstrated classifier, alongside classical and CNN baselines, trained on cached window features.


Project Information

Type

Signal Processing / Machine Learning

Domain

Real-Time Biosignal Decoding

Stack

Python, NumPy, SciPy, scikit-learn, pytest

Technologies

Surface EMG, Causal Streaming, Digital Filtering, SVM / CNN Classification

Links
GitHub Repository

Results

Latency

Per-window processing runs at roughly 1 ms, comfortably inside the 50 ms real-time budget, leaving ample headroom for live gesture control.

Live Demo

A recorded demo streams filtered EMG channels while overlaying the predicted gesture, the true label, the current processing latency, and a running accuracy counter — validating the causal pipeline end to end on a personalized subject model.