Opencv学习总结1-背景建模
来源:互联网 发布:mac待机时间设置 编辑:程序博客网 时间:2024/06/05 06:33
背景建模
在摄像机静止的情况下,背景减法是一种较常见的运动目标检测方法。它利用当前帧和参考帧(背景模型)之差进行运动物体的检测,如下图所示;这些运动的物体一般就是我们感兴趣的目标,即前景检测。详细的描述可参考:http://docs.opencv.org/trunk/doc/tutorials/video/background_subtraction/background_subtraction.html
一、 背景建模的一般方法
背景建模的一般方法可分为:帧差、中值滤波、高斯平均、混合高斯、Vibe和以纹理为特征的背景建模等。具体描述可参考:
http://blog.sciencenet.cn/blog-722391-571072.html ;http://blog.csdn.net/stellar0/article/details/8777283
其存在的主要问题有:光照的缓慢变化及突变两种情况、动态背景、相似、阴影和噪声等。不同的方法在某些方面表现的较优的性能,很少有某一方法能在各个方面都呈现出最优的情况,所以需针对不同的应用场景选择最合适的方法。在这里主要是结合Opencv的实现对混合高斯背景模型进行介绍和分析。背景混合模型中,每个像素的强度值由一个高斯混合模型来表示,通过一定的方法判断那些强度值更倾向于背景。
二、Opencv实现过程
OpenCV中用于实现混合高斯前景分割的方法,主要有BackgroundSubtractorMOG和BackgroundSubtractorMOG2两个类。这2个类都继承BackgroundSubtractor类,其定义如下:
class BackgroundSubtractor : public Algorithm{public: virtual ~ BackgroundSubtractor(); virtual void operator()(InputArray image, OutputArray fgmask,double learningRate=0); virtual void getBackgroundImage( OutputArray backgroundImage) const;}
其成员函数的功能如下:
1)void BackgroundSubtractor::operator()(InputArray image, OutputArray fgmask,double learningRate=0)
功能:计算前景掩膜(foreground mask)
参数:image-视频帧
fgmask-输出前景掩膜,为8-bit的二进制图像
2)void BackgroundSubtractor::getBackgroundImage( OutputArray backgroundImage) const
功能:获得背景图像
参数:backgroundImage-输出的背景图像
下面主要总结OpenCV中实现高斯混合背景建模的二个类:
1、BackgroundSubtractorMOG类
1)构造函数
BackgroundSubtractorMOG::BackgroundSubtractorMOG()
BackgroundSubtractorMOG::BackgroundSubtractorMOG(int history,int nmixtures,double backgroundRatio,double noiseSigma=0)
其构造函数有2个,若采取默认的构造函数,则对应的参数将取默认值;第二个构造函数中参数对应为:
history—历史视频帧的长度
nmixtures---混合高斯的数目
backgroundRatio---背景比例
noiseSigma-----噪声强度
2)operator() 函数
功能:更新背景模型并返回前景掩膜
具体实现:
void BackgroundSubtractorMOG::operator()(InputArray _image, OutputArray _fgmask, double learningRate){ Mat image = _image.getMat(); bool needToInitialize = nframes == 0 || learningRate >= 1 || image.size() != frameSize || image.type() != frameType; if( needToInitialize ) initialize(image.size(), image.type()); CV_Assert( image.depth() == CV_8U ); _fgmask.create( image.size(), CV_8U ); Mat fgmask = _fgmask.getMat(); ++nframes; learningRate = learningRate >= 0 && nframes > 1 ? learningRate : 1./min( nframes, history ); //根据学习率和帧数确定当前学习率大小 CV_Assert(learningRate >= 0); if( image.type() == CV_8UC1 ) //根据图像的通道数确定处理的函数 process8uC1( image, fgmask, learningRate, bgmodel, nmixtures, backgroundRatio, varThreshold, noiseSigma ); else if( image.type() == CV_8UC3 ) process8uC3( image, fgmask, learningRate, bgmodel, nmixtures, backgroundRatio, varThreshold, noiseSigma ); else CV_Error( CV_StsUnsupportedFormat, "Only 1- and 3-channel 8-bit images are supported in BackgroundSubtractorMOG" );}
可看出,高斯混合背景建模具体功能主要由process8uc1()和process8uc3()两个函数实现,这两个函数的具体实现可参考OpenCV源代码目录下\sources\modules\video\src\bgfg_gaussmix.cpp文件。
2、BackgroundSubtractorMOG2类
1)构造函数
BackgroundSubtractorMOG2::BackgroundSubtractorMOG2()BackgroundSubtractorMOG2::BackgroundSubtractorMOG2(int history,float varThreshold,bool bShadowDetection=true)
其中第二个构造函数的参数定义如下:
history-历史帧的长度
varThreshold-变量的阈值
bShadowDetection-是否进行阴影的检测
2)operator()函数
更新背景模型并返回前景掩膜,与BackgroundSubtractorMOG类中operator()函数实现相同的功能。
具体实现:
void BackgroundSubtractorMOG2::operator()(InputArray _image, OutputArray _fgmask, double learningRate){ Mat image = _image.getMat(); bool needToInitialize = nframes == 0 || learningRate >= 1 || image.size() != frameSize || image.type() != frameType; if( needToInitialize ) initialize(image.size(), image.type()); _fgmask.create( image.size(), CV_8U ); Mat fgmask = _fgmask.getMat(); ++nframes; learningRate = learningRate >= 0 && nframes > 1 ? learningRate : 1./min( 2*nframes, history ); CV_Assert(learningRate >= 0); parallel_for_(Range(0, image.rows), MOG2Invoker(image, fgmask, (GMM*)bgmodel.data, (float*)(bgmodel.data + sizeof(GMM)*nmixtures*image.rows*image.cols), bgmodelUsedModes.data, nmixtures, (float)learningRate, (float)varThreshold, backgroundRatio, varThresholdGen, fVarInit, fVarMin, fVarMax, float(-learningRate*fCT), fTau, bShadowDetection, nShadowDetection));}
该函数实现中主要是parallel_for_()函数,其中背景建模的功能的实现主要是struct MOG2Invoker : ParallelLoopBody{}这一结构体,其具体的定义参考sources\modules\video\src\bgfg_gaussmix2.cpp。
3)getBackgroundImage()函数
获取背景图像,是该类新实现的具体功能。具体实现:
void BackgroundSubtractorMOG2::getBackgroundImage(OutputArray backgroundImage) const{ int nchannels = CV_MAT_CN(frameType); CV_Assert( nchannels == 3 ); Mat meanBackground(frameSize, CV_8UC3, Scalar::all(0)); int firstGaussianIdx = 0; const GMM* gmm = (GMM*)bgmodel.data; const Vec3f* mean = reinterpret_cast<const Vec3f*>(gmm + frameSize.width*frameSize.height*nmixtures); for(int row=0; row<meanBackground.rows; row++) { for(int col=0; col<meanBackground.cols; col++) { int nmodes = bgmodelUsedModes.at<uchar>(row, col); Vec3f meanVal; float totalWeight = 0.f; for(int gaussianIdx = firstGaussianIdx; gaussianIdx < firstGaussianIdx + nmodes; gaussianIdx++) { GMM gaussian = gmm[gaussianIdx]; meanVal += gaussian.weight * mean[gaussianIdx]; totalWeight += gaussian.weight; if(totalWeight > backgroundRatio) break; } meanVal *= (1.f / totalWeight); meanBackground.at<Vec3b>(row, col) = Vec3b(meanVal); firstGaussianIdx += nmixtures; } } switch(CV_MAT_CN(frameType)) //根据视频帧的类型返回相应的背景图像 { case 1: { vector<Mat> channels; split(meanBackground, channels); channels[0].copyTo(backgroundImage); break; } case 3: { meanBackground.copyTo(backgroundImage); break; } default: CV_Error(CV_StsUnsupportedFormat, ""); }}
三、实例分析
以BackgroundSubtractorMOG2类为例:
#include<iostream>#include<opencv2\core\core.hpp>#include<opencv2\highgui\highgui.hpp>#include<opencv2\imgproc\imgproc.hpp>#include<opencv2\video\background_segm.hpp>using namespace cv;using namespace std;void helpProcess(){cout<<"Opencv中背景减法的实例程序!\n";}int main(){helpProcess();VideoCapture video("Car.avi");Mat Frame,fgMask,bg;int FrameNum=0;if(!video.isOpened()) {printf("读取视频失败,请确认视频目录是否正确!\n");return false;}BackgroundSubtractorMOG2 bgSub; //定义背景减法的对象,以默认构造函数进行初始化while(video.read(Frame)){FrameNum++;cout<<FrameNum<<endl;bgSub(Frame,fgMask,0.001); //背景减法获取前景掩膜bgSub.getBackgroundImage(bg); //获取背景图像//显示imshow("Foreground mask",fgMask);imshow("Background Image",bg);waitKey(10);}return 0;}
对应运行结果:
背景建模受光照的缓慢变化及突变、阴影、图像噪声、动态背景,如晃动的树叶等等因素的影响,在不同的应用场景下,还需进行不同的处理。
- Opencv学习总结1-背景建模
- opencv学习系列(五)--- 背景建模
- opencv codebook背景建模
- opencv-背景建模
- 《学习OpenCV》平均距离法实现背景建模(page300)
- 《学习OpenCV》codebook法实现背景建模(page308)
- OpenCV学习之利用背景建模检测运动物体
- 背景建模总结
- opencv 高斯背景建模
- 单高斯背景建模opencv仿真
- 背景建模-均值法(Matlab)高斯背景建模(opencv)
- 平均背景建模、Vibe背景建模、CodeBook背景建模、gauss混合背景建模总结
- 背景建模方法论文总结
- 【OpenCV】高斯混合背景建模
- 【OpenCV】高斯混合背景建模
- OpenCV移动平均法背景建模
- opencv背景建模mog2源码剖析
- OpenCV:利用背景建模检测运动物体
- 静态链接库和动态链接库
- SendMessage
- 前端基础二
- android之WebView及与js的交互
- 同步
- Opencv学习总结1-背景建模
- ARIS 中的概念和表达法
- JavaScript-2.内置对象---简单脚本之弹出对话框显示当前时间 ---ShinePans
- 第2次实验——算法基本功 与 综合思考
- 深入浅出Java并发包—锁(Lock)VS同步(synchronized)
- g++: command not found
- UVa272_TEX Quotes
- 第1次实验——NPC问题(回溯算法、聚类分析)
- 怎么简单快速一个钟头入侵网站