背景建模与前景检测之三(Background Generation And Foreground Detection Phase 3)

作者:王先荣

在上一篇文章里,我尝试翻译了《Nonparametric Background Generation》,本文主要介绍以下内容:如何实现该论文的算法,如果利用该算法来进行背景建模及前景检测,最后谈谈我的一些体会。为了使描述更加简便,以下将该论文的算法及实现称为NBGModel。
1 使用示例
    NBGModel在使用上非常的简便,您可以仿照下面的代码来使用它:

//初始化NBGModel对象
NBGModel nbgModel = new NBGModel(320, 240);
//训练背景模型
nbgModel.TrainBackgroundModel(historyImages);
//前景检测
nbgModel.Update(currentFrame);
//利用结果
pbResult.Image = nbgModel.ForegroundMask.Bitmap;
//释放对象
nbgModel.Dispose();

下面是更加完整的示例:

更加完整的示例

2 实现NBGModel
    2.1 我在实现NBGModel的时候基本上跟论文中的方式一样,不过有以下两点区别:
(1)论文中的MeanShift计算使用了Epanechnikov核函数,我使用的是矩形窗形式的MeanShift计算。主要是因为我自己不会实现MeanShift,只能利用OpenCV中提供的cvMeanShift函数。这样做也有一个好处——不再需要计算与保存典型点。
(2)论文中的方法在检测的过程中聚集中心会不断的增加,我模仿CodeBook的实现为其增加了一个清除消极聚集中心的ClearStable方法。这样可以在必要的时候将长期不活跃的聚集中心清除掉。

2.2 NBGModel中用到的数据成员如下所示:
        private int width;                                          //图像的宽度
        private int height;                                         //图像的高度
        private NBGParameter param;                                 //非参数背景模型的参数

private List<Image<Ycc, Byte>> historyImages = null;        //历史图像:列表个数为param.n,在更新时如果个数大于等于param.n,删除最早的历史图像,加入最新的历史图像
        //由于这里采用矩形窗口方式的MeanShift计算,因此不再需要分组图像的典型点。这跟论文不一样。
        //private List<Image<Ycc,Byte>> convergenceImages = null;   //收敛图像:列表个数为param.m,仅在背景训练时使用,训练结束即被清空,因此这里不再声明
        private Image<Gray, Byte> sampleImage = null;               //样本图像:保存历史图像中每个像素在Y通道的值,用于MeanShift计算
        private List<ClusterCenter<Ycc>>[,] clusterCenters = null;  //聚集中心数据:将收敛点分类之后得到的聚集中心,数组大小为:height x width,列表元素个数不定q(q<=m)。
        private Image<Ycc, Byte> mrbm = null;                       //最可靠背景模型

private Image<Gray, Byte> backgroundMask = null;            //背景掩码图像

private double frameCount = 0;                              //总帧数(不包括训练阶段的帧数n)

其中,NBGParameter结构包含以下成员:
        public int n;                       //样本数目:需要被保留的历史图像数目
        public int m;                       //典型点数目:历史图像需要被分为多少组
        public double theta;                //权重系数:权重大于该值的聚集中心为候选背景
        public double t;                    //最小差值:观测值与候选背景的最小差值大于该值时,为前景;否则为背景
        public MCvTermCriteria criteria;    //Mean Shift计算的终止条件:包括最大迭代次数和终止计算的精度

聚集中心ClusterCenter使用类而不是结构,是为了方便更新,它包含以下成员:
        public TColor ci;              //聚集中心的像素值
        public double wi;              //聚集中心的权重
        public double li;              //聚集中心包含的收敛点数目
        public double updateFrameNo;   //更新该聚集中心时的帧数:用于清除消极的聚集中心

2.3 NBGModel中的关键流程
1.背景建模
(1)将训练用的样本图像添加到历史图像historyImages中;
(2)将历史图像分为m组,以每组所在位置的矩形窗为起点进行MeanShift计算,结果窗的中点为收敛中心,收敛中心的像素值为收敛值,将收敛值添加到收敛图像convergenceImages中;
(3)计算收敛图像的聚集中心:(a)得到收敛中心的最小值Cmin;(b)将[0,Cmin+t]区间中的收敛中心划分为一类;(c)计算已分类收敛中心的平均值,作为聚集中心的值;(d)删除已分类的收敛中心;(e)重复a~d,直到收敛中心全部归类;
(4)得到最可靠背景模型MRBM:在聚集中心中选取wi最大的值作为某个像素的最可靠背景。

2.前景检测
(1)用wi≥theta作为条件选择可能的背景组Cb;
(2)对每个观测值x0,计算x0与Cb的最小差值d;
(3)如果d>t,则该点为前景;否则为背景。

3.背景维持
(1)如果某点为背景,更新最近聚集中心的wi为(li+1)/m;
(2)如果某点为前景:(a)以该点所在的矩形窗为起点进行MeanShift计算,可得到新的收敛中心Cnew(wi=1/m);(b)将Cnew加入到聚集中心clusterCenters;
(3)在必要的时候,清理消极的聚集中心。

2.4 NBGModel的实现代码
值得注意的是:在实现代码中,有好几个以2结尾的私有方法,它们主要用于演示算法流程,实际上并未使用。为了优化性能而增加了不少指针操作之后的代码可读性变得很差。

NBGModel实现代码

3 NBGModel类介绍
    3.1 属性
Width——获取图像的宽度
Height——获取图像的高度
Param——获取参数设置
Mrbm——获取最可靠背景模型图像
BackgroundMask——获取背景掩码图像
ForegroundMask——获取前景掩码图像
FrameCount——获取已被检测的帧数

3.2 构造函数
public NBGModel(int width, int height)——用默认的参数初始化NBGModel,等价于NBGModel(width, height, NBGParameter.GetDefaultNBGParameter())
public NBGModel(int width, int height, NBGParameter param)——用指定的参数初始化NBGModel

3.3 方法
AddHistoryImage——添加一幅或者一组历史图像
TrainBackgroundModel——训练背景模型;如果传入了历史图像,则先添加历史图像,然后再训练背景模型
Update——更新背景模型,同时检测前景
ClearStale——清除消极的聚集中心
Dispose——释放资源

4 体会
    NBGModel的确非常有效,非常简洁,特别适用于伴随复杂运动对象的背景建模。我特意选取了PETS2009中的素材对其做了一些测试,结果也证明了NBGModel的优越性。不过需要指出的是,它需要占用大量的内存(主要因为需要保存n幅历史图像);它的计算量比较大。
在使用的过程中,它始终需要在内存中缓存n幅历史图像,1幅最可靠背景模型图像,1幅背景掩码图像,近似m幅图像(聚集中心);而在训练阶段,更需要临时存储m幅收敛图像。
例如:样本数目为100,典型点数目为10,图像尺寸为768x576时,所用的内存接近300M,训练背景需要大约需要33秒,而对每幅图像进行前景检测大约需要600ms。虽然可以使用并行编程来提高性能,但是并不能从根本上解决问题。
(注:测试电脑的CPU为AMD闪龙3200+,内存1.5G。)
    看来,有必要研究一种新的方法,目标是检测效果更好,内存占用低,处理更快速。目前的想法是使用《Wallflower: Principles and Practice of Background Manitenance》中的3层架构(时间轴上的像素级处理,像素间的区域处理,帧间处理),但是对每层架构都选用目前流行的处理方式,并对处理方式进行优化。时间轴上的像素级处理打算使用CodeBook方法,但是增加本文的一些思想。像素间的区域处理打算参考《基于区域相关的核函数背景建模算法》中的方法。帧间处理预计会采用全局灰度统计值作为依据。

最后,按照惯例:感谢您耐心看完本文,希望对您有所帮助。
本文所述方法及代码仅用于学习研究,不得用于商业目的。

背景建模与前景检测3(Background Generation And Foreground Detection Phase 3)相关推荐

  1. 背景建模与前景检测2(Background Generation And Foreground Detection Phase 2)

    背景建模与前景检测2(Background Generation And Foreground Detection Phase 2) 作者:王先荣 本文尝试对<学习OpenCV>中推荐的论 ...

  2. 背景建模与前景检测1(Background Generation And Foreground Detection)

    背景建模与前景检测(Background Generation And Foreground Detection) 作者:王先荣 前言     在很多情况下,我们需要从一段视频或者一系列图片中找到感兴 ...

  3. ViBe(Visual Background extractor)背景建模或前景检测

    ViBe算法:ViBe - a powerful technique for background detection and subtraction in video sequences 算法官网: ...

  4. 背景建模或前景检测(Background Generation And Foreground Detection) 二

    转自:http://www.cnblogs.com/xrwang/archive/2010/03/27/BackgroundGenerationAndForegroundDetectionPhase2 ...

  5. 基于平均背景建模的运动目标检测

    建立一个场景模型,包含图像灰度均值.帧间平均差值. 对于输入的后续视频,当灰度在区间内时,认为是静止区域,反之为运动目标.判断静止灰度区间为: diff实际上可认为是为了抑制一定的噪声,当图像序列噪声 ...

  6. 0057-在OpenCV环境下使用KNN背景建模提取前景目标

    博主注: 已于2022-06-01重写这篇博文,链接如下 https://blog.csdn.net/wenhao_ir/article/details/125007017​​​​​​​ 博主注: 已 ...

  7. 0056-在OpenCV环境下使用混合高斯背景建模提取前景目标

    博主注: 已于2022-06-01重写这篇博文,有两个链接,分别如下 https://blog.csdn.net/wenhao_ir/article/details/125010301 https:/ ...

  8. Background Subtraction and Modeling 常见的目标检测中的背景建模方法漫谈

    转载者的话: 最近一直在看background subtraction and modeling.正如如下链接的第一个回帖所说,背景建模虽然最近研究不是很热,但对视频的处理至关重要,甚至直接影响一个系 ...

  9. 目标检测中背景建模方法

    FROM: http://www.cnblogs.com/ronny/archive/2012/04/12/2444053.html 最近一直在做前景检测方面的研究,刚开始主要是做一些工程性的应用,为 ...

最新文章

  1. Python中的凝聚层次聚类示例
  2. 【转】sql if else 语句
  3. python中eval与json.loads对json的处理
  4. Linux中如何杀掉僵尸进程
  5. Django静态文件配置
  6. Linux-重装系统之静态ip配置
  7. 定时任务重启后执行策略_C语言操作时间函数time.ctime,实现定时执行某个任务小例子...
  8. 电脑连接virtualbox虚拟机的方法
  9. 企业邮箱及邮件服务器架设
  10. scala从url或者其他数据源读取数据
  11. torch -index_select()、Pytorch 之修改Tensor部分值、pytorch中Tensor的数据类型
  12. 关于扩展欧几里得算法的证明
  13. ansys中模态扩展是什么意思_ANSYS模态分析教程与实例讲解.ppt
  14. 王垠:完全用Linux工作 (转载)
  15. ffmpeg安装及在java中的使用案例
  16. 操作系统-添加文件加密系统
  17. httpclient 设置短连接_关于HTTP的长连接和短连接那些事
  18. 目标追踪(tracking)简介
  19. 微信平台 签名生成工具
  20. cad放大_cad快捷键大全amp;鼠标各键用法

热门文章

  1. IT 语音 java hi_Java bithift陌生
  2. leetcode算法题--平衡二叉树
  3. kubernetes 清理日志命令_Kubernetes之容器数据写满磁盘解决方法
  4. 采购订单模板_电子信息制造业解决方案,电子工业采购监管、管理、降本可控化...
  5. SUSE11sp3 perf工具安装过程
  6. (DT系列五)Linux kernel 是怎么将 devicetree中的内容生成plateform_device【转】
  7. window对象方法之setTimeout(),setInterval()
  8. 《C语言及程序设计》实践参考——回文日
  9. 看到他我一下子就悟了-- Lambda表达式
  10. nagios出现乱码