目录
1. 简介
车辆跟踪是计算机视觉领域中的重要应用,旨在实时追踪道路上运动的车辆,以提供交通监控、自动驾驶、交通流量统计等服务。光流法是一种常用的车辆跟踪方法之一,而基于HS光流法的车辆跟踪则是在HS光流法的基础上进行的车辆目标跟踪技术。
2. HS光流法
HS光流法(Horn-Schunck Optical Flow)是由B.K.P. Horn和B. Schunck在1981年提出的计算光流的方法。它假设在一个局部窗口内,图像像素的光强度在时间上保持不变,基于该假设构建了一个能量函数并通过最小化能量函数来求解光流场。
2.1 光流场的表示
在一个平面运动的情况下,图像上的一个像素点$(x, y)$在时间间隔$\Delta t$内的位移可以用光流向量$(u, v)$来表示,其中$(u, v)$分别表示$x$方向和$y$方向的位移。光流场即为图像上每个像素点的光流向量。
2.2 HS光流法原理
在HS光流法中,假设光流场$(u, v)$在整个图像区域上是连续的,光流向量$(u, v)$在整个图像上的变化尽可能小。基于这个假设,构建HS能量函数如下:
其中,$I_x, I_y$是图像在$x, y$方向上的梯度,$I_t$是图像在时间上的变化率,$(u_x, u_y)$和$(v_x, v_y)$是$u$和$v$在$x, y$方向上的梯度,$\lambda$是平滑参数。最小化能量函数$E(u, v)$,可以得到整个图像区域上的光流场$(u, v)$。
3. 基于HS光流法的车辆跟踪
基于HS光流法的车辆跟踪流程如下:
3.1 预处理
对于输入的视频序列,首先进行预处理,包括图像去噪、灰度化等操作。去噪操作可以采用高斯滤波或中值滤波等方法,以减少图像中的噪声。
3.2 光流场计算
对预处理后的图像序列,利用HS光流法计算光流场。将相邻两帧图像视为两个时间间隔,通过最小化HS能量函数,计算出整个图像区域上的光流场$(u, v)$。
3.3 目标检测
在光流场中,车辆通常会表现为明显的运动区域。可以通过阈值化、边缘检测等方法来提取运动区域,以实现目标检测。
3.4 跟踪与更新
对于每个检测到的运动区域,使用目标跟踪算法进行跟踪。常用的跟踪算法包括卡尔曼滤波、基于模板匹配的方法等。跟踪过程中,根据新的光流场信息,更新目标的位置和速度。
3.5 目标输出
在整个视频序列中,持续跟踪并更新车辆的位置和运动信息。最终输出跟踪结果,可视化显示车辆在视频中的运动轨迹。
4. 仿真效果
................................................................
% 循环处理视频每一帧,直到文件结束
while ~isDone(Vedioh)
% 从视频文件中读取视频帧
frame = step(Vedioh);
% 将图像转换为灰度图
gray = rgb2gray(frame);
%1 计算光流场矢量,返回一个复数矩阵,分别代表每个像素点u和v
flow = estimateFlow(hFlow,gray);
% 每隔5行5列选择一个像素点,绘制它的光流图,20表示将光流幅值放大20倍
% lines每行对应一条曲线,分别是第1和2个点的x,y坐标
lines = [xpos, ypos, xpos+20*real(flow.Vx(locs)), ypos+20*imag(flow.Vy(locs))];
% 将光流矢量添加到视频帧上
vector = step(hShape2, frame, lines);
%2 光流矢量幅值
magnitude = flow.Magnitude;
% 计算光流幅值平均值,表征速度阀值
threshold = 0.5 * step(hMean2, step(hMean1, magnitude));
% 使用阀值分割提取运动对象,然后滤波去噪
carobj = magnitude >= threshold;
carobj = imfilter(carobj, hFilter, 'replicate');
% 通过形态学腐蚀去掉道路,然后形态学关闭填补BLOB(汽车)孔洞
carobj = imerode(carobj, hErode);
carobj = imclose(carobj, hClose);
%3 统计估计BLOB(汽车)对象的面积area和边框bbox=[left,bottom,width,height]
[area, bbox] = step(hBlob, carobj);
% 只是统计过了杆的汽车,杆位置大约在帧图像的第22行
grow=22;
idx = bbox(:,1) > grow;
% 计算汽车面积和边框面积的百分比,bbox(k,3)*bbox(k,4)是第k个边框面积
ratio = zeros(length(idx), 1);
ratio(idx) = single(area(idx,1))./single(bbox(idx,3).*bbox(idx,4));
% 当面积百分比大于40%时认为是汽车,flag中为1的表示汽车
flag = ratio > 0.4;
% 统计视频帧中的汽车数量
count = int32(sum(flag));
bbox(~flag, :) = int32(-1);
% 添加汽车边框,用于显示被追踪到的汽车
result = step(hShape1, frame, bbox);
% 在处理结果视频帧上添加白色横杆
result(grow:grow+1,:,:) = 1;
% 显示汽车数量位置的背景设为黑色
result(1:15,1:30,:) = 0;
% 在视频帧添加文本显示汽车数量
result = insertText(result,[1 1],sprintf('%d',count));
%4 显示最后处理结果
step(hVideo1, frame); % 原始的视频帧
step(hVideo2, vector); % 绘制光流矢量
step(hVideo3, carobj); % 阀值分割结果
step(hVideo4, result); % 带框标示汽车
pause(0.01);
end
%% 释放视频对象
release(Vedioh);
up3007