(OpenCV+Python)--目标跟踪,卡尔曼滤波+鼠标轨迹跟踪

卡尔曼是匈牙利数学家,Kalman滤波器源于其博士毕业了论文和1960年发表的论文《A New Approach to Linear Filtering and Prediction Problems》(线性滤波与预测问题的新方法)。
论文地址

卡尔曼滤波不要求信号和噪声都是平稳过程的假设条件。对于每个时刻的系统扰动和观测误差(即噪声),只要对它们的统计性质作某些适当的假定,通过对含有噪声的观测信号进行处理,就能在平均的意义上,求得误差为最小的真实信号的估计值。

因此,自从卡尔曼滤波理论问世以来,在通信系统、电力系统、航空航天、环境污染控制、工业控制、雷达信号处理等许多部门都得到了应用,取得了许多成功应用的成果。卡尔曼滤波器会对含有噪声的输入数据流(比如计算机视觉中的视频输入)进行递归操作,并产生底层系统状态(比如视频中的位置)在统计意义上的最优估计。


卡尔曼滤波算法分为两个阶段:
预测阶段:卡尔曼滤波器使用由当前点计算的协方差来估计目标的新位置;
更新阶段:卡尔曼滤波器记录目标的位置,并为下一次循环计算修正协方差。

整个卡尔曼滤波的过程就是个递推计算的过程,不断的“预测–更新–预测–更新……”


import cv2
import numpy as np

# 创建一个空帧,定义(700, 700, 3)画图区域
frame = np.zeros((700, 700, 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)]]) # 当前测量
    kalman.correct(current_measurement) # 用当前测量来校正卡尔曼滤波器
    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), (255, 0, 0)) # 蓝色线为测量值
    cv2.line(frame, (lpx, lpy), (cpx, cpy), (255, 0, 255)) # 粉色线为预测值

# 窗口初始化
cv2.namedWindow("kalman_tracker")

# opencv采用setMouseCallback函数处理鼠标事件,具体事件必须由回调(事件)函数的第一个参数来处理,该参数确定触发事件的类型(点击、移动等)
cv2.setMouseCallback("kalman_tracker", mousemove)

kalman = cv2.KalmanFilter(4, 2) # 4:状态数,包括(x,y,dx,dy)坐标及速度(每次移动的距离);2:观测量,能看到的是坐标值
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)
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'):
        break
cv2.destroyAllWindows()

这里写图片描述


一些学习资料:

  • 22
    点赞
  • 164
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
python-opencv中,可以使用KalmanFilter类对空间坐标进行卡尔曼滤波。下面是一个示例代码: ```python import cv2 import numpy as np # 定义一个2D的卡尔曼滤波kalman = cv2.KalmanFilter(4, 2) # 定义状态变量x和观测变量z x = np.zeros((4, 1), np.float32) # [x, y, dx/dt, dy/dt] z = np.zeros((2, 1), np.float32) # [x, y] # 定义状态转移矩阵A和观测矩阵H dt = 0.1 A = np.array([[1, 0, dt, 0], [0, 1, 0, dt], [0, 0, 1, 0], [0, 0, 0, 1]], np.float32) kalman.transitionMatrix = A H = np.array([[1, 0, 0, 0], [0, 1, 0, 0]], np.float32) kalman.measurementMatrix = H # 定义过程噪声协方差矩阵Q和观测噪声协方差矩阵R kalman.processNoiseCov = np.eye(4, dtype=np.float32) * 0.03 kalman.measurementNoiseCov = np.eye(2, dtype=np.float32) * 0.1 # 初始化状态变量x kalman.statePost = x # 定义观测数据 measurements = np.array([[10, 10], [20, 20], [30, 30], [40, 40], [50, 50]], np.float32) # 进行卡尔曼滤波 for i in range(len(measurements)): z = measurements[i].reshape((2, 1)) kalman.correct(z) x = kalman.predict() print("预测坐标:", x[0], x[1]) ``` 在上面的代码中,我们定义了一个2D的卡尔曼滤波器,然后定义了状态变量x和观测变量z。接着,我们定义了状态转移矩阵A和观测矩阵H,以及过程噪声协方差矩阵Q和观测噪声协方差矩阵R。最后,我们初始化了状态变量x,并定义了观测数据。在for循环中,我们使用correct()函数将观测数据进行滤波,然后使用predict()函数预测下一个状态。最后,我们输出了预测的坐标。
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值