【目标检测】基于帧差法+Vibe算法实现车辆行人检测matlab源码

本文介绍了视频中运动目标检测的两种方法:帧差分法和混合高斯建模。帧差分法包括两帧差分和三帧差分,适用于不同速度的目标检测,但易受光照变化影响。混合高斯建模则通过单高斯和多高斯模型来适应复杂背景变化,能更准确地识别目标。仿真代码展示了这两种方法在实际应用中的实现。
摘要由CSDN通过智能技术生成

一、帧差分法

    摄像机采集的视频序列具有连续性的特点。如果场景内没有运动目标,则连续帧的变化很微弱,如果存在运动目标,则连续的帧和帧之间会有明显地变化。

1.1  两帧差分法

    帧间差分法(Temporal Difference)就是借鉴了上述思想。由于场景中的目标在运动,目标的影像在不同图像帧中的位置不同。该类算法对时间上连续的两帧或三帧图像进行差分运算,不同帧对应的像素点相减,判断灰度差的绝对值,当绝对值超过一定阈值时,即可判断为运动目标,从而实现目标的检测功能。

                      

    两帧差分法的运算过程如图2-2所示。记视频序列中第n帧和第n−1帧图像为fnfn−1,两帧对应像素点的灰度值记为fn(x,y)和fn−1(x , y),按照式2.13将两帧图像对应像素点的灰度值进行相减,并取其绝对值,得到差分图像Dn

                                                                                  

    设定阈值T,按照式2.14逐个对像素点进行二值化处理,得到二值化图像Rn'。其中,灰度值为255的点即为前景(运动目标)点,灰度值为0的点即为背景点;对图像Rn'进行连通性分析,最终可得到含有完整运动目标的图像Rn

                                         

1.2 三帧差分法

    两帧差分法适用于目标运动较为缓慢的场景,当运动较快时,由于目标在相邻帧图像上的位置相差较大,两帧图像相减后并不能得到完整的运动目标,因此,人们在两帧差分法的基础上提出了三帧差分法。

            

   三帧差分法的运算过程如图2-3所示。记视频序列中第n+1帧、第n帧和第n−1帧的图像分别为fn+1、fnfn−1,三帧对应像素点的灰度值记为fn+1(x , y) 、fn(x , y) 和fn−1(x , y) , 按照式2.13分别得到差分图像Dn+1和Dn,对差分图像Dn+1和Dn按照式2.15进行与操作,得到图像Dn',然后再进行阈值处理、连通性分析,最终提取出运动目标。 

                   

    在帧间差分法中,阈值 的选择非常重要。如果阈值T选取的值太小,则无法抑制差分图像中的噪声;如果阈值T选取的值太大,又有可能掩盖差分图像中目标的部分信息;而且固定的阈值T无法适应场景中光线变化等情况。为此,有人提出了在判决条件中加入对整体光照敏感的添加项的方法,将判决条件修改为:

                               

    其中, A为待检测区域中像素的总数目,λ为光照的抑制系数,A可设为整帧图像。添加项表达了整帧图像中光照的变化情况。如果场景中的光照变化较小,则该项的值趋向于零;如果场景中的光照变化明显,则该项的值明显增大,导致式2.16右侧判决条件自适应地增大,最终的判决结果为没有运动目标,这样就有效地抑制了光线变化对运动目标检测结果的影响。

    图 2-5 是采用帧间差分法对自拍序列 lab 序列进行运动目标检测的实验结果,(b)图是采用两帧差分法的检测结果,(c)图是采用三帧差分法的检测结果。lab序列中的目标运动较快,在这种情况下,运动目标在不同图像帧内的位置明显不同,采用两帧差分法检测出的目标会出现“重影”的现象,采用三帧差分法,可以检测出较为完整的运动目标。

                

    综上所述,帧间差分法的原理简单,计算量小,能够快速检测出场景中的运动目标。但由实验结果可以看出,帧间差分法检测的目标不完整,内部含有“空洞”,这是因为运动目标在相邻帧之间的位置变化缓慢,目标内部在不同帧图像中相重叠的部分很难检测出来。帧间差分法通常不单独用在目标检测中,往往与其它的检测算法结合使用。

二、混合高斯建模法

高斯模型有单高斯模型(SGM)和混合高斯模型(GMM)两种。

(1)单高斯模型:

为简单起见,阈值t的选取一般靠经验值来设定。通常意义下,我们一般取t=0.7-0.75之间。

二维情况如下所示:

(2)混合高斯模型:

      对于(b)图所示的情况,很明显,单高斯模型是无法解决的。为了解决这个问题,人们提出了高斯混合模型(GMM),顾名思义,就是数据可以看作是从数个高斯分布中生成出来的。虽然我们可以用不同的分布来随意地构造 XX Mixture Model ,但是 GMM是 最为流行。另外,Mixture Model 本身其实也是可以变得任意复杂的,通过增加 Model 的个数,我们可以任意地逼近任何连续的概率密分布。

    每个 GMM 由 K 个 Gaussian 分布组成,每个 Gaussian 称为一个“Component”,这些 Component 线性加成在一起就组成了 GMM 的概率密度函数:

                (1)

其中,πk表示选中这个component部分的概率,我们也称其为加权系数。

根据上面的式子,如果我们要从 GMM 的分布中随机地取一个点的话,实际上可以分为两步:

(1)首先随机地在这 K 个 Component 之中选一个,每个 Component 被选中的概率实际上就是它的系数 πk,选中了 Component 之后,再单独地考虑从这个 Component 的分布中选取一个点就可以了──这里已经回到了普通的 Gaussian 分布,转化为了已知的问题。假设现在有 N 个数据点,我们认为这些数据点由某个GMM模型产生,现在我们要需要确定 πk,μk,σk 这些参数。很自然的,我们想到利用最大似然估计来确定这些参数,GMM的似然函数如下:

        (2)

在最大似然估计里面,由于我们的目的是把乘积的形式分解为求和的形式,即在等式的左右两边加上一个log函数,但是由上文博客里的(2)式可以看出,转化为log后,还有log(a+b)的形式,因此,要进一步求解。

三、仿真代码

function varargout = object_detect(varargin)
% OBJECT_DETECT MATLAB code for object_detect.fig
%      OBJECT_DETECT, by itself, creates a new OBJECT_DETECT or raises the existing
%      singleton*.
%
%      H = OBJECT_DETECT returns the handle to a new OBJECT_DETECT or the handle to
%      the existing singleton*.
%
%      OBJECT_DETECT('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in OBJECT_DETECT.M with the given input arguments.
%
%      OBJECT_DETECT('Property','Value',...) creates a new OBJECT_DETECT or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before object_detect_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to object_detect_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help object_detect

% Last Modified by GUIDE v2.5 16-May-2018 08:41:00

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @object_detect_OpeningFcn, ...
                   'gui_OutputFcn',  @object_detect_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before object_detect is made visible.
function object_detect_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to object_detect (see VARARGIN)

% Choose default command line output for object_detect
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes object_detect wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = object_detect_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename, pathname] = uigetfile({'*.avi'; '*.mp4'},'打开视频');
str = [pathname filename];
set(handles.edit1, 'String', str);



function edit1_Callback(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of edit1 as text
%        str2double(get(hObject,'String')) returns contents of edit1 as a double


% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to edit1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
videoName = get(handles.edit1, 'String');
videoSource = vision.VideoFileReader(videoName,...
    'ImageColorSpace', 'RGB', 'VideoOutputDataType', 'uint8');
videoInfo = info(videoSource);
videoRate = videoInfo.VideoFrameRate;
waitTime = 1.0/videoRate;
frame_last = rgb2gray(step(videoSource));
count = 1
global exit_flag;
global pause_flag;
exit_flag = false;
pause_flag = false;

while ~isDone(videoSource) && ~exit_flag
    if pause_flag
        uiwait(handles.figure1);
    end
    frame = step(videoSource);
    frame_now = rgb2gray(frame);
    frame_now = medfilt2(frame_now);
    frame_diff = abs(frame_now - frame_last);
    fgMask = imbinarize(frame_diff);
    fgMask = imopen(fgMask, strel('rectangle', [3, 3]));
    fgMask = imfill(fgMask, 'holes');
    frame_last = frame_now;
    axes(handles.axes1);
    imshow(frame);
    axes(handles.axes2);
    imshow(fgMask);
    pause(waitTime - 0.02);
    count = count + 1
end
release(videoSource);


% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global exit_flag;
exit_flag = true;


% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global pause_flag;
pause_flag = true;


% --- Executes on button press in pushbutton5.
function pushbutton5_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton5 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global pause_flag;
pause_flag = false;
uiresume(handles.figure1);


% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
videoName = get(handles.edit1, 'String');
videoSource = vision.VideoFileReader(videoName,...
    'ImageColorSpace', 'RGB', 'VideoOutputDataType', 'uint8');
videoInfo = info(videoSource);
videoRate = videoInfo.VideoFrameRate;
waitTime = 1.0/videoRate;
frame_first = rgb2gray(step(videoSource));
frame = step(videoSource);
global exit_flag;
global pause_flag;
exit_flag = false;
pause_flag = false;
while ~isDone(videoSource) && ~exit_flag
    if pause_flag
        uiwait(handles.figure1);
    end
    % 显示该帧图像
    axes(handles.axes1);
    imshow(frame);
    frame_second = rgb2gray(frame);
    frame = step(videoSource);
    frame_third = rgb2gray(frame);
    frame_diff1 = abs(frame_second - frame_first);
    frame_diff2 = abs(frame_third - frame_second);
    fgMask = imbinarize(min(frame_diff1,frame_diff2));
    fgMask = imopen(fgMask, strel('rectangle', [3, 3]));
    fgMask = imfill(fgMask, 'hole');
    frame_first = frame_second;
    axes(handles.axes2);
    imshow(fgMask);
    pause(waitTime - 0.02);
end
release(videoSource);


% --- Executes on button press in pushbutton7.
function pushbutton7_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton7 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close(gcf);


% --- Executes on button press in pushbutton8.
function pushbutton8_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
videoName = get(handles.edit1, 'String');
videoSource = vision.VideoFileReader(videoName,...
    'ImageColorSpace', 'RGB', 'VideoOutputDataType', 'uint8');
videoInfo = info(videoSource);
videoRate = videoInfo.VideoFrameRate;
waitTime = 1.0/videoRate;
global exit_flag;
global pause_flag;
exit_flag = false;
pause_flag = false;

            % 已经匹配,则不需要再进行优先级排序判定
            if match_ground
                fgMask(i, j) = 0;
                continue;
            end
            
            % 优先级排序
            rank = W(i, j, :) ./ sd(i, j, :);
            [~, rank_index] = sort(rank, 'descend');
            
            fgMask(i, j) = 0;
            k = 1;
            temp_T = 0;
            while (match == 0) && (temp_T < T)
                index = rank_index(k);
                if abs(u_dist(i, j, index) <= D * sd(i, j, index))
                    fgMask(i, j) = 0;
                    break;
                else
                    temp_T = temp_T + W(i, j, index);
                    fgMask(i, j) = 255;
                end
                k = k + 1;
            end
        end
    end
        
    % 使用混合高斯背景建模
    fgMask = logical(fgMask);
    fgMask = imdilate(imerode(fgMask, disk1), disk2);
    axes(handles.axes1);
    imshow(frame);
    axes(handles.axes2);
    imshow(fgMask);
    drawnow;
    
    frame_count = frame_count + 1
end
release(videoSource);

% videoName = get(handles.edit1, 'String');
% videoSource = vision.VideoFileReader(videoName,...
%     'ImageColorSpace', 'RGB', 'VideoOutputDataType', 'uint8');
% detector = vision.ForegroundDetector(...
%     'NumTrainingFrames', 5, ...
%     'InitialVariance', 30 * 30);
% videoInfo = info(videoSource);
% videoRate = videoInfo.VideoFrameRate;
% waitTime = 1.0/videoRate;
% global exit_flag;
% global pause_flag;
% exit_flag = false;
% pause_flag = false;
% 
% while ~isDone(videoSource) && ~exit_flag
%     if pause_flag
%         uiwait(handles.figure1);
%     end
%     frame = step(videoSource);
%     frame_now = rgb2gray(frame);
%     fgMask = step(detector, frame_now);
%     fgMask = imopen(fgMask, strel('rectangle', [3, 3]));
%     fgMask = imfill(fgMask, 'holes');
%     axes(handles.axes1);
%     imshow(frame);
%     axes(handles.axes2);
%     imshow(fgMask);
%     pause(waitTime - 0.02);
% end
% release(detector);
% release(videoSource);


% --- Executes on button press in pushbutton9.
function pushbutton9_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton9 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
videoName = get(handles.edit1, 'String');
videoSource = vision.VideoFileReader(videoName,...
    'ImageColorSpace', 'RGB', 'VideoOutputDataType', 'uint8');
videoInfo = info(videoSource);

% 参数设置
sample_num = 10;                % 样本库
match_thres = 20;               % 匹配阈值
match_num = 2;                  % 最小匹配数
update_factor = 1;              % 一开始50帧内采用该更新因
next_update_factor = 5;         % 50帧以后的更新因子
cols = videoInfo.VideoSize(1);  % 图像的宽度
rows = videoInfo.VideoSize(2);  % 图像的高度
fore_thres = 20;                % 前景阈值
frame_count = 0;                % 处理帧数
neighbor = [1, 0, -1, -1, 1, 0, 0, -1, 1];  % 邻域选择
% 外部控制标记
global exit_flag;
global pause_flag;
exit_flag = false;
pause_flag = false;
% 判断是否为第一帧
first_flag = true;
while ~isDone(videoSource) && ~exit_flag
    if pause_flag
        uiwait(handles.figure1);
    end
    
    frame = step(videoSource);
    frame_gray = double(rgb2gray(frame));
    if first_flag
        first_flag = false;
        %% 开始初始化
        samples = cell(1, sample_num);
        % 前两个样本设置初始像素
        samples{1} = frame_gray;
        samples{2} = frame_gray;
        % 剩下的样本初始化
        for i = 3:sample_num
            samples{i} = frame_gray + double(floor(rand(rows, cols) * 20) - 10);
        end
        
        fore_count = uint8(zeros(rows, cols));
        frame_count = frame_count + 1
        % 初始化结束
        continue
    end
    
    %% 前景分割
    fgMask = uint8(ones(rows, cols) * match_num);
    for i = 1:sample_num
        distance = uint8(abs(samples{i} - frame_gray) <= match_thres);
        fgMask = fgMask - distance;
    end
    fgMask = logical(fgMask * 255);
    % 更新前景计数
    for r = 1 : rows
        for c = 1:cols
            if fgMask(r, c) == 1
                fore_count(r, c) = fore_count(r, c) + 1;
                if fore_count(r, c) >= fore_thres
                    fore_count(r,c) = 0;
                    fgMask(r, c) = 0;
                end
            else
                fore_count(r, c) = 0;
            end
        end
    end
    updateMask = fgMask;
    updateMask = imfill(updateMask, 'hole');
 ;
    imshow(fgMask);
    drawnow;
end
release(videoSource);

四、仿真结果

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Matlab科研辅导帮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值