卡尔曼滤波学习

什么是卡尔曼滤波?

卡尔曼滤波是一种高效率递归滤波器,即只要获知上一时刻状态的估计值以及当前状态的观测值

就可以计算当前状态的估计值,因此不需要记录观测或者估计历史信息。卡尔曼滤波器与大多数

滤波器不同之处,在于它是一种纯粹的时域滤波器,它不需要在频域设计再转换到时域实现。

 

卡尔曼滤波包括两个阶段:

预测(KF.predict):

使用上一状态的估计,做出当前状态的估计

更新(KF.correct):

用当前状态的观测值优化在预测阶段获得的预测值,以次获得一个更精确的新估计值

使用卡尔曼滤波之前要考虑,模型是否满足卡尔曼滤波使用条件

以上个两个是卡尔曼滤波需要遵循的两个方程

第一个方程意味着xk的预估值必须通过线性随机方程,任意的xk都是前一个状态值xk-1和控制信号uk以及过程噪声wk-1的线性组合

下面的方程是观测方程,任意观测值zk(并不确定是否为真值)都是观测信号值xk和测量噪声vk的线性组合。它们都遵循高斯分布

过程噪声和测量噪声相互独立

如果确认了你的模型符合卡尔曼使用条件,就可以开始过程并进行迭代

 

xk-1 表示上个状态的估计值

Pk-1表示上个状态的协方差

 

有兴趣的可以深入研究下面两个链接

http://bilgin.esme.org/BitsAndBytes/KalmanFilterforDummies

http://www.bzarg.com/p/how-a-kalman-filter-works-in-pictures/

 

这里用OpenCV KalmanFilter举例说明

//构造函数
//@param dynamParams   状态维度
//@param measureParams 测量量维度
//@param controlParams 控制向量维度
//@param type          创建矩阵的类型只能是CV_32F 或者 CV_64F

CV_WRAP KalmanFilter( int dynamParams, int measureParams, int controlParams = 0, int type = CV_32F );
//预测函数  预测下个状态值
//@param control 控制矩阵
//@return        预测状态
CV_WRAP const Mat& predict(const Mat& control=Mat());  

//更新  根据观测值优化预测状态值
//@param  measurement 观测状态
//@return             优化后的状态值
CV_WRAP const Mat& correct(const Mat& measurement); 

 

以  y = kx + b  这个函数为例  

 

#include "opencv2/video/tracking.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;

int main(int, char**)
{
    double k = 10;
    double b = 15;
    
    cout << " origin k = " << k << " " << "b = " << b << endl;
    
    int N = 100;            //数据长度
    double w_sigma = 0.1;
    
    cv::RNG rng;
    
    vector<double>  x_data,y_data;
    
    cout << "generating data: " << endl;
    
    //生成带噪声的数据
    for(int i = 0; i < N; ++i)
    {
        double x = i;
        x_data.emplace_back(x);
        y_data.emplace_back(k * x + b + rng.gaussian(w_sigma));
    }
    
    //声明卡尔曼滤波器
    KalmanFilter KF(2, 1, 0);
    //状态
    Mat state(2, 1, CV_32F);
    //过程噪声
    Mat processNoise(2, 1, CV_32F);
    //参数初始化
    Mat measurement = Mat::zeros(1, 1, CV_32F);
    KF.transitionMatrix = (Mat_<float>(2,2) << 1, 0, 0, 1);
    
    setIdentity(KF.measurementMatrix);
    setIdentity(KF.processNoiseCov, Scalar::all(1e-5));
    setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));
    setIdentity(KF.errorCovPost, Scalar::all(1));
    
    for( int i = 0;i < N; ++i)
    {
        //预估值
        Mat prediction = KF.predict();
        //观测值
        KF.measurementMatrix.at<float>(0,0) = x_data[i];
        KF.measurementMatrix.at<float>(0,1) = 1;
        measurement = y_data[i];
        //获取优化值
        Mat result = KF.correct(measurement);
        cout << "k = " << result.at<float>(0,0) << " "
             << "b = " << result.at<float>(1,0) << endl;
    }
    
    return 0;
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值