智慧交通day02-车流量检测实现05:卡尔曼滤波器实践(小车模型)

1.filterpy

FilterPy是一个实现了各种滤波器的Python模块,它实现著名的卡尔曼滤波粒子滤波器。我们可以直接调用该库完成卡尔曼滤波器实现。其中的主要模块包括:

  • filterpy.kalman

    该模块主要实现了各种卡尔曼滤波器,包括常见的线性卡尔曼滤波器,扩展卡尔曼滤波器等。

  • filterpy.common

    该模块主要提供支持实现滤波的各种辅助函数,其中计算噪声矩阵的函数,线性方程离散化的函数等。

  • filterpy.stats

    该模块提供与滤波相关的统计函数,包括多元高斯算法,对数似然算法,PDF及协方差等。

  • filterpy.monte_carlo

    该模块提供了马尔科夫链蒙特卡洛算法,主要用于粒子滤波。

开源代码在:

https://github.com/rlabbe/filterpy/tree/master/filterpy/kalman

我们介绍下卡尔曼滤波器的实现,主要分为预测和更新两个阶段,在进行滤波之前,需要先进行初始化:

  • 初始化

预先设定状态变量dim_x和观测变量维度dim_z、协方差矩阵P、运动形式和观测矩阵H等,一般各个协方差矩阵都会初始化为单位矩阵,根据特定的场景需要相应的设置。


def __init__(self, dim_x, dim_z, dim_u = 0, x = None, P = None,Q = None, B = None, F = None, H = None, R = None):"""Kalman FilterRefer to http:/github.com/rlabbe/filterpyMethod-----------------------------------------Predict        |        Update-----------------------------------------|  K = PH^T(HPH^T + R)^-1x = Fx + Bu     |  y = z - HxP = FPF^T + Q   |  x = x + Ky|  P = (1 - KH)P|  S = HPH^T + R-----------------------------------------note: In update unit, here is a more numerically stable way: P = (I-KH)P(I-KH)' + KRK'Parameters----------dim_x: intdims of state variables, eg:(x,y,vx,vy)->4dim_z: intdims of observation variables, eg:(x,y)->2dim_u: intdims of control variables,eg: a->1p = p + vt + 0.5at^2v = v + at=>[p;v] = [1,t;0,1][p;v] + [0.5t^2;t]a"""assert dim_x >= 1, 'dim_x must be 1 or greater'assert dim_z >= 1, 'dim_z must be 1 or greater'assert dim_u >= 0, 'dim_u must be 0 or greater'self.dim_x = dim_xself.dim_z = dim_zself.dim_u = dim_u# initialization# predictself.x = np.zeros((dim_x, 1)) if x is None else x      # stateself.P = np.eye(dim_x)  if P is None else P            # uncertainty covarianceself.Q = np.eye(dim_x)  if Q is None else Q            # process uncertainty for predictionself.B = None if B is None else B                      # control transition matrixself.F = np.eye(dim_x)  if F is None else F            # state transition matrix# updateself.H = np.zeros((dim_z, dim_x)) if H is None else H  # Measurement function z=Hxself.R = np.eye(dim_z)  if R is None else R            # observation uncertaintyself._alpha_sq = 1.                              # fading memory controlself.z = np.array([[None] * self.dim_z]).T       # observationself.K = np.zeros((dim_x, dim_z))                # kalman gainself.y = np.zeros((dim_z, 1))                    # estimation errorself.S = np.zeros((dim_z, dim_z))                # system uncertainty, S = HPH^T + Rself.SI = np.zeros((dim_z, dim_z))               # inverse system uncertainty, SI = S^-1self.inv = np.linalg.invself._mahalanobis = None                         # Mahalanobis distance of measurementself.latest_state = 'init'                       # last process name
  • 预测阶段

接下来进入预测环节,为了保证通用性,引入了遗忘系数α,其作用在于调节对过往信息的依赖程度,α越大对历史信息的依赖越小:

 代码如下:


def predict(self, u = None, B = None, F = None, Q = None):"""Predict next state (prior) using the Kalman filter state propagation equations:x = Fx + BuP = fading_memory*FPF^T + QParameters----------u : ndarrayOptional control vector. If not `None`, it is multiplied by Bto create the control input into the system.B : ndarray of (dim_x, dim_z), or NoneOptional control transition matrix; a value of Nonewill cause the filter to use `self.B`.F : ndarray of (dim_x, dim_x), or NoneOptional state transition matrix; a value of Nonewill cause the filter to use `self.F`.Q : ndarray of (dim_x, dim_x), scalar, or NoneOptional process noise matrix; a value of None will cause thefilter to use `self.Q`."""if B is None:B = self.Bif F is None:F = self.Fif Q is None:Q = self.Qelif np.isscalar(Q):Q = np.eye(self.dim_x) * Q# x = Fx + Buif B is not None and u is not None:self.x = F @ self.x + B @ uelse:self.x = F @ self.x# P = fading_memory*FPF' + Qself.P = self._alpha_sq * (F @ self.P @ F.T) + Qself.latest_state = 'predict'
  • 更新阶段

按下式进行状态的更新:

 也可以写为:

 其中,y是测量余量,S是测量余量的协方差矩阵。

在实际应用中会做一些微调,使协方差矩阵为:

代码如下:


def update(self, z, R = None, H = None):"""Update Process, add a new measurement (z) to the Kalman filter.K = PH^T(HPH^T + R)^-1y = z - Hxx = x + KyP = (1 - KH)P or P = (I-KH)P(I-KH)' + KRK'If z is None, nothing is computed.Parameters----------z : (dim_z, 1): array_likemeasurement for this update. z can be a scalar if dim_z is 1,otherwise it must be convertible to a column vector.R : ndarray, scalar, or NoneOptionally provide R to override the measurement noise for thisone call, otherwise  self.R will be used.H : ndarray, or NoneOptionally provide H to override the measurement function for thisone call, otherwise self.H will be used."""if z is None:self.z = np.array([[None] * self.dim_z]).Tself.y = np.zeros((self.dim_z, 1))returnz = reshape_z(z, self.dim_z, self.x.ndim)if R is None:R = self.Relif np.isscalar(R):R = np.eye(self.dim_z) * Rif H is None:H = self.Hif self.latest_state == 'predict':# common subexpression for speedPHT = self.P @ H.T# S = HPH' + R# project system uncertainty into measurement spaceself.S = H @ PHT + Rself.SI = self.inv(self.S)# K = PH'inv(S)# map system uncertainty into kalman gainself.K = PHT @ self.SI# P = (I-KH)P(I-KH)' + KRK'# This is more numerically stable and works for non-optimal K vs# the equation P = (I-KH)P usually seen in the literature.I_KH = np.eye(self.dim_x) - self.K @ Hself.P = I_KH @ self.P @ I_KH.T + self.K @ R @ self.K.T# y = z - Hx# error (residual) between measurement and predictionself.y = z - H @ self.xself._mahalanobis = math.sqrt(float(self.y.T @ self.SI @ self.y))# x = x + Ky# predict new x with residual scaled by the kalman gainself.x = self.x + self.K @ self.yself.latest_state = 'update'

那接下来,我们就是用filterpy中的卡尔曼滤波器方法完成小车位置的预测。

2.小车案例

现在利用卡尔曼滤波对小车的运动状态进行预测。主要流程如下所示:

  • 导入相应的工具包
  • 小车运动数据生成
  • 参数初始化
  • 利用卡尔曼滤波进行小车状态预测
  • 可视化:观察参数的变化与结果

下面我们看下整个流程实现:

  • 导入包
from matplotlib import pyplot as plt
import seaborn as sns
import numpy as np
from filterpy.kalman import KalmanFilter
  • 小车运动数据生成

在这里我们假设小车作速度为1的匀速运动

# 生成1000个位置,从1到1000,是小车的实际位置
z = np.linspace(1,1000,1000) 
# 添加噪声
mu,sigma = 0,1
noise = np.random.normal(mu,sigma,1000)
# 小车位置的观测值
z_nosie = z+noise
  • 参数初始化
# dim_x 状态向量size,在该例中为[p,v],即位置和速度,size=2
# dim_z 测量向量size,假设小车为匀速,速度为1,测量向量只观测位置,size=1
my_filter = KalmanFilter(dim_x=2, dim_z=1)# 定义卡尔曼滤波中所需的参数
# x 初始状态为[0,0],即初始位置为0,速度为0.
# 这个初始值不是非常重要,在利用观测值进行更新迭代后会接近于真实值
my_filter.x = np.array([[0.], [0.]])# p 协方差矩阵,表示状态向量内位置与速度的相关性
# 假设速度与位置没关系,协方差矩阵为[[1,0],[0,1]]
my_filter.P = np.array([[1., 0.], [0., 1.]])# F 初始的状态转移矩阵,假设为匀速运动模型,可将其设为如下所示
my_filter.F = np.array([[1., 1.], [0., 1.]])# Q 状态转移协方差矩阵,也就是外界噪声,
# 在该例中假设小车匀速,外界干扰小,所以我们对F非常确定,觉得F一定不会出错,所以Q设的很小
my_filter.Q = np.array([[0.0001, 0.], [0., 0.0001]])# 观测矩阵 Hx = p
# 利用观测数据对预测进行更新,观测矩阵的左边一项不能设置成0
my_filter.H = np.array([[1, 0]])
# R 测量噪声,方差为1
my_filter.R = 1
  • 卡尔曼滤波进行预测
# 保存卡尔曼滤波过程中的位置和速度
z_new_list = []
v_new_list = []
# 对于每一个观测值,进行一次卡尔曼滤波 
for k in range(len(z_nosie)):# 预测过程 my_filter.predict()# 利用观测值进行更新my_filter.update(z_nosie[k])# do something with the outputx = my_filter.x# 收集卡尔曼滤波后的速度和位置信息z_new_list.append(x[0][0])v_new_list.append(x[1][0])
  • 可视化

  • 预测误差的可视化

    # 位移的偏差
    dif_list = []
    for k in range(len(z)):dif_list.append(z_new_list[k]-z[k])
    # 速度的偏差
    v_dif_list = []
    for k in range(len(z)):v_dif_list.append(v_new_list[k]-1)
    plt.figure(figsize=(20,9))
    plt.subplot(1,2,1)
    plt.xlim(-50,1050)
    plt.ylim(-3.0,3.0)
    plt.scatter(range(len(z)),dif_list,color ='b',label = "位置偏差")
    plt.scatter(range(len(z)),v_dif_list,color ='y',label = "速度偏差")
    plt.legend()

    运行结果如下所示:

2.卡尔曼滤波器参数的变化

首先定义方法将卡尔曼滤波器的参数堆叠成一个矩阵,右下角补0,我们看一下参数的变化。

# 定义一个方法将卡尔曼滤波器的参数堆叠成一个矩阵,右下角补0 
def filter_comb(p, f, q, h, r):a = np.hstack((p, f))b = np.array([r, 0])b = np.vstack([h, b])b = np.hstack((q, b))a = np.vstack((a, b))return a

 对参数变化进行可视化:

# 保存卡尔曼滤波过程中的位置和速度
z_new_list = []
v_new_list = []
# 对于每一个观测值,进行一次卡尔曼滤波 
for k in range(1):# 预测过程 my_filter.predict()# 利用观测值进行更新my_filter.update(z_nosie[k])# do something with the outputx = my_filter.xc = filter_comb(my_filter.P,my_filter.F,my_filter.Q,my_filter.H,my_filter.R)plt.figure(figsize=(32,18))sns.set(font_scale=4)#sns.heatmap(c,square=True,annot=True,xticklabels=False,yticklabels==False,cbar=False)sns.heatmap(c,square=True,annot=True,xticklabels=False,yticklabels=False,cbar=False)

对比变换:

从图中可以看出变化的P,其他的参数F,Q,H,R为变换。另外状态变量x和卡尔曼系数K也是变化的。

3.概率密度函数

为了验证卡尔曼滤波的结果优于测量的结果,绘制预测结果误差和测量误差的概率密度函数:

# 生成概率密度图像
z_noise_list_std = np.std(noise)
z_noise_list_avg = np.mean(noise)
z_filterd_list_std = np.std(dif_list)
import seaborn as sns 
plt.figure(figsize=(16,9))
ax = sns.kdeplot(noise,shade=True,color="r",label="std=%.3f"%z_noise_list_std)
ax = sns.kdeplot(dif_list,shade=True,color="g",label="std=%.3f"%z_filterd_list_std)

结果如下:


总结:

1.了解filterpy工具包

FilterPy是一个实现了各种滤波器的Python模块,它实现著名的卡尔曼滤波粒子滤波器。直接调用该库完成卡尔曼滤波器实现。

2.知道卡尔曼滤波的实现过程

卡尔曼滤波器的实现,主要分为预测和更新两个阶段,在进行滤波之前,需要先进行初始化

  • 初始化

预先设定状态变量和观测变量维度、协方差矩阵、运动形式和转换矩阵

  • 预测

对状态变量X和协方差P进行预测

  • 更新

利用观测结果对卡尔曼滤波的结果进行修征

3.能够利用卡尔曼滤波器完成小车目标状态的预测

  • 导入相应的工具包

  • 小车运动数据生成:匀速运动的小车模型

  • 参数初始化:对卡尔曼滤波的参数进行初始化,包括状态变量和观测变量维度、协方差矩阵、运动形式和转换矩阵

  • 利用卡尔曼滤波进行小车状态预测:使用Filterpy工具包,调用predict和update完成小车状态的预测

  • 可视化:观察参数的变化与结果

    1.预测误差的分布:p,v

    2.参数的变化:参数中变化的是X,P,K,不变的是F,Q,H,R

    1. 误差的概率密度函数:卡尔曼预测的结果优于测量结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469725.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux多线程——使用互斥量同步线程

前文再续,书接上一回,在上一篇文章:Linux多线程——使用信号量同步线程中,我们留下了一个如何使用互斥量来进行线程同步的问题,本文将会给出互斥量的详细解说,并用一个互斥量解决上一篇文章中,要…

智慧交通day02-车流量检测实现05:小车匀速案例

""" 现在利用卡尔曼滤波对小车的运动状态进行预测。主要流程如下所示:导入相应的工具包小车运动数据生成参数初始化利用卡尔曼滤波进行小车状态预测可视化:观察参数的变化与结果 """#导入包 from matplotlib import pyplo…

排座椅

题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳。同学们在教室中坐成了M行…

智慧交通day02-车流量检测实现05:小车匀加速案例

""" 现在利用卡尔曼滤波对小车的运动状态进行预测。主要流程如下所示:导入相应的工具包小车运动数据生成参数初始化利用卡尔曼滤波进行小车状态预测可视化:观察参数的变化与结果 """#导入包 from matplotlib import pyplo…

智慧交通day02-车流量检测实现06:目标估计模型-卡尔曼滤波

在这里我们主要完成卡尔曼滤波器进行跟踪的相关内容的实现。 初始化:卡尔曼滤波器的状态变量和观测输入更新状态变量根据状态变量预测目标的边界框初始化: 状态量x的设定是一个七维向量: 分别表示目标中心位置的x,y坐标,面积s和当…

python或anaconda下安装opencv提示Error:No matching distribution found for opencv

python或anaconda下安装opencv提示Error:No matching distribution found for opencv 错误提示: ERROR: Could not find a version that satisfies the requirement python-opencv (from versions: none) ERROR: No matching distribution found for p…

iOS 10 的坑:新机首次安装 app,请求网络权限“是否允许使用数据”(转)

转载自:文/戴仓薯(简书作者)原文链接:http://www.jianshu.com/p/6cbde1b8b922症状 iOS 10 之后,陆陆续续地有用户联系我们,说新机第一次安装、第一次启动的时候,app 首屏一片空白&am…

智慧交通day02-车流量检测实现06:目标估计模型-卡尔曼滤波(汇总)

from __future__ import print_function from numba import jit import numpy as np from scipy.optimize import linear_sum_assignment from filterpy.kalman import KalmanFilter#计算IOU(交并比) jit def iou(bb_test,bb_gt):"""在两…

Redis入门指南(第2版) Redis设计思路学习与总结

https://www.qcloud.com/community/article/222 宋增宽,腾讯工程师,16年毕业加入腾讯,从事海量服务后台设计与研发工作,现在负责QQ群后台等项目,喜欢研究技术,并思考技术演变,专注于高并发业务架…

智慧交通day02-车流量检测实现07:匈牙利算法

匈牙利算法(Hungarian Algorithm)与KM算法(Kuhn-Munkres Algorithm)是用来解决多目标跟踪中的数据关联问题,匈牙利算法与KM算法都是为了求解二分图的最大匹配问题。 有一种很特别的图,就做二分图&#xff0…

非线性回归(Non-linear Regression)学习笔记

非线性回归&#xff08;Non-linear Regression&#xff09; 1.概率: 1.1定义概率Probability:对一件事情发生的可能性的衡量 1.2范围 0<P<1 1.3计算方法: 1.3.1根据个人置信 1.3.2根据历史数据 1.3.3根据模拟数据 1.4条件概率:&#xff08;A发生的条件下B发生的概率&…

智慧交通day02-车流量检测实现08:目标跟踪中的数据关联(将检测框bbox与卡尔曼滤波器的跟踪框进行关联匹配)

# 将YOLO模型的检测框和卡尔曼滤波的跟踪框进行匹配 def associate_detection_to_tracker(detections,trackers,iou_threshold0.3):"""将检测框bbox与卡尔曼滤波器的跟踪框进行关联匹配:param detections:检测框:param trackers:跟踪框&#xff0c;即跟踪目标:p…

回归中的相关度和R平方值 学习笔记

回归中的相关度和R平方值 自变量x和因变量y的相关度 1.皮尔逊相关系数(Pearson Correlation Coefficient): 1.1衡量两个值线性相关强度的量 1.2取值范围[-1,1]: 正向相关: >0,负向相关: <0,无相关性: 0 公式&#xff1a;correlation&#xff0c; correlationvariance(Co…

智慧交通day02-车流量检测实现09:SORT/deepSORT

SORT和DeepSORT是多目标跟踪中两个知名度比较高的算法。DeepSORT是原团队对SORT的改进版本。现在来解析一下SORT和DeepSORT的基本思路。 1.SORT SORT核心是卡尔曼滤波和匈牙利匹配两个算法。流程图如下所示&#xff0c;可以看到整体可以拆分为两个部分&#xff0c;分别是匹配…

素数环 与 算法 全排列

在说起全排列前&#xff0c;先说一下昨天碰到的一个题目&#xff08;答案不是我做出来的&#xff0c;但是我感觉有好多个亮点&#xff0c;贴出来方便日后的学习&#xff09;&#xff1a; 素数环 时间限制&#xff1a;1000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;…

简单线性回归(Simple Linear Regression)和多元线性回归(Multiple Regression)学习笔记

简单线性回归(Simple Linear Regression) 0.前提介绍: 为什么需要统计量? 统计量:描述数据特征 0.1集中趋势衡量 0.1.1均值(平均数&#xff0c;平均值) (mean)&#xff1a;&#xff08;求和除以个数&#xff0c;Ex也可以表示x求均值&#xff09; 0.1.2中位数(median) : 将数…

智慧交通day02-车流量检测实现10:多目标追踪实现

在这里我们主要实现了一个多目标跟踪器&#xff0c;管理多个卡尔曼滤波器对象&#xff0c;主要包括以下内容&#xff1a; 初始化&#xff1a;最大检测数&#xff0c;目标未被检测的最大帧数 目标跟踪结果的更新&#xff0c;即跟踪成功和失败的目标的更新 初始化 def __init_…

智慧交通day02-车流量检测实现11:yoloV3模型

yoloV3以V1&#xff0c;V2为基础进行的改进&#xff0c;主要有&#xff1a;利用多尺度特征进行目标检测&#xff1b;先验框更丰富&#xff1b;调整了网络结构&#xff1b;对象分类使用logistic代替了softmax,更适用于多标签分类任务。 1.算法简介 YOLOv3是YOLO (You Only Loo…

bzoj1992鬼谷子的钱袋(二分乱搞 二进制)

1192: [HNOI2006]鬼谷子的钱袋 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3223 Solved: 2333Descriptio 鬼谷子非常聪明&#xff0c;正因为这样&#xff0c;他非常繁忙&#xff0c;经常有各诸侯车的特派员前来向他咨询时政。有一天&#xff0c;他在咸阳游历的时候&…

聚类(Clustering): K-means算法

聚类(Clustering): K-means算法 1.归类: 聚类(clustering)属于非监督学习(unsupervised learning) 无类别标记( class label) 3. K-means 算法&#xff1a; 3.1 Clustering 中的经典算法&#xff0c;数据挖掘十大经典算法之一 3.2 算法接受参数 k &#xff1b;然后将事先输入…