matlab 混合高斯背景建模的实现

%根据opencv源代码改编 输入视频 输出一连串的黑白图像帧
clc;
clear;
%-------混合高斯背景建模 参数 -----------------
gauss_n = 3;     %每个像素点高斯背景模型数量
a   = 0.005;     %学习速率   alpha
vt  = 2.5^2;     %方差阈值   2.5*2.5倍的方差VarThreshold 
bgr = 0.7;       %背景比率   BackgroundRatio 
w0  = 0.05;      %初始权值   weight
var0= 10^2;      %初始方差   variance 
v = VideoReader('cs.mp4');    %读取视频

%-------混合高斯背景建模 读取视频参数----------------
f_n  =   v.NumberOfFrames;        %帧数 frame_num 
f    =   rgb2gray(read(v,1));     %读取第一帧灰度图像  
height = v.Height;                %获取图像的高度
width  = v.Width;                 %获取图像的宽度

%--------初始化高斯背景模型 共有height*width*gauss_n*3个数值-
%每一个像素对应 gauss_n 个高斯背景模型  每个模型有三个参数[权值 均值 方差]
g_b = zeros(height,width,gauss_n,3); 
for h = 1:height
    for w = 1:width           %像素遍历
        g_b(h,w,1,1) = 1;     %第一个模型初始权值为1
        g_b(h,w,1,2) = double(f(h,w));%第一个模型初始均值为第一帧灰度图像素点的值
        g_b(h,w,1,3) = 9;    %初始方差
    end
end %此方式初始化容易将第一帧内的运动物体也当成背景 最好使用前n个帧训练模型 or 一开始的学习率很高

%---------进行匹配 更新模型---------------
%帧遍历
for n=2:f_n  
    f = rgb2gray(read(v,n));       %读取下一帧
    %像素遍历
    for h = 1:height
        for w = 1:width    
            khit = 0;   %匹配的模型序号 默认与第一个模型匹配
            bg_n = 0;   %描述背景的高斯模型数量
            %高斯模型遍历
            for k = 1:gauss_n
                ww   = g_b(h,w,k,1);        %模型权值
                if(ww == 0)                 %权值为0 则模型为空 跳过
                    continue;
                end
                mean = g_b(h,w,k,2);        %模型均值
                var  = g_b(h,w,k,3);        %模型方差
                diff = double(f(h,w))-mean; %像素点与模型均值的差 
                d2 = diff^2;          %差的平方
                %与此模型匹配成功
                if(d2 < vt*var)  
                    g_b(h,w,k,1) =  ww + a * (1 - ww);     %增加权值  
                    g_b(h,w,k,2) =  mean + a * diff;       %更新均值
                    g_b(h,w,k,3) =  var + a * (d2 - var);  %更新方差
                    khit = k;  %记录匹配的模型序号
                    %模型排序 从后向前冒泡
                    for kk = k:-1:2
                        ww1 = g_b(h,w,kk,1);%权值
                        var1= g_b(h,w,kk,3);%方差 
                        ww  = g_b(h,w,kk-1,1);%权值
                        var = g_b(h,w,kk-1,3);%方差 
                        %大于前一个 则交换
                        if(ww1/sqrt(var1) > ww/sqrt(var))
                            tmp = g_b(h,w,kk,:);
                            g_b(h,w,kk,:) = g_b(h,w,kk-1,:);
                            g_b(h,w,kk-1,:) = tmp;
                            khit = khit - 1; %匹配的模型序号更新
                        end
                    end
                    break;
                end
            end
            %全部匹配失败  新建立模型覆盖权值为0 or 最后一个模型
            if(khit == 0)
                for k = 2:gauss_n
                    if(g_b(h,w,k,1) == 0 || k == gauss_n)
                        g_b(h,w,k,1) = w0;
                        g_b(h,w,k,2) = double(f(h,w));
                        g_b(h,w,k,3) = var0;
                        break;
                    end
                end
                khit = k;      %匹配的模型序号变更
            end
            %权值归一化 保证权值和为1
            wsum = sum( g_b(h,w,:,1) );
            bt = 0;
            for k = 1:gauss_n
                %%%
                g_b(h,w,k,1) = g_b(h,w,k,1)/wsum;
                bt = bt + g_b(h,w,k,1);
                %前bg_n个模型的权值和 大于背景比率 则前gb_n个模型来描述背景
                if( bt > bgr && bg_n ==0)
                    bg_n = k;
                end
            end
            %二值化 
            if(khit > bg_n)  %匹配的模型 不是前gb_n描述背景的模型
                f(h,w) = 255;
            else             %匹配的模型 属于用来描述背景的模型
                f(h,w) = 0;
            end
        end
    end
    %输出
    clc;
    fprintf('进度:%d / %d \n',n,f_n); 
    imwrite(f,strcat('cs/dst_',num2str(n),'.jpg'));
end
disp('OK!');

%%-----小结------
%1.视频先用软件进行预处理(裁剪,缩小) 方便测试程序 
%2.图片像素点类型为uint8 改为double参与运算才可得负数   (class 查看变量类型)
%3.打印某帧参数到txt       windows \r\n换行
%  1)fid=fopen(strcat(num2str(n),'.txt'),'w');    %创建日志
%  2)fprintf(fid,'(%d,%d)---%d\r\n',h,w,f(h,w));  %写入日志
%  3)fclose(fid);                                 %关闭
%

参考博文:https://blog.csdn.net/qq_26460507/article/details/56314085 opencv之GMM高斯混合模型源码解析

  • 4
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
混合高斯背景建模(Mixture of Gaussians Background Modeling)是一种常见的背景建模方法,可以用于运动目标检测等领域。Matlab中可以使用“vision.ForegroundDetector”函数来实现混合高斯背景建模。 具体步骤如下: 1.读取视频序列或图像序列。 2.初始化背景模型。可以使用“vision.ForegroundDetector”函数进行初始化。 3.对于每一帧图像,将其送入背景模型中进行处理,得到前景掩码。 4.对前景掩码进行形态学处理,如膨胀、腐蚀等,以去除噪声。 以下是一个示例代码: ```matlab % 读取视频序列 videoReader = vision.VideoFileReader('example.avi'); % 初始化背景模型 foregroundDetector = vision.ForegroundDetector('NumGaussians', 3, ... 'NumTrainingFrames', 50); % 处理每一帧图像 while ~isDone(videoReader) % 读取一帧图像 frame = step(videoReader); % 将图像送入背景模型中进行处理 foregroundMask = step(foregroundDetector, frame); % 对前景掩码进行形态学处理 se = strel('square', 3); filteredForegroundMask = imopen(foregroundMask, se); % 显示结果 subplot(1, 2, 1); imshow(frame); title('原始图像'); subplot(1, 2, 2); imshow(filteredForegroundMask); title('前景掩码'); end % 释放资源 release(videoReader); ``` 该代码实现了对视频序列的处理,输出了每一帧图像的原始图像和前景掩码。其中,“NumGaussians”参数指定使用的高斯成分数量,“NumTrainingFrames”参数指定用于初始化模型的训练帧数。在实际应用中,这些参数需要根据具体情况进行调整。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大米粥哥哥

感谢认可!

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

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

打赏作者

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

抵扣说明:

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

余额充值