如何使用卡尔曼滤波(Kalman Filtering)实现对物体运动轨迹的预测?(附源码)

OpenCV杂谈_13


一. 什么是卡尔曼滤波?它的用途又是什么?以及它有什么拓展?

  1. 卡尔曼滤波(Kalman filtering, KF)是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。
  2. 卡尔曼滤波的一个典型实例是从一组有限的,对物体位置的,包含噪声的观察序列中预测出物体的坐标位置及速度。在很多工程应用(雷达、计算机视觉)中都可以找到它的身影。同时,卡尔曼滤波也是控制理论以及控制系统工程中的一个重要话题。
  3. 为了解决普通KF仅能处理线性数据的问题,从而就有了用于解决非线性数据的基于KF的推展:拓展卡尔曼滤波(EKF)和无迹卡尔曼滤波(UKF)。KF主要应用于系统方程和量测方程为线性的的场景,EKF应用于轻度非线性场景,而UKF则在强非线性情况下有更好的表现。

二. 环境配置

  1. Python版本:3.7
  2. 功能包:opencv-python(4.5.3.56)、 numpy (1.21.1)
  3. 文件夹配置:
    bydemo

三. 使用简单的线性数据做预测实验

讲解:通过以下两个.py文件,简单实现了对随机点位置的预测,结果展示中红色的点代表着手动录入的点,白色的圈则是根据已给出的红色点进行的卡尔曼滤波预测,黑色的圈则是根据白色的圈进行的卡尔曼滤波预测。

  1. klamanfilter.py
import cv2
import numpy as np


class KalmanFilter:
    kf = cv2.KalmanFilter(4, 2)
    kf.measurementMatrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32)
    kf.transitionMatrix = np.array([[1, 0, 1, 0], [0, 1, 0, 1], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32)

    def predict(self, coordX, coordY):
        '''This function estimates the position of the object'''
        measured = np.array([[np.float32(coordX)], [np.float32(coordY)]])
        self.kf.correct(measured)
        predicted = self.kf.predict()
        x, y = int(predicted[0]), int(predicted[1])
        return x, y
  1. main.py
"""用一个实例代码讲述一下什么是卡尔曼滤波器其本质其实就是用来预测之后物体的运动位置"""

from kalmanfilter import KalmanFilter
import cv2

# 初始化 Kalman 滤波器
kf = KalmanFilter()

img = cv2.imread("background.png")
img = cv2.resize(img, (1280, 720))

ball_positions = [(4, 300), (61, 256), (116, 214), (170, 180), (225, 148), (279, 120), (332, 97),
         (383, 80), (434, 66), (484, 55), (535, 49), (586, 49), (634, 50),
         (683, 58), (731, 69), (778, 82), (824, 101), (870, 124), (917, 148),
         (962, 169), (1006, 212), (1051, 249), (1093, 290)]

for pt in ball_positions:  # 先用之前规定好的点预测出第一个预测点
    cv2.circle(img, pt, 5, (0, 0, 255), -1)

    predicted = kf.predict(pt[0], pt[1])
    cv2.circle(img, predicted, 5, (255, 255, 255), 4)

for i in range(10):  # 用预测出的第一个预测点作为新预测点的评估对象,得出第二个预测点,之后再将第二个预测点作为第三个预测点的评估对象,得到第三个预测点,反反复复得到十个预测点
    predicted = kf.predict(predicted[0], predicted[1])
    cv2.circle(img, predicted, 5, (0, 0, 0), 4)

cv2.imshow("Img", img)
cv2.waitKey(0)

结果展示:
bydemo

四. 卡尔曼滤波器在真实世界中的使用

  1. 对抛出橘子的运动轨迹预测:图中蓝色框表示的是对橘子的识别后生成的bounding box,蓝色的点表示的是bounding box的中心点,黑色的圈表示的是对橘子在图像下一帧中的运动轨迹的预测。
    bydemo
  2. 对路上行人的运动轨迹预测:图中蓝色框表示的是对人体的识别后生成的bounding box,蓝色的点表示的是bounding box的中心点,黑色的圈表示的是对人体在图像下一帧中的运动轨迹的预测。

bydemo

五. 感悟与分享

  1. 在文章的第四部分分别对符合自由落体规律的橘子以及毫无规律可言的人的运动轨迹进行了基于普通卡尔曼滤波的轨迹预测,可见在预测精确度上有着明显的差异,换句话说就是,普通卡尔曼滤波在对有规律可言的线性数据进行预测时有着不错的表现,但对于毫无规律可言的非线性数据进行预测时,其精度表现差强人意。
  2. 分享:
    1. 百度百科 – – 卡尔曼滤波
    2. 浅谈卡尔曼滤波
    3. 详解卡尔曼滤波
  3. 代码参考:Predict trajectory of an Object with Kalman filter(内容为英文)

如有问题,敬请指正。欢迎转载,但请注明出处。

来源:Demo_xxx

物联沃分享整理
物联沃-IOTWORD物联网 » 如何使用卡尔曼滤波(Kalman Filtering)实现对物体运动轨迹的预测?(附源码)

发表评论