卡尔曼滤波(Kalman filtering)是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。由于观测数据中包括系统中的噪声和干扰的影响,所以最优估计也可看作是滤波过程。
数据滤波是去除噪声还原真实数据的一种数据处理技术,Kalman滤波在测量方差已知的情况下能够从一系列存在测量噪声的数据中,估计动态系统的状态。(百度百科)
实际应用中,我们陀螺仪实验的时候,会发现获取的数值抖动太大,不够平滑;这样的数值在应用时会导致很多问题,因此需要通过一定的算法将数值转换的更平滑。如下采集数据:
105.87231557, 108.0076993, 85.64052734, 84.23328308, 124.71488794, 102.91086635, 96.6229862, 93.07739765, 98.52594135, 111.79610743, 94.78393208, 105.27301268, 87.23224952, 89.71036819, 117.43724425, 64.70525616, 75.48832499, 91.99249324, 105.44355624, 84.93538347
上面的数据是获取的陀螺仪Roll方向20次样本数据,可见数值波动很大,如84都124,89到117等。下面我们将尝试卡尔曼算法,实现数值降噪滤波。
代码示例:
#!/usr/bin/env python
#coding:utf-8
'''
from JiuJiang
树莓酱的操作实例
https:://www.suhmeijiang.com
'''
import matplotlib.pyplot as plt
#滤波类
class kalman_filter:
def __init__(self,Q,R):
self.Q = Q
self.R = R
self.P_k_k1 = 1
self.Kg = 0
self.P_k1_k1 = 1
self.x_k_k1 = 0
self.ADC_OLD_Value = 0
self.Z_k = 0
self.kalman_adc_old=0
def kalman(self,ADC_Value):
self.Z_k = ADC_Value
if (abs(self.kalman_adc_old-ADC_Value)>=60):
self.x_k1_k1= ADC_Value*0.382 + self.kalman_adc_old*0.618
else:
self.x_k1_k1 = self.kalman_adc_old;
self.x_k_k1 = self.x_k1_k1
self.P_k_k1 = self.P_k1_k1 + self.Q
self.Kg = self.P_k_k1/(self.P_k_k1 + self.R)
kalman_adc = self.x_k_k1 + self.Kg * (self.Z_k - self.kalman_adc_old)
self.P_k1_k1 = (1 - self.Kg)*self.P_k_k1
self.P_k_k1 = self.P_k1_k1
self.kalman_adc_old = kalman_adc
return kalman_adc
if __name__ == '__main__':
kalman_filter = kalman_filter(0.001,0.1)
#陀螺仪测试数据
test_array = [105.87231557, 108.0076993, 85.64052734, 84.23328308, 124.71488794, 102.91086635, 96.6229862, 93.07739765, 98.52594135, 111.79610743, 94.78393208, 105.27301268, 87.23224952, 89.71036819, 117.43724425, 64.70525616, 75.48832499, 91.99249324, 105.44355624, 84.93538347, 105.87231557, 108.0076993, 85.64052734, 84.23328308, 124.71488794, 102.91086635, 96.6229862, 93.07739765, 98.52594135, 111.79610743, 94.78393208, 105.27301268, 87.23224952, 89.71036819, 117.43724425, 64.70525616, 75.48832499, 91.99249324, 105.44355624, 84.93538347]
print(test_array)
n = len(test_array)
#卡尔曼过滤
new_array=[]
for i in range(n):
new_array.append(int(kalman_filter.kalman(test_array[i])))
#滤波后数据
print(new_array)
#图形生成展示
plt.plot(new_array)
plt.plot(test_array)
plt.show()
效果如图:
上图可见,我们通过vnc进入可视化桌面,然后命令行执行程序文件,左侧是输出的数据;右侧是图表化滤波数据和原值数据,蓝色是滤波后数据,黄色是原值数据。可见,滤波后数据变的平滑很多。
算法部分来源于大神文章:https://blog.csdn.net/moge19/article/details/82531119
图形化展示部分,使用的是matplotlib,Python的2D绘图库;系统默认是没有安装的,需要自己安装,由于默认安装的matplotlib版本执行一直有问题,所以安装时指定了版本:
pip install matplotlib==2.0.2
安装后执行如果报问题:Couldn't find foreign struct converter for 'cairo.Context',那么执行如下命令:
sudo apt-get install python-gi-cairo
其他滤波算法,还没尝试,如果有兴趣可以试一下:十种滤波算法的Python实现。