Smoothing filter
Savitzky–Golay
Smooths without flattening the peaks
Instead of averaging a sliding window, it fits a curve through it. An average pulls the top of a peak down; a fitted curve follows it — which matters when a range of motion is read off exactly those peaks.
- Peak flattening
- 0.00°
- Phase lag
- 0 frames
- Noise remaining
- 1.29° of 2.34°
- Frame rate needed
- No
Measured on our own test signals at 24fps: a clean sine wave, that wave with ±4° of random noise, and that wave with one frame knocked 108° out of place. These describe how the filter behaves — they are not a validation of markerless measurement against marker-based capture.
How it works
For every frame, take the frames around it, fit a quadratic through them by least squares, and use the value of that curve at the middle. Repeat for the next frame.
The difference from an average is the shape being fitted. An average assumes the window is flat, so where the signal is curved — at a peak, which is the most curved part of it — the average sits below the true value and the peak is clipped. A quadratic can be curved, so it sits on the peak instead.
Originally built for chemists reading peaks off noisy spectra. The problem is the same one: the height of the peak is the measurement.
Reach for it when
- The minimum and maximum are what you are reporting, and you cannot afford to lose any of them.
- You want more smoothing than a Butterworth at the same window without paying for it in flattened extremes.
- The measurement has no frame rate recorded — this one counts in frames, so it always works.
What it costs
It is less predictable in the frequency domain than a Butterworth: you can say what it does to a peak much more easily than you can say what it does at 8 Hz. And like any window filter, it smears a spike rather than deleting it.
What we actually run
So the page and the code say the same thing.
- Quadratic fit over a centred window. For smoothing — as opposed to derivatives — a quadratic and a cubic give identical results, so the quadratic is the cheaper way to say the same thing.
- The fit is solved directly for each frame rather than applied as tabulated coefficients, which also avoids the errors that were found in the 1964 tables.
- At the start and end of a run the window is simply shorter, and the fit is still read at the frame's own position. That is the correct asymmetric treatment rather than an edge fudge.
- Windows scale with the frame rate — around 0.10s, 0.20s and 0.38s at the three strengths — so a setting means the same thing on a 24fps clip and a 60fps one.
The research behind it
Savitzky, A., & Golay, M. J. E. (1964). Smoothing and differentiation of data by simplified least squares procedures. Analytical Chemistry, 36(8), 1627–1639.
The original method: fit a low-order polynomial through a sliding window, which smooths without pulling the tops off peaks.
doi:10.1021/ac60214a047
Steinier, J., Termonia, Y., & Deltour, J. (1972). Smoothing and differentiation of data by simplified least square procedure. Analytical Chemistry, 44(11), 1906–1909.
Corrects errors in the 1964 coefficient tables. We solve the fit directly rather than using tabulated coefficients, which sidesteps the issue.
doi:10.1021/ac60319a045
Schafer, R. W. (2011). What is a Savitzky-Golay filter?. IEEE Signal Processing Magazine, 28(4), 111–117.
The clearest modern account, including the frequency response and why the filter behaves as it does at the ends of a signal.
doi:10.1109/MSP.2011.941097