一欧元滤波器是一种通过可调抖动(tunable jitter)和延迟平衡(lag balance)来改善噪声信号质量的工具。它使用低通滤波器,但是截止频率根据速度变化:在低速时,低截止以延迟为代价减少抖动,但在高速时,增加截止值减少延迟而不是抖动。
从直觉上看,人们在缓慢移动时对抖动而不是延迟非常敏感,但随着移动速度的增加,人们对延迟而不是抖动变得非常敏感。
对于人类的运动,噪声通常在信号中形成高频,而实际的肢体运动频率较低。低通滤波器的设计目的是让这些所需的低频部分通过,同时衰减高于固定截止频率的高频信号。低通滤波器的阶数与它如何积极地衰减每个频率有关:一阶滤波器在频率每加倍时将信号振幅降低一半,而高阶变体以更大的速率降低信号振幅。
算法推导:
https://jaantollander.com/post/noise-filtering-using-one-euro-filter/#fn:1
简单来说:
有两个可以调节的参数,
最小截止频率fc↓,会减少抖动,但是增大延迟
参数β↑,会减小延迟,增大抖动
一个举例实现的网址:
https://gery.casiez.net/1euro/InteractiveDemo/
OneEuroFilter的各种语言实现搬运网址:
https://gery.casiez.net/1euro/
C++语言实现如下:
#include <iostream>
#include <stdexcept>
#include <cmath>
#include <ctime>
// -----------------------------------------------------------------
// Utilities
#define M_PI 3.1415926 //原文档这里缺少了对M_PI的定义!
void randSeed(void) {
srand(time(0)); //设置随机数种子
}
double unifRand(void) {
return rand() / double(RAND_MAX);
}
typedef double TimeStamp; // in seconds
static const TimeStamp UndefinedTime = -1.0;
// -----------------------------------------------------------------
class LowPassFilter {
//低通滤波器
double y, a, s;
bool initialized;
void setAlpha(double alpha) {
if (alpha <= 0.0 || alpha > 1.0)
throw std::range_error("alpha should be in (0.0., 1.0]");
a = alpha;
}
public:
LowPassFilter