https://www.mathworks.com/help/vision/examples/using-kalman-filter-for-object-tracking.html:由该例整理而来。
1、前言
本文所举例子说明了如何使用vision.KalmanFilter 对象和configureKalmanFilter函数来跟踪目标。示例以函数名形式显示,其函数内容在最后。
function kalmanFilterForTracking
2、介绍
卡尔曼滤波器有很多用处,包括控制,导航,计算机视觉和时间序列计量经济学。这个例子解释了怎样使用卡尔曼滤波器用于目标跟踪,并致力于三个重要的特征:
- 目标未来位置的预测;
- 减少不准确检测引入的噪声;
- 促进多个对象与其轨迹相关联的过程。
3、目标跟踪的挑战
在显示卡尔曼滤波器的使用之前,让我们先看看视频中的跟踪对象。 以下视频显示了一个绿球在地板上从左向右移动。
showDetections();
球上高亮的白色像素是由 vision.ForegroundDetector检测得到的,这个函数可以从背景中分离移动的目标,背景减法因为球和地板的低对比度使得只能检测到球的一部分,不理想并且引入噪声。
把所有帧叠加到单幅图片上,可视化检测到的轨迹如下。
这样的检测结果可以看出两个问题:
- 区域中心不同于球的中心,说明检测有误差。
- 球被方框遮挡时,检测不到了。
但是,这两个挑战都可以被卡尔曼滤波器解决。
4、使用卡尔曼滤波器跟踪单个目标
使用之前展示的视频,trackSingleObject如下做法:
1. 通过使用configureKalmanFilter创建vision.KalmanFilter。
2. 使用序列中的predict和correct方法消除跟踪系统中存在的噪声。
3. 当球被遮挡时,使用预测方法估计球的位置。
参数选择可以调整,configureKalmanFilter函数可以简化问题,细节性的问题可以看最后的函数内容。
trackSingleObject函数包含了嵌套的辅助函数,下面的全局变量用于在子函数之间传输数据。
frame = []; % 视频帧
detectedLocation = []; % 检测到的位置
trackedLocation = []; % 跟踪到的位置
label = ''; % 球的标签
utilities = []; % 处理视频的实例
跟踪单个目标的步骤如下:
function trackSingleObject(param)
% 创建用于读取视频,检测移动对象和显示结果的实用程序。 utilities = createUtilities(param);
isTrackInitialized = false;
while ~isDone(utilities.videoReader)
frame = readFrame();
% 检测球
[detectedLocation, isObjectDetected] = detectObject(frame);
if ~isTrackInitialized
if isObjectDetected
% 当球第一次被检测到时,通过创建一个卡尔曼滤波器初始化一个跟踪器。
initialLocation = computeInitialLocation(param, detectedLocation);
kalmanFilter = configureKalmanFilter(param.motionModel, ...
initialLocation, param.initialEstimateError, ...
param.motionNoise, param.measurementNoise);
isTrackInitialized = true;
trackedLocation = correct(kalmanFilter, detectedLocation);
label = 'Initial';
else
trackedLocation = [];
label = '';
end
else
% 使用卡尔曼滤波器来跟踪球
if isObjectDetected