BackgroundSubtractorMOG部分代码
来源:互联网 发布:烈火交友软件 编辑:程序博客网 时间:2024/05/07 17:07
1、Opencv的帮助文档地址:http://docs.opencv.org/2.4/modules/video/doc/motion_analysis_and_object_tracking.html?highlight=backgroundsubtractormog#backgroundsubtractormog
2、关键函数
2.1、BackgroundSubtractorMOG::BackgroundSubtractorMOG(int _history, int _nmixtures,
double _backgroundRatio,
double _noiseSigma)
2.2、void BackgroundSubtractorMOG::operator()(InputArray _image, OutputArray _fgmask, double learningRate)
3、几点说明:
3.1、这个参数int _history 的用途。仅仅用于第一帧学习率,或者在学习率为负值时的学习率计算,其他地方没有使用
learningRate = learningRate >= 0 && nframes > 1 ? learningRate : 1./min( nframes, history );
3.2、 _backgroundRatio的用途,是个阈值,用于判断前多少个model作为背景模型。是前n个模型权重的和的比较阈值。具体可以参考下面代码注释部分
**代码摘自opencv
//backgroundRatio : 通过代码可知,就是k个模型的权重累加值>= backgroundRatio ,此时前k个model就是背景的model,大于k的model就是前景的model//nmixtures : model数量static void process8uC1( const Mat& image, Mat& fgmask, double learningRate, Mat& bgmodel, int nmixtures, double backgroundRatio, double varThreshold, double noiseSigma ){ int x, y, k, k1, rows = image.rows, cols = image.cols; float alpha = (float)learningRate, T = (float)backgroundRatio, vT = (float)varThreshold; int K = nmixtures; MixData<float>* mptr = (MixData<float>*)bgmodel.data; const float w0 = (float)defaultInitialWeight; const float sk0 = (float)(w0/(defaultNoiseSigma*2)); const float var0 = (float)(defaultNoiseSigma*defaultNoiseSigma*4); const float minVar = (float)(noiseSigma*noiseSigma); for( y = 0; y < rows; y++ ) { const uchar* src = image.ptr<uchar>(y); uchar* dst = fgmask.ptr<uchar>(y); if( alpha > 0 ) { // 考虑更新模型的情况。 for( x = 0; x < cols; x++, mptr += K ) { float wsum = 0; float pix = src[x]; int kHit = -1, kForeground = -1; // K:是高斯分布数量 for( k = 0; k < K; k++ ) { float w = mptr[k].weight; wsum += w; if( w < FLT_EPSILON ) // 由于mptr是按权重降序排列的,因此权重太小的情况就结束循环 break; float mu = mptr[k].mean; float var = mptr[k].var; float diff = pix - mu; float d2 = diff*diff; if( d2 < vT*var ) //同样判断是否是匹配的分布 { wsum -= w; // 这里得到的wsum是前面k-1个不匹配的分布的权重的累加和 float dw = alpha*(1.f - w); // mptr[k].weight = w + dw; //更新权重 mptr[k].mean = mu + alpha*diff; // 更新均值 var = max(var + alpha*(d2 - var), minVar); // 更新方差 mptr[k].var = var; mptr[k].sortKey = w/sqrt(var); // 排序的关键字,为什么? for( k1 = k-1; k1 >= 0; k1-- ) // 重新排序,通过交换的方式,将该高斯分布适当前移 { if( mptr[k1].sortKey >= mptr[k1+1].sortKey ) break; std::swap( mptr[k1], mptr[k1+1] ); } kHit = k1+1; break; } } if( kHit < 0 ) // no appropriate gaussian mixture found at all, remove the weakest mixture and create a new one { kHit = k = min(k, K-1); wsum += w0 - mptr[k].weight; mptr[k].weight = w0; mptr[k].mean = pix; mptr[k].var = var0; mptr[k].sortKey = sk0; } else for( ; k < K; k++ ) wsum += mptr[k].weight; float wscale = 1.f/wsum; wsum = 0; for( k = 0; k < K; k++ ) { wsum += mptr[k].weight *= wscale; mptr[k].sortKey *= wscale; // 前面权重或者分布有变化,这里做更新 if( wsum > T && kForeground < 0 ) kForeground = k+1; } dst[x] = (uchar)(-(kHit >= kForeground)); } } else { //不考虑更新模型的情况。这里更好理解些,看完这个在看考虑学习率的场景 for( x = 0; x < cols; x++, mptr += K ) { float pix = src[x]; int kHit = -1, kForeground = -1; //kForeground:前多少个分布是背景的分布。大于kForeground的就是前景分布 //kHit: 表示给定的像素最符合哪个分布 ; //kHit <0 ,表示没有匹配的分布,自然是前景; //kHit<kForeground 自然是背景;否则是前景 //这里判断给定的像素值与哪个高斯分布最匹配,匹配的依据就是小于vT倍的方差 for( k = 0; k < K; k++ ) { if( mptr[k].weight < FLT_EPSILON ) break; float mu = mptr[k].mean; float var = mptr[k].var; float diff = pix - mu; float d2 = diff*diff; if( d2 < vT*var ) { kHit = k; break; } } if( kHit >= 0 ) //若是没有找到匹配的分布,就被判定为为前景,不需要下面的计算 { float wsum = 0; for( k = 0; k < K; k++ ) { wsum += mptr[k].weight; if( wsum > T ) { kForeground = k+1; // 前k个作为背景模型,这里计算的到k值。 break; } } } dst[x] = (uchar)(kHit < 0 || kHit >= kForeground ? 255 : 0);// kForeground表示前kForeground个作为背景模型,若是kHit>=kForeground说明匹配的高斯分布已经不在前kForeground中,因此该像素点就是前景了。否则就判定为背景点 } } }}
[1]: 《An Improved Adaptive Background Mixture Model for Realtime Tracking with Shadow Detection》
- BackgroundSubtractorMOG部分代码
- BackgroundSubtractorMOG 前景检测
- 代码 部分
- 部分代码
- opencv BackgroundSubtractorMOG和BackgroundSubtractorMOG2的区别
- opencv中BackgroundSubtractorMOG类中的背景提取
- 部分js代码
- 又一个hideport_hook部分代码
- 部分JS代码
- 遗漏的代码部分
- 线程的部分代码
- 部分matlab代码
- 部分重构代码
- asp部分实用功能代码
- SD部分事务代码
- spring AOP 部分代码
- 部分javascript代码
- MySchool部分代码
- 天声人語 20160305 聖火台の置き場がない!
- AAA Zookeeper精讲 三种安装方法
- 杭电1715
- 物料批次特性值
- MySQL中concat函数(连接字符串)学习整理
- BackgroundSubtractorMOG部分代码
- 蓝桥杯 六角填数
- android日期相关知识
- 修改mysql字符集
- 解决由Handler引发的内存泄漏
- C/CPP点滴积累--void小记
- 仿QQ侧滑效果ViewDragHelper
- Socket是什么?
- Spring进阶之路(1)-Spring核心机制:依赖注入/控制反转