OpenCV3-Python卡尔曼(Kalman)滤波器介绍
admin 于 2018年09月16日 发表在 计算机视觉

卡尔曼滤波器主要由Rudolf Kalam在20世纪50年代末提出来的,它在众多领域得到应用,特别是交通工具的导航系统上经常用到。该方法认为物体的运动模型服从高斯模型,通过对输入数据流进行递归操作,预测目标的运动状态,然后通过与观察模型进行对比,根据误差来更新运动目标的状态。

举例说明:

假设桌子上有一个小红球,现场也有摄像头对着这一个场景。小球确定为被追踪的目标,用手指轻弹下小球,它会在桌子上滚动。如果球在一个特定方向上以1米/秒的速度滚动,则不需要卡尔曼滤波器也可估计1秒后球在哪里,因为1秒后它就在1米远处,利用卡尔曼滤波器可以基于上一帧的信息,预测目标在当前视频帧中的位置。

卡尔曼滤波算法分为两个阶段:

<1> 预测:在此阶段,卡尔曼滤波器使用由当前点计算的协方差来估计目标的新位置;

<2> 更新:在此阶段,卡尔曼滤波器记录目标的位置,并为下一次循环计算修正协方差;

1. 应用举例

绘制一个空帧和两条线:一条对应于鼠标的实际运动;另一条对应于卡尔曼滤波器预测的轨迹。

import cv2, numpy as np

measurements = []
predictions = []

#创建800*800的空帧
frame = np.zeros((800, 800, 3), np.uint8)

#初始化测量数组和鼠标运动预测数组
last_measurement = current_measurement = np.array((2,1), np.float32) 
last_prediction = current_prediction = np.zeros((2,1), np.float32)

#鼠标移动回调函数,绘制跟踪结果
def mousemove(event, x, y, s, p):
    global frame, current_measurement, measurements, last_measurement, current_prediction, last_prediction
    last_prediction = current_prediction
    last_measurement = current_measurement
    current_measurement = np.array([[np.float32(x)],[np.float32(y)]])
    
    #Updates the predicted state from the measurement.
    kalman.correct(current_measurement)
    
    #Computes a predicted state.
    current_prediction = kalman.predict()
    
    lmx, lmy = last_measurement[0], last_measurement[1]
    cmx, cmy = current_measurement[0], current_measurement[1]
    lpx, lpy = last_prediction[0], last_prediction[1]
    cpx, cpy = current_prediction[0], current_prediction[1]
    cv2.line(frame, (lmx, lmy), (cmx, cmy), (0,100,0))
    cv2.line(frame, (lpx, lpy), (cpx, cpy), (0,0,200))


cv2.namedWindow("kalman_tracker")
cv2.setMouseCallback("kalman_tracker", mousemove);

'''
cv2.KalmanFilter([dynamParams, measureParams[, controlParams[, type]]]) → <KalmanFilter object>

Parameters:	
    dynamParams – Dimensionality of the state.
    measureParams – Dimensionality of the measurement.
    controlParams – Dimensionality of the control vector.
    type – Type of the created matrices that should be CV_32F or CV_64F.

The class implements a standard Kalman filter http://en.wikipedia.org/wiki/Kalman_filter, [Welch95]. However, you can modify transitionMatrix, controlMatrix, and measurementMatrix to get an extended Kalman filter functionality.
See the OpenCV sample kalman.cpp .
'''
#创建卡尔曼滤波器
kalman = cv2.KalmanFilter(4,2,1)

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.03

while True:
    cv2.imshow("kalman_tracker", frame)
    if cv2.waitKey(100) & 0xff == ord("q"): 
        break
    if cv2.waitKey(100) & 0xff == ord("q"): 
        cv2.imwrite('kalman.jpg', frame)        
        break

cv2.destroyAllWindows()

2. 实验结果

由于卡尔曼滤波算法的精度不是特高,因此,实际应用中,将其和CAMShift()算法相结合来获得更高的准确度和性能。

注意:本站所有文章除特别说明外,均为原创,转载请务必以超链接方式并注明作者出处。