Author: Lekan Ogunmolu
Nicely computes the Vandermonde matrix, Savitzky-Golay differentiation filters, and smoothing coefficients for any sequential signal. It is a textbook implementation of the Savitzky-Golay Filter. Initial testing of this code was on a Ubuntu 14.04.02 Trusty OS running Linux 4.4 but will work on any other Linux/Windows/Mac OS machine with little effort.
Below are examples of how the filter smoothes out a noisy depth map data from the kinect time-of-flight sensor:
- Eigen3 Library for the linear algebra of the matrices, vectors and related algorithms. You can download the 3.2.5 library which I used from here and follow the
READMEinstructions after unpacking the tarball to install.
-
./savgolOptions
-
-h or --help: print out the help menu.
-
Example: Compute the savitzky-golay filter coefficients with frame size,
F = 5and polynomial order 3 (these are the default parameters of the filter) for linearly spaced data points betweenx_min = 900andx_max = 980. A typical cmd line usage:./savgoal 9 5whereF = 9andk = 5. -
To pass in your arbitrary data points between a value
x_minandx_max, run this way in order: ./savgoalFkx_minx_max.
The filtered values are returned to the console. Note that the Frame size should ideally be odd.
-
-
MatrixXi vander(const int F);- Computes the Vandermonde matrix and the polynomial of basis vectors; it flips the vector column-wise, left to right.
-
MatrixXf B = MatrixXf sgdiff(int k, double F)- Designs a Savitzky-Golay FIR smoothing filter, B, with polynomial order k and frame size F of convolution coefficients. The polynomial order, k, must be less than the frame size F, and F must be odd.
-
savgolfilt(x, x_on, k, F)- Computes the smoothed values of the signal x, whose tansient on is
x_oninitialized with size F.
- Computes the smoothed values of the signal x, whose tansient on is
-
Note In calculating the transient off,
x_offwill be the last(F-1)xvalues, wherex's are the data sequence we want to filter.If you are smoothing data offline, then this code will work seamlessly. Just load your data in themain()function where, for an example, I have used linearly spaced values between900and980at a frame5size for my steady state values.
Note, if you are smoothing data in real time, you need to find a way to let your compiler pick the last F-length samples from your data in order to compute your transient off, i.e., x_off. You could have the program wait for x_milliseconds after stopping your code before you pick the transient off, for example.
There is a CMakeLists.txt file in the project root folder. From the project root directory:
- Create a build directory:
mkdir build && cd build - Compile the
cppcode:cmake ../ - Build your executable:
make - Run the executable:
./savgol
If you have used Savitzky-Golay in your work, please cite it.
@misc{Savitzky-Golay,
author = {Ogunmolu, Olalekan},
title = {{Savitzky-Golay Filter in C++}},
year = {2015},
howpublished = {\url{https://github.com/lakehanne/Savitzky-Golay}},
note = {Accessed August 15, 2015}
}If you have issues running the files, please use the issues tab to open a bug. I will generally respond within a 24-hour period.
- Added citation to README (August 14, 2015)
- Added examples to
int main()function (August 15, 2015) - Modified frame size and polynomial order to be reconfigurable at run time (July 1, 2016)
Add a plotter to plot the filtered values on a gtk chart?
INTRODUCTION TO SIGNAL PROCESSING
Sophocles J. Orfanidis, Prentice Hall, 2010
Chapter 8; Section 8.3.5

