"I stared at the raw trace for an hour looking for the gesture. Then someone rectified it, smoothed it, and the whole intention was sitting there in plain sight."
An Enlightened AI Agent
Prerequisites
This section assumes the surface-versus-intramuscular distinction and the interference-pattern picture of the raw signal from Section 32.1: you should know that a surface electrode sums the electrical activity of many motor units into a noise-like, roughly zero-mean waveform. It leans directly on the power-spectral-density and time-frequency machinery of Chapter 7, the filtering vocabulary of Chapter 6, and the sampling and windowing ideas of Chapter 3. How these features drive a classifier or a prosthesis is the job of Section 32.3; the fatigue story that the spectrum tells is developed in Section 32.4.
The Big Picture
Raw surface EMG is close to useless as a direct input. It is an oscillating, sign-flipping interference pattern whose instantaneous value carries almost no meaning: the same muscle contraction produces a positive spike one millisecond and a negative one the next. What matters is not the wiggle but two summaries of it. The amplitude envelope answers "how hard is this muscle working right now," a slow, positive, force-like signal you can read at a glance. The spectrum answers "how fast are the underlying muscle fibers firing and conducting," a shape that quietly slides toward lower frequencies as a muscle tires. Nearly every EMG system ever deployed, from a 1970s myoelectric hand to a modern gesture wristband, runs on some combination of these two ideas. This section is about computing them well, understanding what each one physically represents, and packing them into a feature vector a model can use.
From interference pattern to envelope: the amplitude features
The raw signal \(x[n]\) swings around zero, so averaging it directly gives roughly nothing. Every amplitude feature therefore starts by discarding the sign. The two canonical choices operate on a short analysis window of \(N\) samples. The mean absolute value (MAV) rectifies and averages,
$$\text{MAV} = \frac{1}{N}\sum_{n=1}^{N} |x[n]|,$$while the root mean square squares, averages, and takes the root,
$$\text{RMS} = \sqrt{\frac{1}{N}\sum_{n=1}^{N} x[n]^2}.$$Both track contraction intensity, and both are proxies for the number and firing rate of active motor units, which is the quantity a controller actually cares about. RMS has a cleaner physical reading: because the signal is roughly zero-mean, RMS equals the standard deviation, so \(\text{RMS}^2\) is the signal power, directly proportional to the energy the muscle is expending. MAV is a hair cheaper to compute and slightly more robust to the occasional large-amplitude spike, which is why the classic Hudgins time-domain feature set built its gesture classifiers on MAV rather than RMS.
Sliding either statistic across the stream, or equivalently rectifying the signal and passing it through a low-pass filter, produces the linear envelope: the smooth, positive, force-shaped curve in every clinical gait lab. The cutoff of that low-pass filter is a real design decision. Too high and the envelope stays jittery; too low and it lags the muscle, smearing a crisp onset into a slow ramp. For dynamic movement a cutoff in the 3 to 10 Hz range is typical, chosen against the bandwidth of the motion you are trying to follow, exactly the tradeoff framed in Chapter 6.
Amplitude alone throws away the shape of the waveform, so the Hudgins set adds three cheap complexity measures. Waveform length sums the absolute sample-to-sample changes, \(\text{WL}=\sum |x[n]-x[n-1]|\), a single number that rises with both amplitude and frequency content. Zero crossings and slope sign changes count how often the signal flips sign or reverses direction, crude but effective stand-ins for spectral content that cost almost nothing to compute. Together these four (MAV, WL, ZC, SSC) remain a startlingly strong baseline for gesture recognition on cheap hardware, which is why they still appear in embedded systems decades after their introduction.
Key Insight
Amplitude features and spectral features answer orthogonal questions, and that orthogonality is the whole reason to compute both. Envelope amplitude tracks how much drive the muscle is producing and rises with force. The spectral summary tracks how the muscle fibers are firing and conducting, and it can slide downward even while force is held perfectly constant. During a sustained hold your force may not move a millimeter, yet the median frequency creeps lower every second as the muscle fatigues. A feature vector with only amplitude is blind to that; a feature vector with only spectrum is blind to effort. Real EMG systems carry both because each covers the other's blind spot.
The spectrum and its two summary numbers
Estimate the power spectral density \(P(f)\) of a window (Welch's method from Chapter 7 is the standard tool) and the raw shape is instantly recognizable: surface EMG power lives roughly between 20 and 450 Hz, humped in the 50 to 150 Hz region, with essentially nothing usable below 20 Hz where motion and baseline wander dominate. Nobody feeds the full spectrum to a classifier, though. It is high-dimensional and noisy, so we collapse it to two scalars that have survived fifty years of use.
The mean frequency (MNF) is the power-weighted average frequency,
$$\text{MNF} = \frac{\sum_{j} f_j\, P(f_j)}{\sum_{j} P(f_j)},$$the "center of mass" of the spectrum. The median frequency (MDF) is the frequency \(f_{\text{med}}\) that splits the total power in half,
$$\sum_{f_j \le f_{\text{med}}} P(f_j) = \tfrac{1}{2}\sum_{j} P(f_j).$$Why do these two numbers matter so much? Because the spectrum's position on the frequency axis is set by the conduction velocity of the muscle fibers, and conduction velocity falls as a muscle fatigues: metabolites accumulate, the action potentials propagate more slowly, and the whole spectrum shifts toward lower frequencies. A steadily declining MNF or MDF under a constant load is the single most established quantitative fatigue marker in the literature. We will not develop the fatigue estimator here (that is Section 32.4), but the reason these particular features exist is worth stating now: they were engineered to make that downward slide measurable. MDF is generally preferred as a fatigue index because it is less sensitive to the high-frequency noise and additive spikes that can drag MNF around.
import numpy as np
from scipy.signal import welch
def emg_features(x, fs):
"""Amplitude + spectral summary for one sEMG analysis window."""
x = np.asarray(x, dtype=float)
x = x - x.mean() # remove any DC offset
mav = np.mean(np.abs(x)) # contraction intensity
rms = np.sqrt(np.mean(x ** 2)) # signal power (= std)
wl = np.sum(np.abs(np.diff(x))) # waveform length
f, P = welch(x, fs=fs, nperseg=min(256, len(x))) # power spectral density
band = f >= 20 # ignore sub-20 Hz motion
f, P = f[band], P[band]
mnf = np.sum(f * P) / np.sum(P) # mean frequency
csum = np.cumsum(P)
mdf = f[np.searchsorted(csum, csum[-1] / 2)] # median frequency
return dict(MAV=mav, RMS=rms, WL=wl, MNF=mnf, MDF=mdf)
fs = 1000
t = np.arange(0, 0.25, 1 / fs) # a 250 ms window
rng = np.random.default_rng(0)
strong = 4.0 * rng.standard_normal(t.size) # hard contraction
print({k: round(v, 2) for k, v in emg_features(strong, fs).items()})
Listing 32.2 is the honest arithmetic behind almost every EMG feature paper. In production you would compute these per channel across an electrode array, then hand the stacked vector to the classifier of Section 32.3 or the dimensionality-reduction stage of Chapter 8.
The Right Tool
Rolling your own bank of time-domain and frequency-domain EMG features, with correct windowing, per-channel handling, and the dozen-odd variants (Willison amplitude, slope sign changes, spectral moments), is a few hundred lines and a magnet for off-by-one and normalization bugs. Purpose-built libraries such as emgfeatures or a configured tsfresh extractor replace that with a call or two:
import numpy as np
from tsfresh.feature_extraction import feature_calculators as fc
x = np.abs(x) # rectify once
feats = {"mav": np.mean(x),
"wl": np.sum(np.abs(np.diff(x))),
"abs_energy": fc.abs_energy(x),
"n_peaks": fc.number_peaks(x, n=3)}
tsfresh extractor collapses roughly 200 lines of hand-written feature code into a short call and returns a labeled feature frame ready for a model. The library supplies the features; deciding which ones survive on your device and subjects, and pruning the redundant ones, is still yours to do.The library removes the plumbing, not the judgment. A feature set tuned on one electrode montage and one set of subjects will not transfer unchanged, the cross-session and cross-subject problem taken up in Section 32.5, so treat the extracted vector as a starting point and validate on held-out subjects.
Non-stationarity: when one spectrum per window is a lie
MNF and MDF quietly assume the signal is stationary within the window, that a single spectrum describes the whole slice. During an isometric hold that is roughly true. During a real reach, grasp, or step it is emphatically false: the muscle is ramping, the limb geometry is changing, and the spectrum is a moving target. Averaging it into one number blurs exactly the transitions a gesture recognizer most wants to see.
The fix is time-frequency analysis from Chapter 7. A short-time Fourier transform recomputes the spectrum on many short overlapping windows, trading frequency resolution for time resolution under the usual uncertainty limit. Wavelet transforms go further, giving fine time resolution at high frequencies (good for catching the sharp onset of a contraction) and fine frequency resolution at low ones, which is why wavelet features are popular for classifying dynamic gestures. The practical guidance is simple: for a static hold, one spectrum per window is fine and cheap; for dynamic movement, either shrink the window until the signal is locally stationary or move to an explicitly time-frequency representation.
In Practice: a prosthetic wrist reads a 200-millisecond intention
A transradial (below-elbow) myoelectric prosthesis carries eight surface electrodes around the forearm. To feel responsive rather than sluggish, the controller must decide the intended grasp within roughly a quarter second of the muscle firing, because a control-loop latency much above 300 milliseconds is perceived as lag and users reject the device. The pipeline therefore runs on a 200 millisecond sliding window advanced every 50 milliseconds. On each window and each of the eight channels it computes the cheap Hudgins amplitude and shape features (MAV, waveform length, zero crossings, slope sign changes) rather than a full spectral estimate, because a Welch PSD over 200 milliseconds is both noisy and too slow for the loop. The resulting 32-number vector feeds a small classifier that outputs one of a handful of grips. The engineering lesson is that feature choice is dictated by the latency budget: the elegant spectral summaries lose to the crude time-domain ones here purely because they cannot be computed accurately and fast enough inside the window the user will tolerate. That real-time budget is the subject of Section 32.7.
Assembling the feature vector
A working extractor is defined by four choices, and getting them right matters more than adding exotic features. Window length trades statistical stability against latency: longer windows give steadier estimates but slower response, and 150 to 250 milliseconds is the well-worn sweet spot for control. Overlap (advancing the window by less than its length) raises the decision rate without enlarging each window. Per-channel stacking concatenates every feature across every electrode, so an eight-channel array with five features yields a forty-dimensional vector. Normalization ties it all together: raw amplitudes depend on electrode placement, skin impedance, and the day, so features are routinely normalized to a reference contraction (often a maximum voluntary contraction) to become comparable across sessions. Skipping that normalization is a leading cause of models that shine in the lab and collapse on the next day's donning, the failure mode Section 32.5 is built to address.
Research Frontier
The hand-designed features in this section are being challenged by learned ones. Deep models fed the raw or lightly rectified multichannel signal, one-dimensional convolutional and temporal networks from Chapter 14, discover their own frequency-selective filters and often match or beat MAV-and-MDF pipelines on large gesture corpora such as the Ninapro and CapgMyo databases. The most visible push is Meta's CTRL-labs surface-EMG wristband, which decodes fine finger and typing intent from a dense electrode array using end-to-end learned representations rather than explicit spectral summaries. The instructive result is that the learned filters frequently rediscover envelope-like and band-power-like structure on their own, which is both a validation of these classical features and a signal that they encode much, though not all, of what the raw stream contains. Self-supervised pretraining on unlabeled EMG, in the spirit of Chapter 17, is the current frontier for cutting the per-user calibration burden.
Exercise
Take a sustained isometric contraction record (or synthesize one as filtered Gaussian noise whose spectral center you deliberately slide downward over time). Split it into consecutive one-second windows and compute RMS and median frequency for each. Plot both against time and describe what you see: which feature stays flat and which one drifts, and explain in one sentence why that pattern is the textbook signature of muscle fatigue rather than of a change in effort.
Self-Check
1. Why does averaging the raw EMG signal directly give a near-useless number, and what single operation fixes it before you compute MAV or RMS?
2. A muscle holds a constant force for thirty seconds. Predict what happens to its RMS and to its median frequency over that interval, and state the physiological cause of the frequency change.
3. You must classify a dynamic grasp inside a 200 millisecond window. Give one concrete reason a full Welch spectral estimate is a poor choice here and name a feature you would compute instead.
What's Next
In Section 32.3, we take the feature vectors built here and turn them into decisions: mapping multichannel EMG features onto discrete gestures and continuous control signals, the pattern-recognition and regression machinery that lets a forearm's electrical chatter drive a robotic hand.