-
静止背景下的多目标追踪
< br>随着计算机技术以及智能汽车行业的发展,
多目标的检测与追踪的实用性与
研究价值逐渐提高。
在计算机视觉的三层结构中,
目标跟踪属于中间层,
是其他
高层任务,例如动作识别以及
行为分析等的基础。其主要应用可包括视频监控,
检测异常行为人机交互,
对复杂场景中目标交互的识别与处理,
以及虚拟现实及
医学图像。
目标跟踪又包括单目标跟踪和多目标跟踪。
p>
单目标跟踪可以通过目标的表观
建模或者运动建模,以处理光照、形
变、遮挡等问题,而多目标跟踪问题则更加
复杂,
除了单目标跟
踪回遇到的问题外,
还需要目标间的关联匹配。
另外在多目
p>
标跟踪任务中经常会碰到
目标的频繁遮挡
、
轨迹开始终止时刻未知、
目标太小、
表观相似、目标间交互、低帧率等等问题。
静止背景下的多目标追踪可分为两步来实现,
第一步是在视频文件的每帧中
p>
检测出移动的目标,
第二步是将检测到的目标与跟踪轨迹实时匹配。
在本次实验
中,
利用混合高斯模型进行
背景减除,
使用形态学操作消除噪声,
通过卡尔曼滤
波预测目标位置,
最后利用匈牙利算法进行匹配,
实现静止背景下的多目标追踪。
1
实验原理
1.1
混合高斯模型
单高斯模型是利用高维高斯分布概率来进行模式分类:
x
N
(
)
?
C
1
exp[
?
(x
?
?
)
T
?
?
1
(x
?
?
< br>)]
2
2
?
|
?
|
1
其中
?
用训练样本均值代替,
?
用样本方差代替,
X
为
d
维的样本向量。通过高
斯概率公
式就可以得出类别
C
属于正(负)样本的概率。
而混合高斯模型就是数据从多个高斯分布中产生,每个
GMM
由
k
个单高斯
分布线性叠加而成。
相当于对各个高斯分布进行加权,
权系数越大,
那么这个数
据属于这个高斯分布的可能性越大。<
/p>
P
(x)
?<
/p>
?
p
(k)*p(x
|
k)
利用混合高斯模型
(GMM)
可以进行背景减除,将前后景分离,得到移动的目
标。
对每个像素点建立由
k
个单高斯模型线性叠加而成的模型,
在这些混合高斯
背景模
型中,
认为像素之间的颜色信息互不相关,
对各像素点的处理都
是相互独
立的。单个像素点在
t
时刻服
从混合高斯分布概率密度函数:
k
p
(x
t
)
?<
/p>
?
w
i
,
t
?
(x
t
,
?
i
,
t
,
?
i
< br>,
t
)
i
?
1
?
(
x
t
,
?
i<
/p>
,
t
,
?
i
,
t
)
为
t
时刻第
i
个高斯分布,
?
i
,
p>
t
为其均值,
?
i
,
t
其中
k<
/p>
为分布模式总数,
为其协方差矩阵。
<
/p>
在获得新一帧图像后更新混合高斯模型。
用图像中的每个像素点与
混合高斯
模型匹配
,
如果成功则判定该
点为背景点
,
否则为前景点。
当背景
更新完成后,
高
1
斯模型与背景相关程度越大,
标准差就越小,
权值越大
。
按照权值与标准差的比
值从大到小进行排序,取前
B
个模型作为背景。
?
?
b
?
?
p>
B
?
arg
?
p>
min
?
?
w
p>
k
?
T
?
?
?
k
?
1
?
?
< br>?
1.2
卡尔曼滤波
卡尔曼滤波是一种利用线
性系统状态方程,通过系统输入输出观测数据,对
系统状态进行最优估计的算法。
其核心思想是,
根据当前的测量值、
上一时间
的
预测值以及误差,计算得到当前值,并可以持续预测下一时间的值。
< br>
试验中利用卡尔曼滤波计算并预测每个轨迹在下一帧中的位置,
建立帧间轨
迹的关系。
卡尔曼滤波将跟踪分为
5
种状态:
新目标出现、
目标匹配、
目标遮挡、
目标分离以及目标消失。其状态方程如
下所示
:
X
(k
?
1)
?
A
(k
?
1,
k
)
X
(k)
?
c
(k)
X
(k)
?
[x(k),
y(k),<
/p>
w(k),
h(k),
v(k)]
其中
x,y,w,h
分别表示目标外接矩形的
横纵坐标以及长、宽,
c(k),
v
(
k)
为不相关
的高斯白噪声。
定义其观测方程为
Z
(k)
< br>?
H(k)
X(k)
?
v
(k)
。
定义好了观测方程与状态方程之后就可以用卡尔曼滤波器实现运动目标的
跟踪,步骤如下:
1
)计算运动目标
的特征信息(运动质心,以及外接矩形)。
2
)用得到的特征信息初始化卡尔曼滤波器。
3
)用卡尔曼滤波器对下一帧中对应的目标区域进行预测,当下一帧到来时,在
< br>预测区域内进行目标匹配。
4
)如果匹配成功,则更新卡尔曼滤波器。
1.3
匈牙利匹配算法
匈牙利匹配算法是一种利用增广路径求取二分图最大匹配的算法。
匈牙利树
一般由宽度优先搜索(
BFS
)构成。
从一个未匹配点出发运行
BFS
,且
必须走交
替路,直至不能再扩展为止。交替路指的是,从一个未匹配点出发,依次经过非
匹配边、匹配边
...
循环往复,形成
的路径称为交替路。
示意图如图
1<
/p>
所示:
2
图
1
匈牙利树匹配
匈牙利算法的要点如下:
1
)从左边第一个顶点开始,挑选未匹配点进行搜索,寻找增广路。
p>
2
)如果经过一个未匹配点,则寻找成功。更新路径信息,匹配变数
+1
,停
止搜索。
3
)
如果一直没有找到增广路,
则不再从这个点开始搜索。
4
)找到
增广路之后需要沿着路径更新匹配,通过
prev
数组来记录路径上的
点。
在实验中,
用匈牙利算法将新一帧图片中检测到的运动物体匹配到对应的轨
迹。
匹配的过程是通过最小化卡尔曼预测得到的质心与检测到的
质心之间的欧氏
距离之和实现的。
通
过卡尔曼滤波计算并预测每个轨迹在下一帧中的位置,
然后计算预测的轨
迹位置和每个新检测到的目标之间的欧几里得距离,
将度量结果作为损失函数矩
阵。损失矩阵的大小为(
M,N
),其
中
M
是轨迹数目,
N
< br>是检测到的运动物体数
目。
2
实验内容
2.1
目标检测
< br>要实现目标检测,首先利用混合高斯模型区分前景背景。通过调用函数
oundD
etector
设置检测子为混合高斯模型,其中参数分别为高斯
核数目、训练背景帧数以及背景阈值。函数的返回值为一个二进制掩码,其中
1
的像素值对应前景,
0
的像素值对应背景。在
实验中,选取前
150
帧图像作为背
景
帧,并设置阈值为
0.6
,高斯核数目为
3
。
完成背景减除后,
通过设置
blob
分析子来寻找连通域,
函数设置的参数为最
小区域面积,返回值为目标面积、质心和边界框。实
验中,设置最小区域面积为
400
,代码如下所示:
or =
oundDetector(
'NumGaussians'
,
3,
...
'NumTrainingFrames'
,
150,
'MinimumBackgroundRatio'
,
0.6);
alyser = alysis(
'BoundingBoxOutputPort'
,
true,
'AreaOutputPort'
, true,
'CentroidOutputPort'
, true,
'MinimumBlobArea'
, 400);
完成混合高斯混合模型以及
blob
分析子后
,逐帧读取视频,为后续目标检
测以及追踪的过程做准备:
frame = ();
3
在检测目标的过程中,利用形态
学运算中的开运算以及闭运算可以消除噪
声,使目标检测更为准确。开运算是通过先腐蚀
再膨胀,去除孤立的像素点、总
的位置和结构不变。
而闭运算是
先膨胀再腐蚀,
弥合小裂缝,
而总的位置和形状
不变,通过填充图像的凹角来滤波图像。其效果如图
2
所展示:
图
2.1
原始像素点
图
2.2
开运算效果图
图
2.3
闭运算效果图
图
2
形态学运算效果图
实验中,首先使用检测子,即混合高斯模型得到前景图,对前景图使用
8*8<
/p>
矩形进行开运算,
切断临近物体间的联系。
再使用
15*15
矩形进行闭运算,
消除
细小物体,最后填补物体中间的空洞。滤除噪声后,使用
b
lob
分析得到所有连
通域的中心以及边界框的大小。代码如下
所示:
function
[centroids, bboxes,
mask] = detectObjects(frame)
% Detect
foreground.
mask =
(frame);
%
Apply
morphological
operations
to
remove
noise
and
fill
in
holes.
mask = imopen(mask,
strel(
'rectangle'
,
[8,8]));
mask =
imclose(mask,
strel(
'rectangle'
,
[15,15]));
mask =
imfill(mask,
'holes'
);
% Perform blob
analysis to find connected components.
[~, centroids, bboxes] =
(mask);
end
视
频中对移动目标的检测结果如图
3.1,
图
3.2
所示:
4
图
3.1
移动目标检测结果
1
图
3.2
移动目标检测结果
2
2.2
目标跟踪
要进行目标跟踪,首先需要
进行轨迹初始化,通过函数
initializeTracks()
来进
行初始化,每一个轨迹代表视频中一个移动的目标。轨迹的结构包含如下信息:
1)
ID
,轨迹编号;
2)
Bbox
,目标的边界框;
3)
kalmanFilter
p>
,用于预测目标位置的卡尔曼滤波器;
4)
Age
,目标被检测到的总帧数;
5)
totalVisibleCo
unt
,目标可被检测到的全部帧数;
6)
consecutiveInv
isibleCount
:连续未检测到目标的帧数。
代码如下所示:
function
tracks =
initializeTracks()
% create an empty array of
tracks
tracks =
struct(
...
'id'
, {},
...
'bbox'
, {},
...
'kalmanFilter'
, {},
...
'age'
, {},
...
'totalVisibleCount'
, {},
...
'consecutiveInvisibleCount'
,
{});
end
5
为消除噪声对目标追踪的影响,仅在
totalVisible
Count
超过阈值时才显示目
标的轨迹。
当连续几帧没有检测到与跟踪相关的信息时,
则假设该对象已经离开
了可视图画面。
通过参数
consecutivein
visiblecount
可判断这种情况,
当其超过阈
值时,删除跟踪轨迹。如果跟踪时间较短,并且在大多数帧中标记为不可见,那
么轨迹也可能作为噪声被删除。
轨迹初始化完成后,
通过卡尔曼滤波计算并预测每个轨迹在下一帧的位置,
函数输出为边框预测中心。
然后调整目标边界框的位置,
使其中心到达预测位置,
并将结果作为轨迹的跟踪矩形框,代码如下所示:
function
predictNewLocationsOfTracks()
for
i =
1:length(tracks)
bbox = tracks(i).bbox;
% Predict the current location of the
track.
predictedCentroid =
predict(tracks(i).kalmanFilter);
%
根据以前的轨迹,预测当前位置
% Shift the
bounding box so that its center is at
% the predicted
location.
predictedCentroid
=
int32(predictedCentroid)
-
bbox(3:4)
/
2;
tracks(i).bbox = [predictedCentroid,
bbox(3:4)];
end
end
完成位置预测后,创建损失函
数矩阵,航代表轨迹,列代表检测到的目标。
损失矩阵的大小为(
M,N
),其中
M
是轨迹数目,
p>
N
是检测到的运动物体数目。
对每个轨迹计
算其卡尔曼滤波预测的轨迹位置和每个新检测到的目标之间的欧
几里得距离,将度量结果
作为损失函数矩阵。
function
[assignments,
unassignedTracks, unassignedDetections] =
...
detectionToTrackAssignment()
nTracks =
length(tracks);
nDetections = size(centroids, 1);
% Compute the cost
of assigning each detection to each
track.
cost =
zeros(nTracks, nDetections);
for
i =
1:nTracks
cost(i, :) = distance(tracks(i).kalmanFilter,
centroids);
end
通过函数
assignDetectionsToTracks(cost, costOfNonAssignme nt)
利用匈牙利匹
配算法将新一帧图片中检测到的运动物体匹
配到对应的轨迹。
其中输入的参数为
损失矩阵以及阈值,
低于阈值时,
取消匹配。
返回值为匹配的结果
以及未匹配成
功的轨迹以及目标。
完
成匹配后,对已分配的轨迹,将其更新至当前帧目标所在位置,对未分配
的轨迹,增加其
连续不可见帧数。设置两个阈值,
invisibleForLong
< br>代表当连续不
可见帧数大于它时,删除轨迹;
ageTh
reshold
代表当总出现帧数小于它时,当该
参数与总可见
帧数的比值小于
0.6
时,删除轨迹。
目标检测与轨迹跟踪的操作循环进行,直至视频结束,显示最终跟踪结果。
6