东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 2394|回复: 2
打印 上一主题 下一主题

[Python] filterpy中线性卡尔曼滤波算法_实战_可视化

[复制链接]

1366

主题

1857

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14459
QQ
跳转到指定楼层
楼主
发表于 2022-3-2 11:39:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式



filterpy中线性卡尔曼滤波算法_实战_可视化


  1. # -*- coding: utf-8 -*-
  2. __author__ = u'东方耀 微信:dfy_88888'
  3. __date__ = '2022/3/2 下午14:50'
  4. __product__ = 'PyCharm'
  5. __filename__ = '01_filterpy跟踪狗_实战完整'

  6. import math
  7. import numpy as np
  8. from filterpy.stats import plot_covariance
  9. from filterpy.kalman import KalmanFilter, EKF, UKF
  10. from filterpy.common import Q_discrete_white_noise
  11. import matplotlib.pyplot as plt
  12. import matplotlib.ticker as mticker
  13. import random
  14. from matplotlib.font_manager import FontProperties

  15. # font_fname = "C:\Windows\Fonts\simfang.ttf"
  16. font_fname = "/usr/share/fonts/wps-office/simfang.ttf"
  17. font = FontProperties(fname=font_fname)


  18. # filterpy中线性卡尔曼滤波算法_实战_可视化
  19. np.random.seed(88)


  20. def randomcolor():
  21.     colorArr = ['1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
  22.     color = ""
  23.     for i in range(6):
  24.         color += colorArr[random.randint(0, 14)]
  25.     return "#" + color


  26. def compute_dog_data(z_var, process_var, count=1, dt=1.):
  27.     "returns track, measurements 1D ndarrays"
  28.     x, vel = 0., 1.   # 这是构造数据的初始位置 与 理想速度
  29.     # 观测值的 标准差
  30.     z_std = math.sqrt(z_var)
  31.     # p_std 速度变化的标准差
  32.     p_std = math.sqrt(process_var)
  33.     xs, zs = [], []
  34.     for _ in range(count):
  35.         # 每次的速度在1m/s上下波动
  36.         v = vel + (np.random.randn() * p_std)
  37.         # x为真实的位置
  38.         x += v * dt
  39.         xs.append(x)
  40.         zs.append(x + np.random.randn() * z_std)
  41.     # xs:狗真实的位置   zs:观测的位置
  42.     return np.array(xs), np.array(zs)


  43. def pos_vel_filter(x, P, R, Q=0., dt=1.0):
  44.     """ Returns a KalmanFilter which implements a
  45.     constant velocity model for a state [x dx].T
  46.     位置position 速度vel 滤波器
  47.     """
  48.     # dim_x的状态向量的维度(位置 速度)   dim_z是测量的维度(位置)
  49.     # 带有dim_x的状态向量和测量向量的大小
  50.     kf = KalmanFilter(dim_x=2, dim_z=1)
  51.     kf.x = np.array([x[0], x[1]])  # 这是初始的location and velocity
  52.     kf.F = np.array([[1., dt],
  53.                      [0., 1.]])  # state transition matrix
  54.     kf.H = np.array([[1., 0]])  # Measurement function
  55.     kf.R *= R  # measurement uncertainty  因为R的维度为1
  56.     if np.isscalar(P):
  57.         kf.P *= P  # covariance matrix
  58.     else:
  59.         kf.P[:] = P  # [:] makes deep copy
  60.     if np.isscalar(Q):
  61.         kf.Q = Q_discrete_white_noise(dim=2, dt=dt, var=Q)
  62.         print("Q过程噪声协方差矩阵kf.Q:", kf.Q)
  63.     else:
  64.         kf.Q[:] = Q
  65.     return kf


  66. def run(x0=(0., 0.), P=500, R=0, Q=0, dt=1.0,
  67.         track=None, zs=None,
  68.         count=0, do_plot=True, **kwargs):
  69.     """
  70.     track is the actual position of the dog, zs are the
  71.     corresponding measurements.
  72.     """

  73.     # Simulate dog if no data provided.
  74.     if zs is None:
  75.         # 生成 真实的track 测量值zs
  76.         track, zs = compute_dog_data(z_var=R, process_var=Q, count=count, dt=dt)

  77.     # create the Kalman filter
  78.     kf = pos_vel_filter(x0, R=R, P=P, Q=Q, dt=dt)
  79.     print("构建的卡尔曼滤波器对象:\n", kf.__repr__)

  80.     # run the kalman filter and store the results
  81.     xs, cov = [], []
  82.     for z in zs:
  83.         kf.predict()
  84.         # # P = (I-KH)P(I-KH)' + KRK'
  85.         #         # This is more numerically stable
  86.         #         # and works for non-optimal K vs the equation
  87.         #         # P = (I-KH)P usually seen in the literature.
  88.         kf.update(z)
  89.         # xs是后验估计值  最优估计值
  90.         xs.append(kf.x)
  91.         # 看 P矩阵的变化
  92.         cov.append(kf.P)

  93.     xs, cov = np.array(xs), np.array(cov)

  94.     # if do_plot:
  95.     #     plot_track(xs[:, 0], track, zs, cov, **kwargs)
  96.     return track, zs, xs, cov


  97. x0 = (10., 10.)  # 初始的位置与速度
  98. P = np.diag([500., 49.])  # 初始的误差协方差矩阵P
  99. frame_num = 50
  100. x_position_true, x_position_measure, X_kalman_est, all_P_cov_mat = run(x0=x0, count=frame_num, R=10, Q=1, P=P)

  101. print("所有的真实的位置:", x_position_true.shape)
  102. print("所有的测量的位置:", x_position_measure.shape)
  103. print("所有的后验估计值(位置与速度):", X_kalman_est.shape)
  104. print("所有的误差的协方差矩阵P:", all_P_cov_mat.shape)

  105. my_color = []
  106. for _ in range(frame_num):
  107.     # 每一帧的颜色不一样
  108.     my_color.append(randomcolor())


  109. # 画图展示
  110. plt.figure(figsize=(14, 12))
  111. plt.figure(1)
  112. plt.xlabel("位置", fontproperties=font, fontsize=15)
  113. plt.ylabel("速度", fontproperties=font, fontsize=15)

  114. # plot_covariance([20.0, 10.], np.diag([50, 50]), edgecolor='r')
  115. plot_covariance(x0, P, edgecolor='r', ls='dashed')

  116. for i in range(X_kalman_est.shape[0]):
  117.     plt.title('误差的协方差矩阵P的变化(协方差椭圆)_第%d帧' % i, fontproperties=font, fontsize=16)
  118.     # print("第%d帧的后验估计值:" % i, X_kalman_est[i, :])
  119.     # print("第%d帧的误差协方差矩阵:" % i, all_P_cov_mat[i, :])
  120.     plot_covariance(X_kalman_est[i, :], all_P_cov_mat[i, :], edgecolor=my_color[i])
  121.     plt.pause(0.01)
  122.     # if(i >= 3):
  123.     #     plt.pause(100000000)


  124. plt.figure(figsize=(14, 12))
  125. plt.figure(2)
  126. plt.xlabel("时间", fontproperties=font, fontsize=15)
  127. plt.ylabel("位置", fontproperties=font, fontsize=15)
  128. plt.title('线性kalman滤波算法', fontproperties=font, fontsize=16)
  129. # plt.ylim()
  130. plt.plot(x_position_true, color="g", linestyle=":", marker='o', markersize=6, label="x_position_true")
  131. plt.plot(x_position_measure, color="b", linestyle=":", marker='o', markersize=6, label="x_position_measure")
  132. print("看看位置改变的顺序:", X_kalman_est[:8, 0])
  133. plt.plot(X_kalman_est[:, 0], color="r", linestyle="-", marker='o', markersize=6, label="x_position_kalman_est")
  134. plt.legend()


  135. plt.show()
复制代码


filterpy中线性卡尔曼滤波01.png (81.09 KB, 下载次数: 206)

filterpy中线性卡尔曼滤波01.png

filterpy中线性卡尔曼滤波02.png (131.45 KB, 下载次数: 207)

filterpy中线性卡尔曼滤波02.png
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1366

主题

1857

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14459
QQ
沙发
 楼主| 发表于 2022-3-2 14:50:57 | 只看该作者
在这个问题中,我们将跟踪狗的位置和速度  状态向量
状态变量可以是观测变量(由传感器直接测量),也可以是隐藏变量(从观测变量推断)
对于我们的狗跟踪问题,传感器只读取位置,所以位置被观察,速度被隐藏

重要的是要理解,跟踪位置和速度是一种设计选择,具有我们尚未准备探索的含义和假设
例如,我们还可以追踪加速度,甚至是急动
卡尔曼滤波器如何计算隐藏变量的估计

在最后一章中,我们证明了位置和速度是相关的。
但是对于一只狗来说,它们有多大的相关性呢?我不知道。正如我们将看到的,过滤器会为我们计算这个,
所以我将协方差初始化为零(非对角线上的)。当然,如果你知道协方差,你应该使用它们

卡尔曼滤波器不只是过滤数据,它允许我们将机器人和飞机等系统的控制输入结合起来

协方差矩阵
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1366

主题

1857

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14459
QQ
板凳
 楼主| 发表于 2022-3-2 16:49:43 | 只看该作者
协方差矩阵P 告诉我们滤波器的理论性能
标准偏差是方差的平方根,大约68%的高斯分布发生在一个标准偏差内
我们可以用这段代码实现非常复杂的多维过滤器,只需改变过滤器变量的赋值即可。也许我们想追踪金融模型中的100个维度
或者我们有一架带有GPS、INS、塔康、雷达高度计、气压高度计和空速指示器的飞机,
我们希望将所有这些传感器集成到一个模型中,以预测3D空间中的位置、速度和加速度
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-6-26 20:05 , Processed in 0.192498 second(s), 22 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表