# Noise Filtering Using 1€ Filter

This article explores the 1€ Filter (1e filter, 1 euro filter, One Euro Filter), a simple, but powerful algorithm for filtering real-time noisy signals. The article focuses on the implementation of the algorithm in practice, and it covers the mathematical basis, a pseudocode implementation and simple pure Python implementation of the algorithm. In order to understand why and how the filter works, I recommend reading the original article (1).

## The 1€ Filter

The 1€ Filter is a low pass filter for filtering noisy signals in real time. It’s also a simple filter with only two configurable parameters. The signal at time $$T_i$$ is denoted as a value $$X_i$$ and the filtered signal as value $$\hat{X}_i$$. The filter is implemented using exponential smoothing $\hat{X}_1 = X_1 \\ \hat{X}_i = α X_i + (1-α) \hat{X}_{i-1}, i≥2 \tag{exponential-smoothing} \label{exponential-smoothing}$ where the smoothing factor $$α∈[0, 1]$$, instead of being a constant, is adaptive, i.e. dynamically computed using information about the rate of change (speed) of the signal. This aims to balance the jitter versus lag trade-off since people are more sensitive to jitter at low speeds and more sensitive to lag at high speeds. The smoothing factor is defined as $α = \frac{1}{1 + \dfrac{τ}{T_e}}, \tag{smoothing-factor} \label{smoothing-factor}$ where $$T_e$$ is the sampling period computed from the time difference between the samples $T_e=T_i-T_{i-1} \tag{sampling-period}$ and $$τ$$ is time constant computed using the cutoff frequency $τ = \frac{1}{2πf_C}. \tag{time-constant}$

The cutoff frequency $$f_C$$ which is designed to increase linearly as the rate of change, aka speed, increases $f_C=f_{C_{min}} + β|\hat{\dot{X}}_i| \tag{cutoff-frequency}$ where $$f_{C_{min}}>0$$ is the minimum cutoff frequency, $$β>0$$ is the speed coefficient and $$\hat{\dot{X}}_i$$ is the filtered rate of change. The rate of change $$\hat{X}_i$$ is defined as the discrete derivative of the signal $\dot{X}_1 = 0 \\ \dot{X}_i = \frac{X_i-\hat{X}_{i-1}}{T_e}, i≥2, \tag{derivative}$ which is then filtered using $$\eqref{exponential-smoothing}$$ with a constant cutoff frequency $$f_{C_d},$$ by default $$f_{C_d}=1$$.

## The Algorithm

The One Euro Filter algorithm as pseudocode. The precise implementation of the One-Euro-filter will depend on the programming language and paradigm in question. This particular algorithm is written in a functional style.

$$\operatorname{Smoothing-Factor}(f_C, T_e)$$

1. $$r=2π⋅f_c⋅T_e$$
2. return $$\dfrac{r}{r+1}$$

$$\operatorname{Exponential-Smoothing}(α, X_i, \hat{X}_{i-1})$$

1. return $$α X_i + (1-α) \hat{X}_{i-1}$$

$$\operatorname{One-Euro-Filter}(T_i,X_i,T_{i-1},\hat{X}_{i-1},\hat{\dot{X}}_{i-1},f_C,β,f_{C_d})$$ for $$i≥2$$

1. $$T_e=T_i-T_{i-1}$$
2. $$α_d=\operatorname{Smoothing-Factor}(T_e, f_{C_d})$$
3. $$\dot{X}_i = \dfrac{X_i-\hat{X}_{i-1}}{T_e}$$
4. $$\hat{\dot{X}}_i=\operatorname{Exponential-Smoothing}(α_d, \dot{X}_i, \hat{\dot{X}}_{i-1})$$
5. $$f_C=f_{C_{min}} + β|\hat{\dot{X}}_i|$$
6. $$α=\operatorname{Smoothing-Factor}(f_C, T_e)$$
7. $$\hat{X}_i=\operatorname{Exponential-Smoothing}(α, X_i, \hat{X}_{i-1})$$
8. return $$T_i,\hat{X}_i,\hat{\dot{X}}_i$$

## Tuning the Filter

There are two configurable parameters in the model, the minimum cutoff frequency $$f_{C_{min}}$$ and the speed coefficient $$β$$. Decreasing minimum cutoff frequency will decrease slow speed jitter. Increasing speed coefficient will decrease speed lag.

## Python Implementation

The following object-oriented Python implementation is also available in OneEuroFilter GitHub repository. The object-oriented approach stores the previous values inside the object instead of giving them explicitly as a return value as functional implementation would. It should be relatively simple to implement this algorithm in other languages.

import math

def smoothing_factor(t_e, cutoff):
r = 2 * math.pi * cutoff * t_e
return r / (r + 1)

def exponential_smoothing(a, x, x_prev):
return a * x + (1 - a) * x_prev

class OneEuroFilter:
def __init__(self, t0, x0, dx0=0.0, min_cutoff=1.0, beta=0.0,
d_cutoff=1.0):
"""Initialize the one euro filter."""
# The parameters.
self.min_cutoff = float(min_cutoff)
self.beta = float(beta)
self.d_cutoff = float(d_cutoff)
# Previous values.
self.x_prev = float(x0)
self.dx_prev = float(dx0)
self.t_prev = float(t0)

def __call__(self, t, x):
"""Compute the filtered signal."""
t_e = t - self.t_prev

# The filtered derivative of the signal.
a_d = smoothing_factor(t_e, self.d_cutoff)
dx = (x - self.x_prev) / t_e
dx_hat = exponential_smoothing(a_d, dx, self.dx_prev)

# The filtered signal.
cutoff = self.min_cutoff + self.beta * abs(dx_hat)
a = smoothing_factor(t_e, cutoff)
x_hat = exponential_smoothing(a, x, self.x_prev)

# Memorize the previous values.
self.x_prev = x_hat
self.dx_prev = dx_hat
self.t_prev = t

return x_hat

An example of how to use the One Euro Filter for filtering a signal in real time.

# Let signal be a generator that yields a tuple (t, x)
# where t is time and x the values of the signal.
signal = ...

# Instantiate the OneEuroFilter with initial values and
# your value for parameters min_cutoff and beta.
t0, x0 = next(signal)
one_euro_filter = OneEuroFilter(
t0=t0,
x0=x0,
min_cutoff=...,
beta=...
)

# Filter the signal in real time.
for (t, x) in signal:
x_hat = one_euro_filter(t, x)
...

## References

1. CASIEZ, Géry, ROUSSEL, Nicolas and VOGEL, Daniel. 1€ filter: A simple speed-based low-pass filter for noisy input in interactive systems. In : Proceedings of the sigchi conference on human factors in computing systems. ACM, 2012. p. 2527–2530.