m基于背景差法与GMM混合高斯模型结合的红外目标检测与跟踪算法matlab仿真

117 阅读4分钟

1.算法仿真效果

matlab2013b仿真结果如下:

 

普通视频:

1bb09b878cc59a6840aa329388287607_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.png

 红外视频:

 

18dd79c2d58e9e28b22efc6e163c5ade_watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=.png

 

2.算法涉及理论知识概要

       在Stauffer等人提出的自适应混合高斯背景模型基础上,为每个像素构建混合高斯背景模型,通过融入帧间差分把每帧中的图像区分为背景区域、背景显露区域和运动物体区域。相对于背景区域,背景显露区中的像素点将以大的更新率更新背景模型,使得长时间停滞物体由背景变成运动前景时,被遮挡的背景显露区被快速恢复。与Stauffer等人提出的方法不同的是,物体运动区不再构建新的高斯分布加入到混合高斯分布模型中,减弱了慢速运动物体对背景的影响。实验结果表明,在有诸多不确定性因素的序列视频中构建的背景有较好的自适应性,能迅速响应实际场景的变化。

 

       混合高斯模型使用K(基本为3到5个) 个高斯模型来表征图像中各个像素点的特征,在新一帧图像获得后更新混合高斯模型,用当前图像中的每个像素点与混合高斯模型匹配,如果成功则判定该点为背景点, 否则为前景点。通观整个高斯模型,他主要是有方差和均值两个参数决定,,对均值和方差的学习,采取不同的学习机制,将直接影响到模型的稳定性、精确性和收敛性。由于我们是对运动目标的背景提取建模,因此需要对高斯模型中方差和均值两个参数实时更新。为提高模型的学习能力,改进方法对均值和方差的更新采用不同的学习率;为提高在繁忙的场景下,大而慢的运动目标的检测效果,引入权值均值的概念,建立背景图像并实时更新,然后结合权值、权值均值和背景图像对像素点进行前景和背景的分类。具体更新公式如下:

3.jpeg

4.jpeg

5.jpeg

6.jpeg

 

       背景差分法是采用图像序列中的当前帧和背景参考模型比较来检测运动物体的一种方法,其性能依赖于所使用的背景建模技术。在基于背景差分方法的运动目标检测中,背景图像的建模和模拟的准确程度,直接影响到检测的效果。不论任何运动目标检测算法,都要尽可能的满足任何图像场景的处理要求,但是由于场景的复杂性、不可预知性、以及各种环境干扰和噪声的存在,如光照的突然变化、实际背景图像中有些物体的波动、摄像机的抖动、运动物体进出场景对原场景的影响等,使得背景的建模和模拟变得比较困难。背景差分法检测运动目标速度快,检测准确,易于实现,其关键是背景图像的获取。在实际应用中,静止背景是不易直接获得的,同时,由于背景图像的动态变化,需要通过视频序列的帧间信息来估计和恢复背景,即背景重建,所以要选择性的更新背景。

 

 

3.MATLAB核心程序 `Time1 = 0;

tic;

for tt = 1:round(frameNum_Original)

    disp('当前帧数');

    tt

    image = Temp(:,:,tt);

    for kk = 1:K   

        Datac         = double(Temp(:,:,tt))-reshape(Mus(:,kk,:),D,CRGB);

        Squared(:,kk) = sum((Datac.^ 2)./reshape(Sigmas(:,kk,:),D,CRGB),2);

    end

    [junk,index] = min(Squared,[],2);

    Gaussian                                                = zeros(size(Squared));

    Gaussian(sub2ind(size(Squared),1:length(index),index')) = ones(D,1);

    Gaussian                                                = Gaussian&(Squared<Deviation_sq);

    %参数更新

    Weights = (1-Alpha).*Weights+Alpha.*Gaussian;

    for kk = 1:K

        pixel_matched   = repmat(Gaussian(:,kk),1,CRGB);

        pixel_unmatched = abs(pixel_matched-1);

        Mu_kk           = reshape(Mus(:,kk,:),D,CRGB);

        Sigma_kk        = reshape(Sigmas(:,kk,:),D,CRGB);

        Mus(:,kk,:)     = pixel_unmatched.Mu_kk+pixel_matched.(((1-Rho).*Mu_kk)+(Rho.*double(image)));

        Mu_kk           = reshape(Mus(:,kk,:),D,CRGB);

        Sigmas(:,kk,:)  = pixel_unmatched.Sigma_kk+pixel_matched.(((1-Rho).Sigma_kk)+repmat((Rho. sum((double(image)-Mu_kk).^2,2)),1,CRGB));       

    end

    replaced_gaussian   = zeros(D,K);

    mismatched          = find(sum(Gaussian,2)==0);       

    for ii = 1:length(mismatched)

        [junk,index]                            = min(Weights(mismatched(ii),:)./sqrt(Sigmas(mismatched(ii),:,1)));

        replaced_gaussian(mismatched(ii),index) = 1;

        Mus(mismatched(ii),index,:)             = image(mismatched(ii),:);

        Sigmas(mismatched(ii),index,:)          = ones(1,CRGB)*Variance;

        Weights(mismatched(ii),index)           = Props;  

    end

    Weights         = Weights./repmat(sum(Weights,2),1,K);

    active_gaussian = Gaussian+replaced_gaussian;

    %背景分割

    [junk,index]    = sort(Weights./sqrt(Sigmas(:,:,1)),2,'descend');

    bg_gauss_good   = index(:,1);

    linear_index    = (index-1)*D+repmat([1:D]',1,K);

    weights_ordered = Weights(linear_index);

    for kk = 1:K

        Weight(:,kk)= sum(weights_ordered(:,1:kk),2);

    end

    bg_gauss(:,2:K) = Weight(:,1:(K-1)) < Back_Thresh;

    bg_gauss(:,1)   = 1;           

    bg_gauss(linear_index)     = bg_gauss;

    active_background_gaussian = active_gaussian & bg_gauss;

    foreground_pixels          = abs(sum(active_background_gaussian,2)-1);

    foreground_map             = reshape(sum(foreground_pixels,2),RR,CC);

    Images1(:,:,tt)            = foreground_map;   

    objects_map                = zeros(size(foreground_map),'int32');

    object_sizes               = [];

    Obj_pos                    = [];

    new_label                  = 1;

    %计算连通区域

    [label_map,num_labels]     = bwlabel(foreground_map,8);

    

    for label = 1:num_labels

       object      = (label_map == label);

       object_size = sum(sum(object));

       if(object_size >= Comp_Thresh)

          objects_map             = objects_map + int32(object * new_label);

          object_sizes(new_label) = object_size;

          [X,Y]                   = meshgrid(1:CC,1:RR);    

          object_x                = X.*object;

          object_y                = Y.*object;

          Obj_pos(:,new_label)    = [sum(sum(object_x)) / object_size;

                     sum(sum(object_y)) / object_size];

          new_label               = new_label + 1;

       end

    end

    num_objects = new_label - 1;

    %去除阴影

    index                       = sub2ind(size(Mus),reshape(repmat([1:D],CRGB,1),DCRGB,1),reshape(repmat(bg_gauss_good',CRGB,1),DCRGB,1),repmat([1:CRGB]',D,1));

    background                  = reshape(Mus(index),CRGB,D);

    background                  = reshape(background',RR,CC,CRGB);

    background                  = uint8(background);

    background_Update(:,:,:,tt) = background;

    background_hsv              = rgb2hsv(background);

    image_hsv                   = rgb2hsv(image_sequence(:,:,:,tt));

    for i = 1:RR

        for j = 1:CC      

            if (objects_map(i,j))&&...

               (abs(image_hsv(i,j,1)-background_hsv(i,j,1))<SHADOWS(1))&&...

               (image_hsv(i,j,2)-background_hsv(i,j,2)<SHADOWS(2))&&...

               (SHADOWS(3)<=image_hsv(i,j,3)/background_hsv(i,j,3)<=SHADOWS(4))

               Shadows(i,j) = 1;  

            else

               Shadows(i,j) = 0;  

            end               

        end    

    end

    Images0(:,:,tt)   = objects_map;

    objecs_adjust_map = Shadows;

    Images2(:,:,tt)   = objecs_adjust_map;    

    

    Images3(:,:,tt)= Images2(:,:,tt);

end

Time1 = toc/frameNum_Original;

msgbox(['视频每帧耗时:',num2str(Time1),'s']);

axes(handles.axes2)

imshow(uint8(background_Update(:,:,:,end)));

drawnow;`