zoukankan      html  css  js  c++  java
  • Kalman滤波器的简单实现

    在目标跟踪领域,Kalman滤波器是一个很常用的方法。

    以在二维平面中跟踪一个物体的位置和速度为例,说明如果实现一个简单的Kalman跟踪器。

    具体使用OpenCV中的KalmanFilter类来实现。

    1. 参数初始化

    kalman = cv2.KalmanFilter(4,2)
    

    表示Kalman滤波器转移矩阵维度为4,测量矩阵维度为2。

    因为状态量包括4个(分别是x、y方向的位移和速度),可观测的量有2个(分别是x、y方向的位移)。

    kalman.measurementMatrix = np.array([[1,0,0,0],[0,1,0,0]],np.float32)
    

    测量矩阵及其含义为:

    kalman.transitionMatrix = np.array([[1,0,1,0],[0,1,0,1],[0,0,1,0],[0,0,0,1]], np.float32)
    

    转移矩阵及其含义为:

    kalman.processNoiseCov = np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]], np.float32) * 0.003
    kalman.measurementNoiseCov = np.array([[1,0],[0,1]], np.float32) * 0.5
    

    过程噪声和测量噪声以一个经验值来估计。

    2. 生成测试数据

    用三角函数叠加随机扰动的方式来生成测试数据。

    def data_generator(length=100):
        dxy = []
        xy = []
        last_xy = [0, 0]
        for i in range(length):
            x_base = 5 - 5 * math.cos(2 * i * math.pi / length)
            y_base = 50 - 50 * math.cos(2 * i * math.pi / length)
            x_noise = 1 * (random()-0.5)
            y_noise = 20 * (random()-0.5)
            dx_base = math.sin(2 * i * math.pi / length)
            dy_base = 30 * math.sin(2 * i * math.pi / length)
            dx_noise = 1 * (random()-0.5)
            dy_noise = 5 * (random()-0.5)
            cur_xy = [x_base + x_noise + dx_base + dx_noise, 
                      y_base + y_noise + dy_base + dy_noise]
            cur_dxy = [cur_xy[0]-last_xy[0], cur_xy[1]-last_xy[1]]
            xy.append(cur_xy)
            dxy.append(cur_dxy)
            last_xy = cur_xy
        return np.array(dxy, dtype=np.float32), 
               np.array(xy, dtype=np.float32)
    

    3. 运行

    核心就是kalman的两个方法:

    • correct更新当前测量值;
    • predict预测下一帧的值。
    length = 100
    dxy, xy = data_generator2(length)
    dxy_pred = []
    xy_pred = []
    for i in range(length):
        kalman.correct(xy[i])
        current_prediction = kalman.predict()
        xy_pred.append(current_prediction[:2, 0])
        dxy_pred.append(current_prediction[2:, 0])  
    dxy_pred = np.stack(dxy_pred, axis=0)
    xy_pred = np.stack(xy_pred, axis=0)
    

    4. 可视化

    利用Matplotlib将结果可视化后如下图所示:

    Figure_1

    可视化部分代码如下所示:

    plot_image((xy, dxy, xy_pred, dxy_pred))
    
    def plot_image(inputs):
        xy, dxy, xy_pred, dxy_pred = inputs
        
        fig, axes = plt.subplots(2, 2)
        fig.set_size_inches(18, 9)
        axes[0, 0].plot(xy[:,0], color='red', label='Measured')
        axes[0, 0].plot(xy_pred[:,0], color='blue', label='Predicted')
        axes[0, 1].plot(xy[:,1], color='red', label='Measured')
        axes[0, 1].plot(xy_pred[:,1], color='blue', label='Predicted')
        axes[1, 0].plot(dxy[:,0], color='red', label='Measured')
        axes[1, 0].plot(dxy_pred[:,0], color='blue', label='Predicted')
        axes[1, 1].plot(dxy[:,1], color='red', label='Measured')
        axes[1, 1].plot(dxy_pred[:,1], color='blue', label='Predicted')
    
        axes[0, 0].set_title('Distance - X',loc='center',fontstyle='normal')
        axes[0, 1].set_title('Distance - Y',loc='center',fontstyle='normal')
        axes[1, 0].set_title('Speed - X',loc='center',fontstyle='normal')
        axes[1, 1].set_title('Speed - Y',loc='center',fontstyle='normal')
        axes[0, 0].legend()
        axes[0, 1].legend()
        axes[1, 0].legend()
        axes[1, 1].legend()
        plt.show()
        return
    
  • 相关阅读:
    20150607-0608
    20150423
    感触
    NSString里面的数字
    Git使用相关
    状态栏的设置
    UI相关问题
    分栏(标签)控制器
    导航控制器
    NSAttributedString 属性
  • 原文地址:https://www.cnblogs.com/lylec/p/14353567.html
Copyright © 2011-2022 走看看