背景建模与前景检测 Background Generation And Foreground Detection

本文介绍了背景建模与前景检测的概念,如帧差法、背景统计模型、编码本背景模型和高级背景统计模型(FGD、MOG),并详细讲述了OpenCV中对应的实现方法。通过实例展示了如何利用这些技术进行前景目标检测,适用于视频监控、仓库防盗等场景。
摘要由CSDN通过智能技术生成

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

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

 

http://www.cnblogs.com/xrwang/archive/2010/02/21/ForegroundDetection.html

作者:王先荣

前言
    在很多情况下,我们需要从一段视频或者一系列图片中找到感兴趣的目标,比如说当人进入已经打烊的超市时发出警报。为了达到这个目的,我们首先需要“学习”背景模型,然后将背景模型和当前图像进行比较,从而得到前景目标。

背景建模
    背景与前景都是相对的概念,以高速公路为例:有时我们对高速公路上来来往往的汽车感兴趣,这时汽车是前景,而路面以及周围的环境是背景;有时我们仅仅对闯入高速公路的行人感兴趣,这时闯入者是前景,而包括汽车之类的其他东西又成了背景。背景建模的方式很多,或高级或简单。不过各种背景模型都有自己适用的场合,即使是高级的背景模型也不能适用于任何场合。下面我将逐一介绍OpenCv中已经实现,或者在《学习OpenCv》这本书中介绍的背景建模方法。
1.帧差
    帧差可说是最简单的一种背景模型,指定视频中的一幅图像为背景,用当前帧与背景进行比较,根据需要过滤较小的差异,得到的结果就是前景了。OpenCv中为我们提供了一种动态计算阀值,然后用帧差进行前景检测的函数——cvChangeDetection(注:EmguCv中没有封装 cvChangeDetection,我将其声明到OpenCvInvoke类中,具体实现见文末代码)。而通过对两幅图像使用减法运算,然后再用指定阀值过滤的方法在《学习OpenCv》一书中有详细的介绍。它们的实现代码如下:

帧差
复制代码
 
    
            [DllImport( " cvaux200.dll " )]            public static extern void cvChangeDetection(IntPtr prev_frame, IntPtr curr_frame, IntPtr change_mask);            // backgroundMask为背景,imageBackgroundModel为背景模型,currentFrame为当前帧             if (backgroundMask == null )                backgroundMask = new Image < Gray, byte > (imageBackgroundModel.Size);            if (threshold == 0d)                // 如果阀值为0,使用OpenCv中的自适应动态背景检测                 OpenCvInvoke.cvChangeDetection(imageBackgroundModel.Ptr, currentFrame.Ptr, backgroundMask.Ptr);            else             {                // 如果设置了阀值,使用帧差                 Image < TColor, Byte > imageTemp = imageBackgroundModel.AbsDiff(currentFrame);                Image < Gray, Byte > [] images = imageTemp.Split();                backgroundMask.SetValue(0d);                foreach (Image < Gray, Byte > image in images)                    backgroundMask._Or(image.ThresholdBinary( new Gray(threshold), new Gray(255d)));            }            backgroundMask._Not();
复制代码

对于类似无人值守的仓库防盗之类的场合,使用帧差效果估计很好。

2.背景统计模型
    背景统计模型是:对一段时间的背景进行统计,然后计算其统计数据(例如平均值、平均差分、标准差、均值漂移值等等),将统计数据作为背景的方法。 OpenCv中并未实现简单的背景统计模型,不过在《学习OpenCv》中对其中的平均背景统计模型有很详细的介绍。在模仿该算法的基础上,我实现了一系列的背景统计模型,包括:平均背景、均值漂移、标准差和标准协方差。对这些统计概念我其实不明白,在维基百科上看了好半天 -_-
调用背景统计模型很简单,只需4步而已:

复制代码
 
   
// (1)初始化对象 BackgroundStatModelBase < Bgr > bgModel = new BackgroundStatModelBase < Bgr > (BackgroundStatModelType.AccAvg); // (2)更新一段时间的背景图像,视情况反复调用(2) bgModel.Update(image); // (3)设置当前帧 bgModel.CurrentFrame = currentFrame; // (4)得到背景或者前景 Image < Gray,Byte > imageForeground = bgModel.ForegroundMask;
复制代码

背景统计模型的实现代码如下:

实现背景统计模型

 

3.编码本背景模型
    编码本的基本思路是这样的:针对每个像素在时间轴上的变动,建立多个(或者一个)包容近期所有变化的Box(变动范围);在检测时,用当前像素与Box去比较,如果当前像素落在任何Box的范围内,则为背景。
    在OpenCv中已经实现了编码本背景模型,不过实现方式与《学习OpenCv》中提到的方式略有不同,主要有:(1)使用单向链表来容纳Code Element;(2)清除消极的Code Element时,并未重置t。OpenCv中的以下函数与编码本背景模型相关:
cvCreateBGCodeBookModel  建立背景模型
cvBGCodeBookUpdate       更新背景模型
cvBGCodeBookClearStale   清除消极的Code Element
cvBGCodeBookDiff         计算得到背景与前景(注意:该函数仅仅设置背景像素为0,而对前景像素未处理,因此在调用前需要将所有的像素先置为前景)
cvReleaseBGCodeBookModel 释放资源
    在EmguCv中只实现了一部分编码本背景模型,在类BGCodeBookModel<TColor>中,可惜它把cvBGCodeBookDiff给搞忘记了 -_-
下面的代码演示了如果使用编码本背景模型:

编码本模型
复制代码
 
    
            // (1)初始化对象             if (rbCodeBook.Checked)            {                if (bgCodeBookModel != null )                {                    bgCodeBookModel.Dispose();                    bgCodeBookModel = null ;                }                bgCodeBookModel = new BGCodeBookModel < Bgr > ();            }            // (2)背景建模或者前景检测             bool stop = false ;            while ( ! stop)            {                Image < Bgr, Byte > image = capture.QueryFrame().Clone();  // 当前帧                 bool isBgModeling, isFgDetecting;                       // 是否正在建模,是否正在前景检测                 lock (lockObject)                {                    stop = ! isVideoCapturing;                    isBgModeling = isBackgroundModeling;                    isFgDetecting = isForegroundDetecting;                }                // 得到设置的参数                 SettingParam param = (SettingParam) this .Invoke( new GetSettingParamDelegate(GetSettingParam));                // code book                 if (param.ForegroundDetectType == ForegroundDetectType.CodeBook)                {                    if (bgCodeBookModel != null )                    {                        // 背景建模                         if (isBgModeling)                        {                            bgCodeBookModel.Update(image);                            // 背景建模一段时间之后,清理陈旧的条目 (因为清理操作不会重置t,所以这里用求余数的办法来决定清理的时机)                             if (backgroundModelFrameCount % CodeBookClearPeriod == CodeBookClearPeriod - 1 )                                bgCodeBookModel.ClearStale(CodeBookStaleThresh, Rectangle.Empty, null );                            backgroundModelFrameCount ++ ;                            pbBackgroundModel.Image = bgCodeBookModel.BackgroundMask.Bitmap;                            // 如果达到最大背景建模次数,停止背景建模                             if (param.MaxBackgroundModelFrameCount != 0 && backgroundModelFrameCount > param.MaxBackgroundModelFrameCount)                                this .Invoke( new NoParamAndReturnDelegate(StopBackgroundModel));                        }                        // 前景检测                         if (isFgDetecting)                        {                            Image < Gray, Byte > imageFg = new Image < Gray, byte > (image.Size);                            imageFg.SetValue(255d);     // CodeBook在得出前景时,仅仅将背景像素置零,所以这里需要先将所有的像素都假设为前景                             CvInvoke.cvBGCodeBookDiff(bgCodeBookModel.Ptr, image.Ptr, imageFg.Ptr, Rectangle.Empty);                            pbBackgroundModel.Image = imageFg.Bitmap;                        }                    }                }                // 更新视频图像                 pbVideo.Image = image.Bitmap;            }            // (3)释放对象             if (bgCodeBookModel != null )            {                try                 {                    bgCodeBookModel.Dispose();                }                catch { }            }
复制代码

 

4.高级背景统计模型
    在OpenCv还实现了两种高级的背景统计模型,它们为别是:(1)FGD——复杂背景下的前景物体检测(Foreground object detection from videos containing complex background);(2)MOG——高斯混合模型(Mixture Of Gauss)。包括以下函数:
CvCreateFGDetectorBase  建立前景检测对象
CvFGDetectorProcess     更新前景检测对象
CvFGDetectorGetMask     获取前景
CvFGDetectorRelease     释放资源
    EmguCv将其封装到类FGDetector<TColor>中。我个人觉得OpenCv在实现这个模型的时候做得不太好,因为它将背景建模和前景检测糅合到一起了,无论你是否愿意,在建模的过程中也会检测前景,而只希望前景检测的时候,同时也会建模。我比较喜欢将背景建模和前景检测进行分离的设计。
调用的过程很简单,代码如下:

高级背景统计模型

 

前景检测
    在建立好背景模型之后,通过对当前图像及背景的某种比较,我们可以得出前景。在上面的介绍中,已经包含了对前景的代码,在此不再重复。一般情况下,得到的前景包含了很多噪声,为了消除噪声&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值