【车辆分类】基于matlab的视频中车辆跟踪监测分类算法仿真,包括背景差分与帧间差分以及形态学处理

本系统的主要算法流程如下所示:

    这里,采用下载的AVI文件作为测试文件,在MATLAB中通过如下语句来获得视频信息:

Obj       = mmreader(datas);

frameNum  = get(Obj,'NumberOfFrames');

      通过上述代码,就能实现AVI视频文件的获取,由于实际中,获取的视频往往存在一定的噪声干扰,所以在使用测试视频的时候,如果测试视频是较为清晰的视频文件,那么我们需要对其人为的加入噪声,来模拟实际情况。

其仿真效果如下所示:

 

图2 加入噪声以后的测试视频

    如图1可以看到,当加入噪声之后的效果更符合实际摄像机得到的视频效果,本系统后面的算法都将基于这个效果进行设计实现。

    视频的预处理,主要分为以下几个步骤,将视频进行灰度处理,得到灰度视频,然后通过滤波得到较清晰的视频效果。通常情况下,对于一般非高斯噪声环境下,我们使用中值滤波进行处理。

中值滤波是一种典型的低通滤波器,属于非线性滤波技术,它的目的是保护图像边缘的同时去除噪声。所谓中值滤波,是指把以某点(x,y)为中心的小窗口内的所有象素的灰度按从大到小的顺序排列,若窗口中的象素为奇数个,则将中间值作为(x,y)处的灰度值。若窗口中的象素为偶数个,则取两个中间值的平均值作为(x,y)处的灰度值。中值滤波对去除椒盐噪声很有效。中值滤波的基本原理是把数字图像或数字序列中一点的值用该点的一个邻域中各点值的中值代替。

在实际使用窗口时,窗口的尺寸一般先用3X3再取5X5逐渐增大,直到其滤波效果满意为止。

对于这个部分,其matlab仿真代码:

      vedio_noise_rgb2(:,:,i) = rgb2gray(vedio_noise_rgb(:,:,:,i));

以上代码为灰度处理。

     vedio_noise_rgb3(:,:,i) = medfilt2(vedio_noise_rgb2(:,:,i),[filter_area filter_area]);

以上代为中值滤波。

    其仿真效果如下所示:

图3 灰度视频滤波之后的效果

      这个步骤的主要目的就是将获得的带噪声的视频信息处理成比较清晰的视频信息,以便算法的处理。

2.2 视频的背景提取

       在基于背景差分的运动车辆检测过程中,必须建立一种合适的背景更新模型才能准确、实时地提取出运动的车辆目标。

       这里我们采用的方法为帧平均算法,就是将一个时间段内的时间序列进行求和,然后求平均得到背景信息,这个是基于汽车在每个时间点内出现的概率远小于路面背景出现的概率来计算的,当然这种计算方法不适用于车辆及其拥堵的环境。在本系统,我们假设路面的车辆量是一个正常的水平。

       然后视频背景需要实时的更新,即当视频在时间上往后前进一帧,那么计算的序列需要自动的往后更新,根据这个原则,上面的式子可以变为如下的表达式:

 其中k为当前帧。

    这里提取背景的时间序列的长度根据时间环境变化来确定。显然,当时间序列长度越大,那么得到的背景就越清晰。

其仿真效果如下所示:

  

2.3 移动车辆的提取

       移动车辆的提取,是指将视频中的车辆提取,这里我们将综合考虑背景差分法和帧间差分法,背景差分法首先通过一定算法建立背景模型作为背景图像,然后用前景图像减去背景图像,得到前景图像和背景图像的差分图像。前景图像分为背景和运动物体两部分,在所求的差分图像中,前景图像的背景部分将对应差分图像的低灰度值部分,前景图像的运动目标对应差分图像的高灰度值部分。

        帧间差分法又称时间差分法,它基于相邻帧间像素差分的阈值化来提取视频图像中的运动目标。交通视频中的序列图像相邻帧之间时间间隔较短,帧间的差异主要体现为运动目标的变化。直接对连续的两帧图像做差并进行阈值化处理后,灰度没有发生变化的部分将被减掉,灰度发生变化的部分将被保留。

 

       在本系统,我们针对车辆提取,采用的方法是同时结合背景差分和帧间差分的方法进行的,该模块的仿真效果如下所示:

 

2.4 形态学处理

       从上面的仿真可以看到,受光照变化、摄像机抖动等影响,二值差分图像中会产生大量孤立噪声点,运动目标周围会出现不同程度的碎化现象,车辆的内部也会有不连续的零碎“孔洞”。差分图像阈值化处理可能会造成运动目标图像断裂。所以在视频分割之前必须对二值差分图像做去噪处理,以消除外界因素对分割精度的影响。

      因此,这个部分主要包括两个部分的处理:

      第一:形态学滤波,一些孤立的噪点进行滤波,得到一个完整的区域矩阵,如图5所示:

第二:合并,即将汽车中间的一些空洞以及部分汽车附近的非孤立噪点进行合并;

图6 临近区域的合并

    将这个方法引入到我们的车辆跟踪系统中,可以得到如下的仿真结果:

  

图7 心态学处理后的效果

从图7可以看到,通过心态学处理之后,图像中存在的噪点已经基本消除,然后某个汽车中的分裂的连通区域也已经合并在一起。

2.5车辆跟踪

    通过以上的处理,基本实现了车辆的提取,即视频中的白色部分,下面我们需要对车辆进行跟踪,获得每辆车辆的位置信息。

    每个车辆在形态学上可以认为是一个联通域,那么在MATLAB的图像处理中,就是计算每帧视频图像中的联通域的个数,在MATLAB中,我们通常使用bwlabel函数。

L = bwlabel(BW,n)

返回一个和BW大小相同的L矩阵,包含了标记了BW中每个连通区域的类别标签,这些标签的值为1、2、num(连通区域的个数)。n的值为4或8,表示是按4连通寻找区域,还是8连通寻找,默认为8。

其仿真效果如下所示:

  

(A) 第24帧效果

 

(B) 第48帧效果

 

(C) 第73帧效果

图8 汽车跟踪的仿真效果

从上面的仿真效果可以看到,汽车已经被白色的矩形框锁定住,这说明车辆已经被成功跟踪。

2.7 车辆特征的提取

图像特征是由于景物的物理和几何特征使图像中局部的灰度产生明显变化而形成的。图像当中存在视觉等一些特殊信息,通过这些信息我们能区分不同图像,对图像进行识别。图像特征的提取就是从图像中提取有用的信息和视觉特征。

通常提取的特征应该满足可区别性、可靠性、独立性和数量少四个特点:根据特定问题领域的性质,选择有明显区分意义的特征,是识别设计过程中非常关键的一步。为了提高车辆分类的速度和准确度,特征选择必须遵循“少”而“精”的原则。

在车辆分类领域,车辆的周长、面积、长宽高等几何特征易于提取,并且符合人类的视觉信息,因此本文选取这些特征对车辆进行分类。

    这里简单的使用汽车的面积作为对汽车进行分类的几何参数。具体的仿真结果在2.8节中给出。

2.8 车辆的计数和分类

车辆的计数问题,主要是利用了每一帧的连通域的数量,这在MATLAB中十分容易实现,使用bwlabel函数得到的n就是连通域的数量,然后通过排除面积较小的连通区域,其余连通域的数量就是该帧车辆的数目,通过仿真,我们可以得到本测试视频不同时间段的车辆数目如下所示:

图8 不同时间段的车辆数目

clc;
clear;
close all;

%备注,由于暂时无法获取CIF格式的视频文件,这里暂时用AVI替代,我们将认为的加入噪声和降低分别率,获得质量较差的视频信息来模拟实际得到的CIF视频。
%     .整个算法和视频格式无关,后期可以将修改读取视频格式的文件,实现功能。


%参数设置
%参数设置
ifnoise     = 1;              %是否人为的加入噪声,如果读入的视频是实际的视频,则ifnoise为0,不用加噪声,如果读入的视频是测试用的高清视频,则ifnoise为1,加入噪声
noise_level = 0.003;           %噪声大小
noise_type  = 'salt & pepper';%噪声类型
filter_area = 3;              %滤波参数

sel_area    = 200;            %最小车辆面积选择

sel_classify= 1;              %选择分类方法,1:为正常的门限分类方法,0:神经网络分类

%普通的分类方法主要根据面积法进行分类,但是仅限于固定视觉距离的环境
%摩托车: 白色框选定
%0,面积0以上,area1以下
%小型车: 紫色框选定
area1 = 700; %面积area1以上,area2以下
%中型车: 黄色框选定
area2 = 1200; %面积area2以上,area3以下
%大型车: 红色框选定
area3 = 2000;%面积area3以上



%Step1:读取视频文件
%Step1:读取视频文件
[Obj,frameNum_Original] = get_AVI('vedio\1.AVI');
%获得视频的帧数
start          = 2;%读取视频的起始位置
frameNum       = frameNum_Original; %需要处理视频的终点位置,如果视频过长,则需要对start和frameNum两个变量进行设置。
%获得视频的灰度信息
pixel_rgb      = vedio_op_rgb(Obj,start,frameNum);%获取处理视频
%对原来的视频添加噪声,来模拟实际的情况
vedio_noise_rgb = addnoise_rgb(ifnoise,pixel_rgb,noise_level,frameNum-start+1,noise_type);
%播放视频,为了运行速度,可以注释该语句
implay(pixel_rgb);
%implay(vedio_noise_rgb);
save mat/pixel_rgb.mat       pixel_rgb
save mat/vedio_noise_rgb.mat vedio_noise_rgb
clear pixel_rgb vedio_noise_rgb;
%******************end Step1***********************
%******************end Step1***********************



%Step2:视频的预处理
%Step2:视频的预处理
load mat/vedio_noise_rgb.mat
vedio_noise_rgb2 = huidu(vedio_noise_rgb,frameNum-start+1);%灰度处理
vedio_noise_rgb3 = filters(vedio_noise_rgb2,filter_area,frameNum-start+1);         %视频滤波
%播放视频,为了运行速度,可以注释该语句
%implay(vedio_noise_rgb2);
%implay(vedio_noise_rgb3);
save mat/vedio_noise_rgb2.mat vedio_noise_rgb2
save mat/vedio_noise_rgb3.mat vedio_noise_rgb3
clear vedio_noise_rgb2 vedio_noise_rgb3;
%******************end Step2***********************
%******************end Step2***********************


%Step3:移动物体的提取
%Step3:移动物体的提取
load mat/vedio_noise_rgb3.mat
cars = func_get_background(vedio_noise_rgb3);
% implay(cars);
save mat/cars.mat cars
clear vedio_noise_rgb3 cars;
%******************end Step3***********************
%******************end Step3***********************




%Step4:车辆跟踪
%Step4:车辆跟踪
load mat/cars.mat
load mat/vedio_noise_rgb.mat
pixel3          = vedio_process(cars);
pixel3          = vedio_process2(pixel3);
[pixel4,pixel5] = car_track(pixel3,sel_area);
pixel6          = car_track2(pixel4,vedio_noise_rgb);
save mat/pixel4.mat pixel4 
save mat/pixel5.mat pixel5 
save mat/pixel6.mat pixel6 
% implay(pixel3);
clear cars vedio_noise_rgb pixel3 pixel4 pixel5 pixel6
%******************end Step4***********************
%******************end Step4***********************



%Step5:车辆特征的提取与分类
%Step5:车辆特征的提取与分类
%备注:这里车辆分类我们按外形分为:摩托车,小型车,中型车,大型车四类型。

%摩托车: 白色框选定
%小型车: 紫色框选定
%中型车: 黄色框选定
%大型车: 红色框选定

%分类按汽车的车长,长高比分类。
%计算特征参数按特征参数进行分类

load mat/pixel5.mat
load mat/vedio_noise_rgb.mat

if sel_classify == 1
%正常的门限分类方法
[square,length,lwrate,pixel7] = func_feature_classify(pixel5,area1,area2,area3);
else
%根据神经网络进行分类  
%这个步骤需要训练数据,即实际你提供的视频中的场景中的所采集得到的车辆的特征参数进行训练,因此这里暂时不弄这个方法
end

msgbox('摩托车: 白色框;小型车: 紫色框;中型车: 黄色框;大型车: 红色框','白色区域为检测区域');

%显示分类结果
pixel8 = func_feature_classify2(pixel7,vedio_noise_rgb);
implay(pixel8);
%******************end Step5***********************
%******************end Step5***********************

A09-15

猜你喜欢

转载自blog.csdn.net/ccsss22/article/details/125755553